Penguin Talk
Some basics posts with un-organized posts written at minimum time mostly with 30 mins of time spent or even less. Many of these contents are taken from other links floating in Internet and which was interesting to me to share with others. These are collection, apart from my other blogger accounts which I didn't feel so worth to share or was better to keep away from my profile. More typical to technical posts and specific to my work are still private and not shared here.
Sunday, August 20, 2017
Tuesday, May 14, 2013
Communication with Remote Processor
Interrupt method
The interrupt method, which is the simplest of the three methods, lets one core send an interrupt to the other, as notification that an application-defined event has occurred. The interrupt routine is very compact, so it doesn’t require a lot of code space. The designer can specify a callback function, for execution during the interrupt, to perform some quick function. If the callback function isn’t used, it can be left as an empty function.
To signal the remote core, the local core issues the dedicated instruction SEV (send event), which is included in the Cortex architecture. Once an IPC notification is received, a flag variable is set. The flag variable can be used by the receiving core to check for status.
Message queue
In the message queue method, the designer defines two areas of shared memory, to be used to store messages that each core sends to the other. A Host Command buffer is dedicated to the commands sent from the master to the slave, and a separate Host Message Buffer is dedicated to the messages the slave sends back in response. Figure 1 shows the setup.
In the message queue method, the designer defines two areas of shared memory, to be used to store messages that each core sends to the other. A Host Command buffer is dedicated to the commands sent from the master to the slave, and a separate Host Message Buffer is dedicated to the messages the slave sends back in response. Figure 1 shows the setup.
Figure 1. The message queue method for IPC in the LPC4300
Mailbox method
As the name implies, this method draws on the concept of a mailbox. Each core has a placeholder in RAM memory that is used to send and receive messages. Each core manages its own RAM mailbox, and messages are directed to the other core’s mailbox.
As the name implies, this method draws on the concept of a mailbox. Each core has a placeholder in RAM memory that is used to send and receive messages. Each core manages its own RAM mailbox, and messages are directed to the other core’s mailbox.
Reference:
NXP blog by
Tuesday, March 12, 2013
Linux System Performance
Power entry could be found at /proc/acpi and running process and dameon in my system are:
root 15 0.0 0.0 0 0 ? S Nov26 0:00 [pm]
root 23 0.0 0.0 0 0 ? S Nov26 0:00 [kacpid]
root 24 0.0 0.0 0 0 ? S Nov26 0:00 [kacpi_notify]
root 25 0.0 0.0 0 0 ? S Nov26 0:00 [kacpi_hotplug]
root 1105 0.0 0.0 2108 596 ? Ss Nov26 0:00 acpid -c /etc/acpi/events -s /var/run/acpid.socket
Power manager manages and keeps entry of class of power source used : Battery, UPS, AC, DC
power consumption by each running apps:
adb shell dumpsys cpuinfo
adb shell dumpsys batteryinfo
System performance measurement:
- Sourcery analyzer: C application software http://www.mentor.com/embedded-software/sourcery-tools/sourcery-analyzer/?cmpid=7770
- Sourcery probe: Tools for debugging and performance measurement http://www.mentor.com/embedded-software/sourcery-tools/sourcery-probe#features
- Utilities: top, htop, iftop.
Power measurement:
- Linaro ARM energy probe: http://www.cnx-software.com/2012/11/29/soc-power-measurement-with-arm-energy-probes-and-linux-eap-tools/ Used in Linux based system
- Less Watts: https://lesswatts.org/projects/ Collection of good tools to measure power at various level in Intel machine.
- powertop
- $sudo add-apt-repository ppa:colin-king/powermanagement
$sudo apt-get update
$sudo apt-get install powerstat
Linux System Call
Good explanation to know at the basic : System call and Address space
\
To add your own system call:
- Add system call definition in kernel/module.c
- Declare system call in include/linux/syscalls.h
- Assign system call number in arch/x86/include/asm/unistd_32.h
- Add system call in system call table at correct offset from top, arch/x86/kernel/sys_call_table_32.S
Session on:
System call: How does it work and behavior of kernel and user process during system call
Kernel process and thread monitor
bionicC and libC
System call: How does it work and behavior of kernel and user process during system call
Kernel process and thread monitor
bionicC and libC
USB and MMC
USB
Search for "LINUX USB API - DAIICT Intranet" for Quick Reference.USB driver link gives easy to understand and clear explanation.
Also see USB tutorial from Atmel.
Application prefers to use libusb library to access usb device/driver functanality.
Before we go to USB driver, we will have a look on USB sub-system.
USB physical interface joins system bus by a controller and is called host controller interface(HCI).
HCI driver is the one which let your system detect attached usb device. If wrong hci driver is used (for controller) devices will not be recognized.
Controller also virtualizes a root usb hub. And all usb devices/hub joins it in hierarchical order.
USBv1.0: Low speed: uhci.o is a driver lincenced by intel and ohci.o is a driver for all other vendors.
USBv2.0: High Speed: ehci.o, and we can see this driver in ARM devices too.
usbcore is the manager of USB sub-system. All drivers has to register with usbcore. Even hci drivers also registers with usbcore.
Endpoints:
Control, Interrupt, Bulk, isochronous.
Interface:
Contains array of settings and the 1st one at array index 0 is the default one.
Configuration:
Descriptor:
A good place to experiment with USB driver.
You can select any USB driver and try to understand. Even comments are brief and understandable. E.g. you can select omap_udc.c or pxa27x_udc.c
It is good to have look into zero.c driver code which is named as testusb driver and is a good test tool during driver development, works on bulk endpoint.
http://linuxgazette.net/133/tag.html
http://docs.blackfin.uclinux.org/kernel/generated/writing_usb_driver/ch03.html
http://www.embeddedlinux.org.cn/EssentialLinuxDeviceDrivers/final/ch11lev1sec2.html
http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/node18.html
USB Class:
http://www.xat.nl/en/riscos/sw/usb/class.htm
Testing USB Driver:
usbmon in /dev is created for each usb interface at hci layer. It is a provision by kernel which could be used to monitor raw data I/O over the USB bus. usbdump and USBMon uses this device node for monitoring the device traffic. More details could be found at linux document, kernel/Documentation/usb/usbmon.txt.
http://www.sysnucleus.com/usbtrace_download.html #testusb -a
#lsusb -v
#usb-devices
Also work with lsusb(lsusb -v) which will show usb device tree.
Notice here for USB Bluetooth dongle: device descriptor, carrying interfaces and endpoints belonging to each interface.
- It carries one device descriptor
- one configuration descriptor(3g modam uses multiple)
- Four interface descriptor
- And multiple endpoints (2 to 3 here) for each interface
- End point carries in or out (and same pipe should be used if you use urbs) and different end point type(again urb pipe will be used accordingly).
- Here we can see alt setting numbers also(0-1-2-3). Which belongs to one interface.
#usb -v
Bus 003 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 224 Wireless
bDeviceSubClass 1 Radio Frequency
bDeviceProtocol 1 Bluetooth
bMaxPacketSize0 16
idVendor 0x0a12 Cambridge Silicon Radio, Ltd
idProduct 0x0001 Bluetooth Dongle (HCI mode)
bcdDevice 1.34
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 108
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 224 Wireless
bInterfaceSubClass 1 Radio Frequency
bInterfaceProtocol 1 Bluetooth
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 224 Wireless
bInterfaceSubClass 1 Radio Frequency
bInterfaceProtocol 1 Bluetooth
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0000 1x 0 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0000 1x 0 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 2
bInterfaceClass 224 Wireless
bInterfaceSubClass 1 Radio Frequency
bInterfaceProtocol 1 Bluetooth
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0009 1x 9 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0009 1x 9 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 2
bNumEndpoints 2
bInterfaceClass 224 Wireless
bInterfaceSubClass 1 Radio Frequency
bInterfaceProtocol 1 Bluetooth
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0011 1x 17 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0011 1x 17 bytes
bInterval 1
cannot read device status, Operation not permitted (1)
USB Gadget Driver:
USB gadget driver explains about target USB device(like linux based firmware inside BT dongle or modem).
kernel/Documentation/usb/usbmon.txt
It is worth to work with dummy_hcd driver, which is good starting point with minimum effort.
dummy_hcd virtulizes gadget driver in host machine itself. It creates usb bus interface for gadget side device, and there is no real need of actual device at initial stage of gadget driver development. Once dummy_hcd is installed into the host system, one usb bus entry point could be found at /dev/bus/usb/<bus number>.
gadgetfs is good module ot explore gadget device file system, which work over the hci, and here dummy_hci. Could be used for debugging or communicating application to the driver.
One can start looking at gadget driver by installing any pre-build gadget driver.
Best way is to start working with g_zero driver, which is dependent on dummy_hcd driver and could be used to create virtual endpoint and interface. g_zero could virtulize control in/out and buld in/out endpoint for testing.
To understand device creation, if one installs g_serial gadget driver into the virtual gadget, /dev/ttyGS0 node gets created. Since, we virtual gadget is connected to the host computer, host side USB core immediately recognizes the devices as serial device and loads /dev/ttyACM0 driver in host.
So, /dev/ttyGS0 is node as gadget device, where as /dev/ttyACM0 is node at host side device.
We can see these details, of host side devices, into lsusb, which will not contain gadget devices.
Now this is the time to write our own gadget driver.
Well, lets consider I am interested to write usbtouch screen, an HID device, take a dummy product id and vendor id, registor it to host side usb touchscreen driver. After fixing the product id and vendor id, lets start developing gadget driver.
Read kernel document, /kernel/Documentation/usb/gadget_serial.txt. This one carry very well explained serial driver information.
---------------------------
Gadget API lower boundery:
handling setup requests (ep0 protocol responses) possibly including class-specific functionality
returning configuration and string descriptors
(re)setting configurations and interface altsettings, including enabling and configuring endpoints
handling life cycle events, such as managing bindings to hardware, USB suspend/resume, remote wakeup, and disconnection from the USB host
managing IN and OUT transfers on all currently enabled endpoints
Upper layer:
user mode code, using generic (gadgetfs) or application specific files in /dev
networking subsystem (for network gadgets, like the CDC Ethernet Model gadget driver)
data capture drivers, perhaps video4Linux or a scanner driver; or test and measurement hardware
input subsystem (for HID gadgets)
sound subsystem (for audio gadgets)
file system (for PTP gadgets)
block i/o subsystem (for usb-storage gadgets)
usb_gadget structure: linux/usb/gadget.h
struct usb_gadget { // represents gadget device
/* readonly to gadget driver */
const struct usb_gadget_ops *ops; // callback for hardware operations
struct usb_ep *ep0;
struct list_head ep_list; /* of usb_ep */
enum usb_device_speed speed;
unsigned is_dualspeed:1;
unsigned is_otg:1;
unsigned is_a_peripheral:1;
unsigned b_hnp_enable:1;
unsigned a_hnp_support:1;
unsigned a_alt_hnp_support:1;
unsigned host_request:1;
const char *name;
struct device dev;
};
Gadget API main functions:
General operations (usb_gadget_x()):
● probe_driver / unregister_driver
● set_selfpowered / clear_selfpowered
● vbus_connect / vbus_disconnect
● connect / disconnect
● frame_number
Endpoint operations (usb_ep_x()):
● autoconf / autoconf_reset
● enable / disable
● alloc / free
● queue / dequeue
● set_halt / clear_halt
● fifo_status / fifo_flush
Decriptor operations:
● usb_descriptor_fillbuf
● usb_gadget_config_buf
MMC
MMC card could be used in two mode, mmc mode as preferred mode and SPI as alternate option.SPI has some limitation in speed of data transfer compare to MMC mode.
This blog shows a very good explanation of how to communicate with MMC hardware controller.
MMC talks with 6 bytes of commands which includes
[ StartBit - command/dataBit - CommandNumber - CommandArgument - CRCcheck - endBit ]
MMC has a small set of attributes which are read only,
cid Card Identifaction Register
csd Card Specific Data Register
scr SD Card Configuration Register (SD only)
date Manufacturing Date (from CID Register)
fwrev Firmware/Product Revision (from CID Register) (SD and MMCv1 only)
hwrev Hardware/Product Revision (from CID Register) (SD and MMCv1 only)
manfid Manufacturer ID (from CID Register)
name Product Name (from CID Register)
oemid OEM/Application ID (from CID Register)
serial Product Serial Number (from CID Register)
erase_size Erase group size
preferred_erase_size Preferred erase size
Now if we come back to linux, linux has mmc subsystem and lies below the block device layer.
MMC subsystem:
Block Driver
----------------
MMC Core
----------------
MMC HCI
_________________________________________________________________________
Boot Loader:
U-boot
Other Subsystems:
ALSA
Bluez
WiFi
V4L2
Tuesday, January 8, 2013
BSP
www.linux-arm.org/pub/LinuxKernel/.../aleph-porting.pdf
up the interrupt controller. Interrupt mask and unmask functions go here too.
arch/arm/kernel/entry-armv.S
Interrupt controller base: /arch/arm/mach-omap2/omap24xx.h
Assigning irq numbers: include/asm/arch/irqs.h
__virt_to_phys() macro in include/asm-arm/arch-XXX/memory.h
(along with corresponding reverse mappings). Normally, this macro
is simply:
phys = virt - PAGE_OFFSET + PHYS_OFFSET
Initialize all memory segments as well: text addr, phys addr, virtual addr, task size, page offset, phy offset, vmalloc start/end, vmalloc offset, data addr.
arch/arm/mach-XXX/irq.c : You should provide the XXX_init_irq function here. This sets
arch/arm/mach-XXX/mm.c
include/asm/arch/dma.h : Defines for DMA channels, and DMA-able areas of memory.
For machines without DMA, you can just declare 0 DMA
channels as follows:
#define MAX_DMA_ADDRESS 0xffffffff
#define MAX_DMA_CHANNELS 0
define the memory addresses, IOaddresses, and so on: include/asm/arch/hardware.h
include/asm/arch/io.h
include/asm/arch/timex.h
Board support package initializes board specific details and keeps the OS not worried about it.
Although board initialization starts before the booting process itself.
When ARM devices are powered on the 1st software (firmware usually) is executed from ROM and written in assembly code. In many cases this firmware might not run on ARM core and may run in DSP processor, if available.
Above piece of code initializes L1 cache of the primary core (in multicore system) to load 1st bootloader, written in C.
Why L1 is required? Well this is not necessary but many vendors does it. This is to support 1st level bootloader which is written in C. As usual standard, C code program keeps segments: text, bss, data, rodata. And when this bootloader comes in execution, it requires stack segment also (as like any simplest program in C). ROM can't hold stack as it is read only (I guess L1 cache or DRAM is required to hold bss and data segment also). Main job of this 1st level of bootloader is to chainload 2nd level bootloader.
Offset Handler
===============
00 Reset
04 Undefined Instruction
08 Supervisor Call (SVC)
0C Prefetch Abort
10 Data Abort
14 (Reserved)
18 Interrupt (IRQ)
1C Fast Interrupt (FIQ)
When the exception happens, the processor just starts execution from a specific offset, so usually this table contains single-instruction branches to the complete handlers further in the code. A typical classic vector table looks like following:
00000000 LDR PC, =Reset
00000004 LDR PC, =Undef
00000008 LDR PC, =SVC
0000000C LDR PC, =PrefAbort
00000010 LDR PC, =DataAbort
00000014 NOP
00000018 LDR PC, =IRQ
0000001C LDR PC, =FIQ
At runtime, the vector table can be relocated to 0xFFFF0000, which is often implemented as a tightly-coupled memory range for the fastest exception handling. However, the power-on reset usually begins at 0x00000000 (but in some chips can be set to 0xFFFF0000 by a processor pin).
http://kiranjammula.wordpress.com/
----------------------------
-Initialize CPU speed
-Initialize memory, which includes enabling memory banks, initializing memory configuration registers, and so on
-nitialize serial port (if present on the target)
-Enable instruction/data caches
-Set up stack pointer
-Set up parameter area and construct parameter structures and tags (this is an important step, as boot parameters are used by the kernel in identifying root device, page size, memory size and more)
-Perform POST (Power On Self Test) to identify the devices present and to report any problems
-Provide support for suspend/resume for power management
-Load the kernel to memory if needed
-For arm Linux kernel, before jumping to the kernel, MMU has to be turned off, D-cache should be turned off, register r0 should be set 0, r1 should contain the correct machine number and r2 should point ATAGS.
-Jump to start of kernel.
----------------------------
-Initialize CPU speed
-Initialize memory, which includes enabling memory banks, initializing memory configuration registers, and so on
-nitialize serial port (if present on the target)
-Enable instruction/data caches
-Set up stack pointer
-Set up parameter area and construct parameter structures and tags (this is an important step, as boot parameters are used by the kernel in identifying root device, page size, memory size and more)
-Perform POST (Power On Self Test) to identify the devices present and to report any problems
-Provide support for suspend/resume for power management
-Load the kernel to memory if needed
-For arm Linux kernel, before jumping to the kernel, MMU has to be turned off, D-cache should be turned off, register r0 should be set 0, r1 should contain the correct machine number and r2 should point ATAGS.
-Jump to start of kernel.
Wednesday, January 2, 2013
Must know
ELF:
Segments in ELF and how it is loaded:
http://www.tenouk.com/Bufferoverflowc/Bufferoverflow1c.html
http://www.kernel.org/doc/man-pages/online/pages/man5/elf.5.html
Segments in ELF and how it is loaded:
http://www.tenouk.com/Bufferoverflowc/Bufferoverflow1c.html
http://www.kernel.org/doc/man-pages/online/pages/man5/elf.5.html
Program headers in an ELF binary describe how the binary should be run. The interesting parts are the LOAD headers which load part of the binary into different places in memory. There could be almost arbitrary number of LOAD headers in a binary, but usually the linker puts everything read-only and executable into one and everything read/write into another. There are operating systems which will have read-only data LOAD header, read-write data and read-only executable code for slightly increased security.
Segments here just mean parts of the binary loaded in different places in memory. So basically the different LOAD headers.
Sections is how the data was organized during linking. For various reasons you want to have better granularity organizing things than just data/code. Some data is read-only, it's put in ".rodata" in your example. The code is in ".text", initialized data is in ".data" while data in variables that are zeroed on program start are in ".bss".
The "section to segment mapping" tells you which sections are in which segments (different LOAD headers). So ".text" and ".rodata" are in the first LOAD header (the third program header) and ".data" is in the second LOAD header (fourth program header).
The stack is something that the operating system gives you on execution and it's not described by an ELF binary.
http://www.linuxjournal.com/article/6463?page=0,0
http://www.linuxjournal.com/article/1060?page=0,0
See also how linker works, to know how loader passes control to linker ld for dynamic linking.
http://www.kernel.org/doc/man-pages/online/pages/man8/ld-linux.so.8.html
http://www.linuxjournal.com/article/1060?page=0,0
See also how linker works, to know how loader passes control to linker ld for dynamic linking.
http://www.kernel.org/doc/man-pages/online/pages/man8/ld-linux.so.8.html
U-Boot:
http://www.scribd.com/doc/56518684/U-Boot-Implementation-Internals
http://www.linux-arm.org/LinuxBootLoader/SMPBoot
http://cache.freescale.com/files/dsp/doc/app_note/AN4173.pdf
DMA:
http://coweb.cc.gatech.edu/sysHackfest/uploads/58/DMA_howto.1.txt
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0424d/index.html
fstab:
SYNOPSIS
#include <fstab.h>
DESCRIPTION
The file fstab contains descriptive information about the various file systems. fstab is only read by programs, and not written; it is the duty of the system administrator to
udev:
DESCRIPTION
udev provides a dynamic device directory containing only the files for actually present devices. It creates or removes device node files in the /dev directory, or it renames
Usually udev runs as udevd(8) and receives uevents directly from the kernel if a device is added or removed from the system.
If udev receives a device event, it matches its configured rules against the available device attributes provided in sysfs to identify the device. Rules that match may provide
http://www.scribd.com/doc/56518684/U-Boot-Implementation-Internals
http://www.linux-arm.org/LinuxBootLoader/SMPBoot
http://cache.freescale.com/files/dsp/doc/app_note/AN4173.pdf
DMA:
http://coweb.cc.gatech.edu/sysHackfest/uploads/58/DMA_howto.1.txt
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0424d/index.html
fstab:
fstab - static information about the filesystems
SYNOPSIS
#include <fstab.h>
DESCRIPTION
The file fstab contains descriptive information about the various file systems. fstab is only read by programs, and not written; it is the duty of the system administrator to
properly create and maintain this file.
udev:
udev - dynamic device management
DESCRIPTION
udev provides a dynamic device directory containing only the files for actually present devices. It creates or removes device node files in the /dev directory, or it renames
network interfaces.
Usually udev runs as udevd(8) and receives uevents directly from the kernel if a device is added or removed from the system.
If udev receives a device event, it matches its configured rules against the available device attributes provided in sysfs to identify the device. Rules that match may provide
additional device information or specify a device node name and multiple symlink names and instruct udev to run additional programs as part of the device event handling.
Subscribe to:
Posts (Atom)