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.
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.

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:


Power measurement:

$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:

  1. Add system call definition in kernel/module.c
  2. Declare system call in include/linux/syscalls.h
  3. Assign system call number in arch/x86/include/asm/unistd_32.h
  4. 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

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

testusb is a good tool. See this link for explanation.
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


http://linuxusbguide.sourceforge.net/USB-guide-1.0.9/book1.html

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

Files:
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.

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


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.
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:




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.