Fork me on GitHub beagleboard url

Learning embedded Linux through the file system: A top-down approach

Marco Casaroli, marco@intelliges.com.br
Nuncio Perrella, n-perrella@ti.com
August 31, 2011, 14:30
TI Tech Day São Paulo - Moema Room

Based on original work by Jason Kridner, jdk@ti.com

Abstract

 

Typical introductions to embedded Linux focus on complex tasks like building device drivers that are highly desired by at least some people working on your Linux product team. What about the rest of us that simply want to build a quick understanding of how to do some of the simple tasks that are trivial in microcontrollers without using operating systems, like accessing GPIO pins and performing I2C or SPI serial communications? This class takes a quick top-down overview from the perspective of an electrical engineer looking to take advantage of the latest in GUI building technologies, like Android, Qt, and HTML5, without completely losing access to the underlying hardware for simple system integration tasks.

Getting Started

 

What is the baseline?

http://refspecs.linuxfoundation.org/lsb.shtml

lsb_release

 

root@beagleboard:~# lsb_release -a
Distributor ID: Angstrom
Description:    Angstrom GNU/Linux 2011.03 (Dureza)
Release:        2011.03
Codename:       Dureza

Filesystem Hierarchy Standard

http://www.pathname.com/fhs/

Filesystem Hierarchy Standard

http://www.pathname.com/fhs/

/proc

 

root@beagleboard:~# ls /proc
1     1151  1214  183  44   87         consoles     kpageflags    sys
10    1160  1215  184  47   9          cpu          loadavg       sysrq-trigger
1021  1171  1218  19   48   901        cpuinfo      locks         sysvipc
1026  1172  1242  2    49   946        crypto       meminfo       timer_list
1029  1177  1251  20   5    950        devices      misc          timer_stats
1031  1182  1254  21   50   953        diskstats    modules       tty
1034  1183  1256  22   51   956        driver       mounts        uptime
1039  1187  1259  23   52   965        execdomains  mtd           version
1048  1190  1262  24   53   966        fb           net           vmallocinfo
1049  1192  1282  25   57   967        filesystems  pagetypeinfo  vmstat
1061  1193  1295  26   58   993        fs           partitions    zoneinfo
1074  12    1296  27   59   996        interrupts   sched_debug
1076  1203  13    28   6    asound     iomem        schedstat
1077  1205  1301  29   61   atags      ioports      scsi
1081  1207  14    3    62   buddyinfo  irq          self
1083  1209  15    30   644  bus        kallsyms     slabinfo
11    1211  16    31   7    cgroups    key-users    softirqs
1102  1212  17    32   8    cmdline    kmsg         stat
1121  1213  18    43   857  config.gz  kpagecount   swaps

/proc

 

root@beagleboard:~# cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 2 (v7l)
BogoMIPS        : 246.33
Features        : swp half thumb fastmult vfp edsp thumbee neon vfpv3
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc08
CPU revision    : 2
Hardware        : OMAP3 Beagle Board
Revision        : 0020
Serial          : 0000000000000000

The file interface abstraction

 

Busybox

The Swiss Army Knife of Embedded Linux

http://www.busybox.net

Kernel.org documentation

http://www.kernel.org/doc/

Kernel Application Binary Interface

http://www.kernel.org/doc/Documentation/ABI/

Kernel Application Binary Interface

http://www.kernel.org/doc/Documentation/ABI/

Syscalls

http://www.kernel.org/doc/man-pages/online/pages/man2/syscalls.2.html

What is SYSFS?

 

/sys/module

http://www.kernel.org/doc/Documentation/ABI/stable/sysfs-module

/sys/class/leds

http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-led

/sys/class/gpio

http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-gpio

GPIOs

readgpio

# cd /sys/class/gpio
# ls
# echo "174" > export
# ls
# echo "in" > gpio174/direction
# cat gpio174/value
# echo "40" > export
# ls
# echo "out" > gpio40/direction
# cat gpio40/value
# echo "1" > gpio40/value
# cat gpio40/value

Reading events

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
    int fd, ret, data[64];
    fd = ret = open(argv[argc - 1], O_RDONLY);
    printf("open returned %d\n", ret);
    while (1) {
        ret = read(fd, &data, sizeof(data));
        printf("read returned %d bytes\n", ret);
        sleep(1);
    }
    exit(0);
}

Reading events

 

root@beagleboard:~/labs# gcc -o myread myread.c
root@beagleboard:~/labs# ./myread /dev/input/event0
open returned 3
read returned 32
read returned 32
read returned 32

Reading events

testuserbtn

Reading events

 

root@beagleboard:~/labs# evtest /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys"
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 276 (ExtraBtn)
Testing ... (interrupt to exit)
Event: time 1307366684.251618, type 1 (Key), code 276 (ExtraBtn), value 1
Event: time 1307366684.251649, -------------- Report Sync ------------
Event: time 1307366684.348203, type 1 (Key), code 276 (ExtraBtn), value 0
Event: time 1307366684.348234, -------------- Report Sync ------------

Access monitor EDID EEPROM

testedid

# opkg install i2c-tools
# i2cdump -y 0x3 0x50 b

Access monitor EDID EEPROM

i2c.c

#include ...
#define DATA_LEN 256

int main()
{
        int file;
        unsigned int i;
        char buf[DATA_LEN];

        file = open("/dev/i2c-3", O_RDWR);
        if (file < 0)                          exit(1);
        if (ioctl(file, I2C_SLAVE, 0x50) < 0)  exit(1);
        if (read(file, buf, DATA_LEN-1) < 1)   exit(1);
        else
                for (i=0;i<DATA_LEN-1;i++)
                        printf("%c", buf[i]);
        return 0;
}

USB OTG and EHCI

 

# cd /sys/bus/usb/devices
# ls
# cat usb1/speed
# cat usb?/manufacturer
# lsusb

Discovering USBFS

 

root@beagleboard:~# cat /sys/module/usbcore/parameters/usbfs_snoop
N
root@beagleboard:~# echo Y > /sys/module/usbcore/parameters/usbfs_snoop
root@beagleboard:~# mount -t usbfs none /mnt
root@beagleboard:~# ls /mnt
001  Devices
root@beagleboard:~/labs# cat /mnt/devices
T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 3
B:  Alloc=  0/800 us ( 0%), #Int=  3, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 2.06
S:  Manufacturer=Linux 2.6.39 ehci_hcd
S:  Product=OMAP-EHCI Host Controller
S:  SerialNumber=ehci-omap.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms
T:  Bus=01 Lev=02 Prnt=02 Port=03 Cnt=03 Dev#=  5 Spd=1.5  MxCh= 0
D:  Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=093a ProdID=2510 Rev= 1.00
S:  Manufacturer=PixArt
S:  Product=USB Optical Mouse
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=10ms

Device nodes

 

Is everything really just a file?

 

GUI building with Qt

 

GUI building with Qt

http://qt.nokia.com

Qt Architecture

Qt modules

http://qt.nokia.com

Qt modules

Qt demos

http://qt.nokia.com

Qt Creator

http://qt.nokia.com

Qt Hello World example

http://qt.nokia.com

#include <QtGui>

int main( int argc, char *argv[] )
{
    QApplication myapp( argc, argv );
    QLabel *mylabel = new 
    QLabel("Helloworld");
    mylabel->show();
    return myapp.exec();
}

Lab #1 - Toggle an LED with SYSFS

 

# cd /sys/class/leds/
# ls
beagleboard::pmu_stat  beagleboard::usr0  beagleboard::usr1
# cd beagleboard\:\:usr0
# ls
brightness  device  max_brightness  power  subsystem  trigger  uevent
# cat trigger
none nand-disk mmc0 [heartbeat]
echo "none" > trigger
# echo "1" > brightness
# echo "0" > brightness
# echo "heartbeat" > trigger

Lab #2 - Read I2C

 

root@beagleboard:~/lab# cd /home/root/lab
root@beagleboard:~/lab# ls
root@beagleboard:~/lab# rm i2c
root@beagleboard:~/lab# cat i2c.c
root@beagleboard:~/lab# make i2c
root@beagleboard:~/lab# ./i2c

Lab #3 - Toggle LED from Qt

 

root@beagleboard:~/lab# cd qt
root@beagleboard:~/lab/qt# ls
root@beagleboard:~/lab/qt# make distclean
...
root@beagleboard:~/lab/qt# ls
(inspect the files...)
root@beagleboard:~/lab/qt# designer led.ui
root@beagleboard:~/lab/qt# cat main.cpp
root@beagleboard:~/lab/qt# gedit led.cpp
root@beagleboard:~/lab/qt# . /usr/share/qt4/environment-setup
root@beagleboard:~/lab/qt# qmake-qt4
root@beagleboard:~/lab/qt# make
root@beagleboard:~/lab/qt# ./qt

Summary