Size: 3607
Comment:
|
Size: 19357
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
= ISELFInalProjectInfo = | ## page was renamed from ISELFInalProjectInfo = ISELFinalProjectInfo = |
Line 20: | Line 21: |
=== Create entry / attributes === https://godandme.wordpress.com/2011/04/05/how-to-make-a-sysfs-entry/ http://stackoverflow.com/questions/11063719/kernel-modules-parameters-in-sysfs-quick-reaction-for-changes http://stackoverflow.com/questions/11067262/getting-parent-for-kobject-add |
|
Line 61: | Line 69: |
Datasheet: http://cache.freescale.com/files/sensors/doc/data_sheet/FXOS8700CQ.pdf |
|
Line 62: | Line 72: |
* su * cd /usr/src/linux/ * mkdir helloWorld * nano Makefile |
{{{#!highlight sh su cd /usr/src/linux/ mkdir helloWorld cd helloWorld nano Makefile }}} |
Line 91: | Line 105: |
module_init(hello_init); module_exit(hello_exit); }}} * make * tail -f /var/log/messages * insmod helloWorld.ko * rmmod helloWorld.ko |
module_init(helloworld_init); module_exit(helloworld_exit); MODULE_LICENSE("GPL"); }}} {{{#!highlight sh make clean make # tail -f /var/log/messages insmod helloWorld.ko dmesg ls /sys/module # /sys/module/helloWorld should appear rmmod helloWorld.ko }}} == sysfs sample == Based on https://godandme.wordpress.com/2011/04/05/how-to-make-a-sysfs-entry/ Directory located in /usr/src/linux/sysfs_sample '''Makefile''' {{{ obj-m = sysfs_sample.o KVERSION = $(shell uname -r) all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean }}} '''sysfs_sample.c''' {{{#!highlight c /* indent -linux sysfs_sample.c make clean make insmod sysfs_sample.ko tail /var/log/messages cat /sys/module/sysfs_sample/sysfs_sample_attrs/first cat /sys/module/sysfs_sample/sysfs_sample_attrs/second cat /sys/module/sysfs_sample/sysfs_sample_attrs/operation echo "asdf" > /sys/module/sysfs_sample/sysfs_sample_attrs/operation cat /sys/module/sysfs_sample/sysfs_sample_attrs/operation dmesg rmmod sysfs_sample.ko */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/slab.h> /*A struct kobject represents a kernel object, maybe a device or so, such as the things that show up as directory in the sysfs filesystem.*/ struct kobject *sysfs_sample_kobject; struct int_attribute { struct attribute attr; int value; }; struct string_attribute { struct attribute attr; char value[64]; }; static struct int_attribute first_attribute = {.attr.name = "first",.attr.mode = 0666,.value = 11, }; static struct int_attribute second_attribute = {.attr.name = "second",.attr.mode = 0666,.value = 22, }; static struct string_attribute operation_attribute = {.attr.name = "operation",.attr.mode = 0666,.value = "add", }; static struct attribute *sysfs_sample_attributes[] = { &first_attribute.attr, &second_attribute.attr, &operation_attribute.attr, NULL }; /*Called when a read is performed on a attribute file in sysfs */ static ssize_t default_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct int_attribute *intAttr; struct string_attribute *stringAttr; printk(KERN_INFO "Show called for kobject %s\n", kobj->name); printk(KERN_INFO "Attribute name: %s\n", attr->name); /* convert to proper struct based on name */ if (strcmp("operation", attr->name) != 0) { intAttr = container_of(attr, struct int_attribute, attr); return scnprintf(buf, PAGE_SIZE, "%d\n", intAttr->value); } else { stringAttr = container_of(attr, struct string_attribute, attr); return scnprintf(buf, PAGE_SIZE, "%s\n", stringAttr->value); } } /*Called when a write is performed on a attribute file in sysfs */ static ssize_t default_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { struct int_attribute *intAttr; struct string_attribute *stringAttr; printk(KERN_INFO "Store called for kobject %s\n", kobj->name); if (strcmp("operation", attr->name) != 0) { intAttr = container_of(attr, struct int_attribute, attr); sscanf(buf, "%d", &(intAttr->value)); /*convert char to int */ return sizeof(int); } else { stringAttr = container_of(attr, struct string_attribute, attr); sscanf(buf, "%s", stringAttr->value); /*convert char to char */ printk(KERN_INFO "Sizeof %d\n", sizeof(stringAttr->value)); return sizeof(stringAttr->value); } } static struct sysfs_ops sysfs_sample_operations = {.show = default_show,.store = default_store, }; static struct kobj_type sysfs_sample_type = {.sysfs_ops = &sysfs_sample_operations,.default_attrs = sysfs_sample_attributes, }; /*Called on module initialization */ static int __init sysfsexample_module_init(void) { int err = -1; printk(KERN_INFO "sysfs_sample init called \n"); sysfs_sample_kobject = kzalloc(sizeof(*sysfs_sample_kobject), GFP_KERNEL); if (sysfs_sample_kobject) { kobject_init(sysfs_sample_kobject, &sysfs_sample_type); // if (kobject_add(sysfs_sample_kobject, NULL, "%s", "sysfs_sample")) { if (kobject_add (sysfs_sample_kobject, &THIS_MODULE->mkobj.kobj, "%s", "sysfs_sample_attrs")) { err = -1; printk(KERN_INFO "sysfs_sample creation failed\n"); kobject_put(sysfs_sample_kobject); sysfs_sample_kobject = NULL; } err = 0; } return err; } /*Called on module exit */ static void __exit sysfsexample_module_exit(void) { printk(KERN_INFO "sysfs_sample exit called \n"); if (sysfs_sample_kobject) { kobject_put(sysfs_sample_kobject); kfree(sysfs_sample_kobject); } } module_init(sysfsexample_module_init); module_exit(sysfsexample_module_exit); MODULE_LICENSE("GPL"); }}} == RTC device info == https://www.kernel.org/doc/Documentation/rtc.txt The interrupts are reported via /dev/rtc (major 10, minor 135, read only character device) The alarm and/or interrupt frequency are programmed into the RTC via various ioctl(2) calls as listed in ./include/linux/rtc.h The sysfs interface under /sys/class/rtc/rtcN provides access to various rtc attributes without requiring the use of ioctls. The ioctl() calls supported by /dev/rtc are also supported by the RTC class framework. == Sysfs support == From https://coherentmusings.wordpress.com/2014/02/19/adding-sysfs-support-to-a-driver/ {{{ As the Linux Kernel Development book mentions "The sysfs file system is currently the place for implementing functionality previously reserved for ioctl() calls on device nodes or the procfs filesystem" }}} === ARM Cross compiling === https://www.ailis.de/~k/archives/19-ARM-cross-compiling-howto.html http://frank.harvard.edu/~coldwell/toolchain/ * http://ftp.slackware.com/pub/slackware/slackware-14.0/source/d/binutils/binutils-2.22.52.0.2.tar.xz * http://ftp.slackware.com/pub/slackware/slackware-14.0/source/d/gcc/gcc-4.7.1.tar.xz * http://ftp.slackware.com/pub/slackware/slackware-14.0/source/l/glibc/glibc-2.15.tar.xz Based on gcc and glibc used on the embedded device * https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.5.tar.xz * http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 * http://ftp.gnu.org/gnu/gcc/gcc-4.8.4/gcc-4.8.4.tar.bz2 * http://ftp.gnu.org/gnu/glibc/glibc-2.20.tar.xz http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/ http://xathrya.web.id/blog/2013/02/28/building-gcc-arm-toolchain-on-slackware64/ === With emdebian Ubuntu lucid32 === {{{#!highlight sh nano /etc/apt/sources.list apt-get update apt-get install linux-libc-dev-armel-cross libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi gcc-4.4-arm-linux-gnueabi apt-get install g++-4.4-arm-linux-gnueabi apt-get install pdebuild-cross apt-get install dpkg-cross qemu cd /tmp wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.5.tar.xz tar xvif linux-3.13.5.tar.xz mv linux-3.13.5 /usr/src /usr/src/ cd /usr/src ln -s linux-3.13.5 linux ls cd linux make ARCH=arm at91sam9260_9g20_defconfig # copy config for ARM at91sam9260 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- export INSTALL_MOD_PATH=/lib/modules/arm/3.13.5/ make modules find . -name "*.ko" | xargs -i file {} make modules_install # to /tmp/lib .... mkdir -p /usr/src/linux/helloWorld cd /usr/src/linux/helloWorld }}} ==== Makefile ==== {{{ obj-m = helloWorld.o KVERSION=3.13.5 all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean }}} ==== helloWorld.c ==== {{{#!highlight c #include <linux/module.h> /* Required by all modules */ #include <linux/kernel.h> /* Required for KERN_INFO */ #include <linux/init.h> /* Required for the macros */ static int __init helloworld_init(void) { printk(KERN_INFO "Hello world\n"); return 0; } static void __exit helloworld_exit(void) { printk(KERN_INFO "Bye all.\n"); } module_init(helloworld_init); module_exit(helloworld_exit); MODULE_LICENSE("GPL"); }}} {{{#!highlight sh cd helloWorld make clean make }}} == Simple hello ARM == {{{#!highlight sh lsb_release -a #No LSB modules are available. #Distributor ID: Ubuntu #Description: Ubuntu 10.04.4 LTS #Release: 10.04 #Codename: lucid arm-linux-gnueabi-gcc --version #arm-linux-gnueabi-gcc (Debian 4.4.5-8) 4.4.5 cat hello.c #include <stdio.h> int main() { printf("Hello cross-compiling world!\n"); return 0; } arm-linux-gnueabi-gcc -static hello.c -o hello qemu-arm -cpu arm926 hello # Hello cross-compiling world! $arm-linux-gnueabi-gcc hello.c -o hello $qemu-arm -L /usr/arm-linux-gnueabi/ hello Hello cross-compiling world! $file hello hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabi- export INSTALL_MOD_PATH=/lib/modules/arm/3.13.5/ cd /usr/src/linux/helloWorld/ cat helloWorld.c #include <linux/module.h> /* Required by all modules */ #include <linux/kernel.h> /* Required for KERN_INFO */ #include <linux/init.h> /* Required for the macros */ static int __init helloworld_init(void) { printk(KERN_INFO "Hello world\n"); return 0; } static void __exit helloworld_exit(void) { printk(KERN_INFO "Bye all.\n"); return; } module_init(helloworld_init); module_exit(helloworld_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("DonaldDuck"); make clean make scp helloworld.ko root@192.168.1.100:/tmp # on embedded system insmod helloworld.ko dmesg # should show an hello world rmmod -f helloworld }}} == Hard iron interference calibration == {{{#!highlight python ''' Based on the worked example 1 from AN4246 - Freescale Calibrating an eCompass in the Presence of Hard and Soft-Iron Interference http://www.freescale.com/files/sensors/doc/app_note/AN4246.pdf http://en.wikipedia.org/wiki/Earth's_magnetic_field Its magnitude at the Earth's surface ranges from 25 to 65 microtesla (0.25 to 0.65 gauss). The tesla is the SI unit of the Magnetic field, B. ''' import numpy as np import math import unittest def calculateBeta(measuresA): measures=np.array(measuresA) #print '# Measures #' #for i in measures: print i yMatrix=[] #calculate squares for each item for m in measures: yMatrix.append( (m[0]*m[0]) +(m[1]*m[1]) + (m[2]*m[2]) ) yMatrix=np.array(yMatrix) #print '# Y matrix #' #for i in yMatrix: print i xMatrix=[] for m in measures: xMatrix.append( [m[0],m[1],m[2],1] ) xMatrix=np.array(xMatrix) #print '# X Matrix #' #for j in xMatrix: print j #print "beta = ( X' * X )^-1 * X'*Measures " transposeX = np.matrix.transpose( xMatrix ) #print '# X Matrix transpose#' #for j in transposeX: print j r1 = np.dot(transposeX , xMatrix) #print "r1\n%s"%(r1) inv1 = np.linalg.inv(r1) #print "inv1\n%s"%(inv1) r2 = np.dot(inv1,transposeX) #print "r2\n%s"%(r2) beta = np.dot(r2,yMatrix) #print "beta\n%s"%(beta) #vx = beta[0]*0.5 #vy = beta[1]*0.5 #vz = beta[2]*0.5 #print " %f %f %f"%(vx, vy , vz) #B = math.sqrt( (beta[3]) + (vx*vx) + (vy*vy) + (vz*vz) ) #print "%f uT"%(B) #return B return beta ######################################################################## class SimpleTestCase(unittest.TestCase): def testCalculation(self): # the norm of the vector should be between 25 and 65 #acquired magnetometer measures measures=[] measures.append([167.4 , -242.4 ,91.7]) measures.append([140.3 , -221.9 ,86.8]) measures.append([152.4 , -230.4 ,-0.6]) measures.append([180.3 , -270.6 ,71.0]) measures.append([190.9 , -212.4 ,62.7]) measures.append([192.9 , -242.4 ,17.1]) Beta = calculateBeta(measures) #print "%s "%(Beta) vx = Beta[0]*0.5 vy = Beta[1]*0.5 vz = Beta[2]*0.5 # subtract V from the measures ... for m in measures: # subtract the strong iron effect from the raw measure vector=[m[0]-vx,m[1]-vy,m[2]-vz] normVector = np.linalg.norm( vector ) self.assertTrue( normVector>= 25 and normVector <=65 ) self.assertTrue( normVector>= 47 and normVector <48 ) if __name__=='__main__': unittest.main() }}} == Build GSL for ARM on emdebian == {{{#!highlight sh mkdir -p /usr/local/arm cp gsl-1.16.tar.gz /tmp cd /tmp tar xvzf gsl-1.16.tar.gz cd gsl-1.16 ./configure --prefix=/usr/local/arm --exec-prefix=/usr/local/arm CC=arm-linux-gnueabi-gcc --host armv5 --target arm-linux-gnueabi make clean; make; make install }}} == Vagrant, change Vagrantfile to SSH listen on 0.0.0.0 == Change Vagrantfile {{{ config.vm.network :forwarded_port, guest: 22, host: 2222, host_ip: "0.0.0.0", id: "ssh", auto_correct: true }}} == GSL, blas example == Matrices multiplication {{{#!highlight c /* cc blasExample.c -o blasExample -lgsl -lgslcblas cc blasExample.c -o blasExample -lgsl -lgslcblas -lm -static on emdebian arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/ -L/usr/arm-linux-gnueabi/lib arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/ arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/ -static qemu-arm blasExample */ #include <stdio.h> #include <gsl/gsl_blas.h> int main (void) { double a[] = { 0.11, 0.12, 0.13, 0.21, 0.22, 0.23 }; double b[] = { 1011, 1012, 1021, 1022, 1031, 1032 }; double c[] = { 0.00, 0.00, 0.00, 0.00 }; gsl_matrix_view A = gsl_matrix_view_array(a, 2, 3); gsl_matrix_view B = gsl_matrix_view_array(b, 3, 2); gsl_matrix_view C = gsl_matrix_view_array(c, 2, 2); /* Compute C = A B */ gsl_blas_dgemm (CblasNoTrans, CblasNoTrans, 1.0, &A.matrix, &B.matrix, 0.0, &C.matrix); printf ("[ %g, %g\n", c[0], c[1]); printf (" %g, %g ]\n", c[2], c[3]); return 0; } }}} == ARM GPIO, General Purpose Input/Output == * http://www.zembedded.com/arm-gpio-general-purpose-input-output-register/ |
ISELFinalProjectInfo
Information about several subjects regarding the ISEL final project.
Linux Kernel
https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.5.tar.xz
Linux Device Drivers book
http://lwn.net/images/pdf/LDD3/ldd3_pdf.tar.bz2
sysfs
http://lxr.free-electrons.com/source/Documentation/filesystems/sysfs.txt
What it is:
sysfs is a ram-based filesystem initially based on ramfs. It provides a means to export kernel data structures, their attributes, and the linkages between them to userspace.
sysfs is tied inherently to the kobject infrastructure. Please read Documentation/kobject.txt for more information concerning the kobject interface.
- /usr/src/linux-3.2.45/Documentation/filesystems/sysfs.txt
Create entry / attributes
https://godandme.wordpress.com/2011/04/05/how-to-make-a-sysfs-entry/
http://stackoverflow.com/questions/11067262/getting-parent-for-kobject-add
IIO
Adapted from http://wiki.analog.com/software/linux/docs/iio/iio
The Industrial I/O subsystem is intended to provide support for devices that in some sense are analog to digital or digital to analog convertors (ADCs, DACs). Devices that fall into this category are:
- ADCs
- Accelerometers
- Gyros
- IMUs
- Capacitance to Digital Converters (CDCs)
- Pressure Sensors
- Color, Light and Proximity Sensors
- Temperature Sensors
- Magnetometers
- DACs
- DDS (Direct Digital Synthesis)
- PLLs (Phase Locked Loops)
- Variable/Programmable Gain Amplifiers (VGA, PGA)
SPI
I2C
ARM AT91SAM9260B
http://www.atmel.com/devices/sam9260.aspx
A 210MHz ARM926-based processor with an extensive range of communication peripherals. It embeds FS USB host and device interfaces, a 10/100 Ethernet MAC and an image sensor interface, as well as standard peripherals such as a Multimedia Card Interface (MCI), I2S, USARTs, master/slave SPIs, 16-bit Timers, a TWI and four-channel 10-bit ADC. The external bus interface features controllers for SDRAM and static memories including NAND flash and CompactFlash. The SAM9260 is available in 217-ball LFBGA and 208-pin QFP packages.
Linux4SAM
http://www.at91.com/linux4sam/bin/view/Linux4SAM/WebHome
http://www.at91.com/linux4sam/bin/view/Linux4SAM/GettingStarted
http://www.at91.com/linux4sam/bin/view/Linux4SAM/IioAdcDriver
FXOS8700CQ
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FXOS8700CQ
Freescale’s FXOS8700CQ 6-axis sensor combines industry leading accelerometer and magnetometer sensors in a small 3 x 3 x 1.2 mm QFN plastic package. The 14-bit accelerometer and 16-bit magnetometer are combined with a high-performance ASIC to enable an eCompass solution capable of a typical orientation resolution of 0.1 degrees and sub 5 degree compass heading accuracy for most applications.
Datasheet: http://cache.freescale.com/files/sensors/doc/data_sheet/FXOS8700CQ.pdf
Hello world linux kernel module on Slackware 14
obj-m = helloWorld.o KVERSION = $(shell uname -r) all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
- nano helloWorld.c
1 #include <linux/module.h> /* Required by all modules */
2 #include <linux/kernel.h> /* Required for KERN_INFO */
3 #include <linux/init.h> /* Required for the macros */
4
5 static int __init helloworld_init(void)
6 {
7 printk(KERN_INFO "Hello world\n");
8 return 0;
9 }
10
11 static void __exit helloworld_exit(void)
12 {
13 printk(KERN_INFO "Bye all.\n");
14 }
15
16 module_init(helloworld_init);
17 module_exit(helloworld_exit);
18 MODULE_LICENSE("GPL");
sysfs sample
Based on https://godandme.wordpress.com/2011/04/05/how-to-make-a-sysfs-entry/
Directory located in /usr/src/linux/sysfs_sample
Makefile
obj-m = sysfs_sample.o KVERSION = $(shell uname -r) all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
sysfs_sample.c
1 /*
2 indent -linux sysfs_sample.c
3 make clean
4 make
5 insmod sysfs_sample.ko
6 tail /var/log/messages
7 cat /sys/module/sysfs_sample/sysfs_sample_attrs/first
8 cat /sys/module/sysfs_sample/sysfs_sample_attrs/second
9 cat /sys/module/sysfs_sample/sysfs_sample_attrs/operation
10 echo "asdf" > /sys/module/sysfs_sample/sysfs_sample_attrs/operation
11 cat /sys/module/sysfs_sample/sysfs_sample_attrs/operation
12 dmesg
13 rmmod sysfs_sample.ko
14 */
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/fs.h>
19 #include <linux/slab.h>
20 /*A struct kobject represents a kernel object, maybe a device or so,
21 such as the things that show up as directory in the sysfs filesystem.*/
22 struct kobject *sysfs_sample_kobject;
23 struct int_attribute {
24 struct attribute attr;
25 int value;
26 };
27 struct string_attribute {
28 struct attribute attr;
29 char value[64];
30 };
31 static struct int_attribute first_attribute = {.attr.name = "first",.attr.mode =
32 0666,.value = 11, };
33 static struct int_attribute second_attribute = {.attr.name =
34 "second",.attr.mode = 0666,.value = 22, };
35 static struct string_attribute operation_attribute = {.attr.name =
36 "operation",.attr.mode = 0666,.value = "add", };
37 static struct attribute *sysfs_sample_attributes[] =
38 { &first_attribute.attr, &second_attribute.attr, &operation_attribute.attr,
39 NULL };
40 /*Called when a read is performed on a attribute file in sysfs */
41 static ssize_t default_show(struct kobject *kobj, struct attribute *attr,
42 char *buf)
43 {
44 struct int_attribute *intAttr;
45 struct string_attribute *stringAttr;
46 printk(KERN_INFO "Show called for kobject %s\n", kobj->name);
47 printk(KERN_INFO "Attribute name: %s\n", attr->name);
48 /* convert to proper struct based on name */
49 if (strcmp("operation", attr->name) != 0) {
50 intAttr = container_of(attr, struct int_attribute, attr);
51 return scnprintf(buf, PAGE_SIZE, "%d\n", intAttr->value);
52 } else {
53 stringAttr = container_of(attr, struct string_attribute, attr);
54 return scnprintf(buf, PAGE_SIZE, "%s\n", stringAttr->value);
55 }
56 }
57
58 /*Called when a write is performed on a attribute file in sysfs */
59 static ssize_t default_store(struct kobject *kobj, struct attribute *attr,
60 const char *buf, size_t len)
61 {
62 struct int_attribute *intAttr;
63 struct string_attribute *stringAttr;
64 printk(KERN_INFO "Store called for kobject %s\n", kobj->name);
65
66 if (strcmp("operation", attr->name) != 0) {
67 intAttr = container_of(attr, struct int_attribute, attr);
68 sscanf(buf, "%d", &(intAttr->value)); /*convert char to int */
69 return sizeof(int);
70 } else {
71 stringAttr = container_of(attr, struct string_attribute, attr);
72 sscanf(buf, "%s", stringAttr->value); /*convert char to char */
73 printk(KERN_INFO "Sizeof %d\n", sizeof(stringAttr->value));
74 return sizeof(stringAttr->value);
75 }
76 }
77
78 static struct sysfs_ops sysfs_sample_operations = {.show = default_show,.store =
79 default_store, };
80 static struct kobj_type sysfs_sample_type = {.sysfs_ops =
81 &sysfs_sample_operations,.default_attrs =
82 sysfs_sample_attributes, };
83 /*Called on module initialization */
84 static int __init sysfsexample_module_init(void)
85 {
86 int err = -1;
87 printk(KERN_INFO "sysfs_sample init called \n");
88 sysfs_sample_kobject =
89 kzalloc(sizeof(*sysfs_sample_kobject), GFP_KERNEL);
90 if (sysfs_sample_kobject) {
91 kobject_init(sysfs_sample_kobject, &sysfs_sample_type);
92 // if (kobject_add(sysfs_sample_kobject, NULL, "%s", "sysfs_sample")) {
93 if (kobject_add
94 (sysfs_sample_kobject, &THIS_MODULE->mkobj.kobj, "%s",
95 "sysfs_sample_attrs")) {
96 err = -1;
97 printk(KERN_INFO "sysfs_sample creation failed\n");
98 kobject_put(sysfs_sample_kobject);
99 sysfs_sample_kobject = NULL;
100 }
101 err = 0;
102 }
103 return err;
104 }
105
106 /*Called on module exit */
107 static void __exit sysfsexample_module_exit(void)
108 {
109 printk(KERN_INFO "sysfs_sample exit called \n");
110 if (sysfs_sample_kobject) {
111 kobject_put(sysfs_sample_kobject);
112 kfree(sysfs_sample_kobject);
113 }
114 }
115
116 module_init(sysfsexample_module_init);
117 module_exit(sysfsexample_module_exit);
118 MODULE_LICENSE("GPL");
RTC device info
https://www.kernel.org/doc/Documentation/rtc.txt
The interrupts are reported via /dev/rtc (major 10, minor 135, read only character device)
The alarm and/or interrupt frequency are programmed into the RTC via various ioctl(2) calls as listed in ./include/linux/rtc.h
The sysfs interface under /sys/class/rtc/rtcN provides access to various rtc attributes without requiring the use of ioctls.
The ioctl() calls supported by /dev/rtc are also supported by the RTC class framework.
Sysfs support
From https://coherentmusings.wordpress.com/2014/02/19/adding-sysfs-support-to-a-driver/
As the Linux Kernel Development book mentions "The sysfs file system is currently the place for implementing functionality previously reserved for ioctl() calls on device nodes or the procfs filesystem"
ARM Cross compiling
https://www.ailis.de/~k/archives/19-ARM-cross-compiling-howto.html
http://frank.harvard.edu/~coldwell/toolchain/
http://ftp.slackware.com/pub/slackware/slackware-14.0/source/d/binutils/binutils-2.22.52.0.2.tar.xz
http://ftp.slackware.com/pub/slackware/slackware-14.0/source/d/gcc/gcc-4.7.1.tar.xz
http://ftp.slackware.com/pub/slackware/slackware-14.0/source/l/glibc/glibc-2.15.tar.xz
Based on gcc and glibc used on the embedded device
http://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/
http://xathrya.web.id/blog/2013/02/28/building-gcc-arm-toolchain-on-slackware64/
With emdebian Ubuntu lucid32
1 nano /etc/apt/sources.list
2 apt-get update
3 apt-get install linux-libc-dev-armel-cross libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi gcc-4.4-arm-linux-gnueabi
4 apt-get install g++-4.4-arm-linux-gnueabi
5 apt-get install pdebuild-cross
6 apt-get install dpkg-cross qemu
7 cd /tmp
8 wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.5.tar.xz
9 tar xvif linux-3.13.5.tar.xz
10 mv linux-3.13.5 /usr/src
11 /usr/src/
12 cd /usr/src
13 ln -s linux-3.13.5 linux
14 ls
15 cd linux
16 make ARCH=arm at91sam9260_9g20_defconfig # copy config for ARM at91sam9260
17 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
18 export ARCH=arm
19 export CROSS_COMPILE=arm-linux-gnueabi-
20 export INSTALL_MOD_PATH=/lib/modules/arm/3.13.5/
21 make modules
22 find . -name "*.ko" | xargs -i file {}
23 make modules_install # to /tmp/lib ....
24 mkdir -p /usr/src/linux/helloWorld
25 cd /usr/src/linux/helloWorld
Makefile
obj-m = helloWorld.o KVERSION=3.13.5 all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
helloWorld.c
1 #include <linux/module.h> /* Required by all modules */
2 #include <linux/kernel.h> /* Required for KERN_INFO */
3 #include <linux/init.h> /* Required for the macros */
4
5 static int __init helloworld_init(void)
6 {
7 printk(KERN_INFO "Hello world\n");
8 return 0;
9 }
10
11 static void __exit helloworld_exit(void)
12 {
13 printk(KERN_INFO "Bye all.\n");
14 }
15
16 module_init(helloworld_init);
17 module_exit(helloworld_exit);
18 MODULE_LICENSE("GPL");
Simple hello ARM
1 lsb_release -a
2 #No LSB modules are available.
3 #Distributor ID: Ubuntu
4 #Description: Ubuntu 10.04.4 LTS
5 #Release: 10.04
6 #Codename: lucid
7
8 arm-linux-gnueabi-gcc --version
9 #arm-linux-gnueabi-gcc (Debian 4.4.5-8) 4.4.5
10 cat hello.c
11 #include <stdio.h>
12
13 int main()
14 {
15 printf("Hello cross-compiling world!\n");
16 return 0;
17 }
18
19 arm-linux-gnueabi-gcc -static hello.c -o hello
20 qemu-arm -cpu arm926 hello
21 # Hello cross-compiling world!
22
23 $arm-linux-gnueabi-gcc hello.c -o hello
24 $qemu-arm -L /usr/arm-linux-gnueabi/ hello
25 Hello cross-compiling world!
26 $file hello
27 hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
28
29 export ARCH=arm
30 export CROSS_COMPILE=arm-linux-gnueabi-
31 export INSTALL_MOD_PATH=/lib/modules/arm/3.13.5/
32 cd /usr/src/linux/helloWorld/
33
34 cat helloWorld.c
35 #include <linux/module.h> /* Required by all modules */
36 #include <linux/kernel.h> /* Required for KERN_INFO */
37 #include <linux/init.h> /* Required for the macros */
38
39 static int __init helloworld_init(void)
40 {
41 printk(KERN_INFO "Hello world\n");
42 return 0;
43 }
44
45 static void __exit helloworld_exit(void)
46 {
47 printk(KERN_INFO "Bye all.\n");
48 return;
49 }
50
51 module_init(helloworld_init);
52 module_exit(helloworld_exit);
53 MODULE_LICENSE("GPL");
54 MODULE_AUTHOR("DonaldDuck");
55
56 make clean
57 make
58 scp helloworld.ko root@192.168.1.100:/tmp
59 # on embedded system
60 insmod helloworld.ko
61 dmesg # should show an hello world
62 rmmod -f helloworld
Hard iron interference calibration
1 '''
2 Based on the worked example 1 from AN4246 - Freescale
3 Calibrating an eCompass in the Presence of Hard and Soft-Iron Interference
4 http://www.freescale.com/files/sensors/doc/app_note/AN4246.pdf
5
6 http://en.wikipedia.org/wiki/Earth's_magnetic_field
7 Its magnitude at the Earth's surface ranges from 25 to 65 microtesla (0.25 to 0.65 gauss).
8
9 The tesla is the SI unit of the Magnetic field, B.
10
11 '''
12 import numpy as np
13 import math
14 import unittest
15
16 def calculateBeta(measuresA):
17 measures=np.array(measuresA)
18 #print '# Measures #'
19 #for i in measures: print i
20 yMatrix=[]
21 #calculate squares for each item
22 for m in measures: yMatrix.append( (m[0]*m[0]) +(m[1]*m[1]) + (m[2]*m[2]) )
23 yMatrix=np.array(yMatrix)
24 #print '# Y matrix #'
25 #for i in yMatrix: print i
26 xMatrix=[]
27 for m in measures: xMatrix.append( [m[0],m[1],m[2],1] )
28 xMatrix=np.array(xMatrix)
29 #print '# X Matrix #'
30 #for j in xMatrix: print j
31 #print "beta = ( X' * X )^-1 * X'*Measures "
32 transposeX = np.matrix.transpose( xMatrix )
33 #print '# X Matrix transpose#'
34 #for j in transposeX: print j
35 r1 = np.dot(transposeX , xMatrix)
36 #print "r1\n%s"%(r1)
37 inv1 = np.linalg.inv(r1)
38 #print "inv1\n%s"%(inv1)
39 r2 = np.dot(inv1,transposeX)
40 #print "r2\n%s"%(r2)
41 beta = np.dot(r2,yMatrix)
42 #print "beta\n%s"%(beta)
43 #vx = beta[0]*0.5
44 #vy = beta[1]*0.5
45 #vz = beta[2]*0.5
46 #print " %f %f %f"%(vx, vy , vz)
47 #B = math.sqrt( (beta[3]) + (vx*vx) + (vy*vy) + (vz*vz) )
48 #print "%f uT"%(B)
49 #return B
50 return beta
51 ########################################################################
52
53 class SimpleTestCase(unittest.TestCase):
54 def testCalculation(self):
55 # the norm of the vector should be between 25 and 65
56 #acquired magnetometer measures
57 measures=[]
58 measures.append([167.4 , -242.4 ,91.7])
59 measures.append([140.3 , -221.9 ,86.8])
60 measures.append([152.4 , -230.4 ,-0.6])
61 measures.append([180.3 , -270.6 ,71.0])
62 measures.append([190.9 , -212.4 ,62.7])
63 measures.append([192.9 , -242.4 ,17.1])
64 Beta = calculateBeta(measures)
65 #print "%s "%(Beta)
66 vx = Beta[0]*0.5
67 vy = Beta[1]*0.5
68 vz = Beta[2]*0.5
69 # subtract V from the measures ...
70 for m in measures:
71 # subtract the strong iron effect from the raw measure
72 vector=[m[0]-vx,m[1]-vy,m[2]-vz]
73 normVector = np.linalg.norm( vector )
74 self.assertTrue( normVector>= 25 and normVector <=65 )
75 self.assertTrue( normVector>= 47 and normVector <48 )
76
77 if __name__=='__main__':
78 unittest.main()
Build GSL for ARM on emdebian
Vagrant, change Vagrantfile to SSH listen on 0.0.0.0
Change Vagrantfile
config.vm.network :forwarded_port, guest: 22, host: 2222, host_ip: "0.0.0.0", id: "ssh", auto_correct: true
GSL, blas example
Matrices multiplication
1 /*
2 cc blasExample.c -o blasExample -lgsl -lgslcblas
3 cc blasExample.c -o blasExample -lgsl -lgslcblas -lm -static
4
5 on emdebian
6 arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/ -L/usr/arm-linux-gnueabi/lib
7 arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/
8
9 arm-linux-gnueabi-gcc blasExample.c -o blasExample -lgsl -lgslcblas -lm -I/usr/local/arm/include/ -L/usr/local/arm/lib/ -static
10 qemu-arm blasExample
11 */
12 #include <stdio.h>
13 #include <gsl/gsl_blas.h>
14
15 int
16 main (void)
17 {
18 double a[] = { 0.11, 0.12, 0.13,
19 0.21, 0.22, 0.23 };
20
21 double b[] = { 1011, 1012,
22 1021, 1022,
23 1031, 1032 };
24
25 double c[] = { 0.00, 0.00,
26 0.00, 0.00 };
27
28 gsl_matrix_view A = gsl_matrix_view_array(a, 2, 3);
29 gsl_matrix_view B = gsl_matrix_view_array(b, 3, 2);
30 gsl_matrix_view C = gsl_matrix_view_array(c, 2, 2);
31
32 /* Compute C = A B */
33
34 gsl_blas_dgemm (CblasNoTrans, CblasNoTrans,
35 1.0, &A.matrix, &B.matrix,
36 0.0, &C.matrix);
37
38 printf ("[ %g, %g\n", c[0], c[1]);
39 printf (" %g, %g ]\n", c[2], c[3]);
40
41 return 0;
42 }