| Size: 3873 Comment:  | Size: 9746 Comment:  | 
| Deletions are marked like this. | Additions are marked like this. | 
| Line 1: | Line 1: | 
| ## page was renamed from ISELFInalProjectInfo | |
| Line 25: | Line 26: | 
| http://stackoverflow.com/questions/11067262/getting-parent-for-kobject-add | |
| Line 104: | Line 107: | 
| == 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. | 
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.
Hello world linux kernel module on Slackware 14
- su
- cd /usr/src/linux/
- mkdir helloWorld
- nano Makefile
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);
- make
- tail -f /var/log/messages
- insmod helloWorld.ko
- /sys/module/helloWorld # module !!!
- 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) cleansysfs_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.
