MPS+Ov9

i denne del af opgaven tester vi om vores tool chaine virker korekt. Dette gøres ved at kompilerer programmet.
 * Del1:**
 * a)** //Kompilér mygpio_basic.//


 * b)** //Sammenhold eksemplerne 5.6 og 5.7 i bogen og vær opmærksom på forskellene. Bemærk at der i 5.7 benyttes en makro til pre-compileren for at få den til at generere 8 ens funktioner: glow_led0, glow_led1....glow_led7. Start med at kigge på init og exit metoderne (her: init / cleanup) og bemærk at der nu er tilføjes en klasse og kobjects som som får filsvarende filer i sysfs. I den seneste version af kernen, erstattes device_class_create med class_create og denne udfører selv manipulation på kobjekter, så dette kan udelades ifht eksempel 5.7. Eksemplerne benytter desuden en "parport" bus, hvilket gør at led driveren registreres som en parport driver. Vores eksempel er mere simpelt og dette skridt kan også udelades.//

i denne del af opgaven sammenholdes eksemplerne eksemplerne 5.6 og 5.7

code //*************************************************************** // globale variabler //*************************************************************** static struct class *myGpio_class; //Klassen som devicet tilhører. struct device *myGpio_device; code
 * c)** //Tilføj en sysfs klasse "mygpio", således at vores driver får sin egen klasse under /sys/class/. Benyt metoderne beskrevet nedenfor i jeres init/exit metoder://
 * Global**

code format="c" //************************************************************************** //oprettelse af classe når denne oprettes oprettes der en mappe under sysfs //**************************************************************************   mygpio_class = class_create(THIS_MODULE, "myGpio"); if(IS_ERR(myGpio_class)) {     printk("Class not created\n"); //Fejlmeddelse ved fejl } //************************************************************************** //Oprettelse af en fil under den mappe i sysfs. //**************************************************************************   myGpio_device = device_create(mygpio_class, NULL, devno, NULL, "myGpio"); printk("mygpio driver successfull initialized"); code
 * Init**

Exit code //********************************************************* // nedlæggelse af filer //******************************************************** device_destroy(mygpio_class, devno); //Nedlæggelse af devic class_destroy(mygpio_class); //Nedlæggelse af mappen mygpio i sysfs code


 * d)** //Kompiler og kopier modulet til target. Lav to ssh forbindelser til target. På den ene startes "udevadm monitor" og via den anden forbindelse indsættes modulet. Bemærk hvad som sker og undersøg forandringerne i /sys/class, samt under /dev/ med ls -l.//

i denne del af opgaven oprettes der to ssh forbindelser fra de to separatåbnede terminaler til devkitet i den ene startes udevadm monitor og fra den anden terminal indsættes vores kernemodul vi kan ud fra udskriften på terminalvinduet hvorfra vi har åbnet udevadm monitor se at der er oprettet en mappe kaldet mygpio ligeledes ses det under dev/ at mygpio objektet er registreret og at denne har fået tildelt de forudefinerede minor/major numre nedenfor kan udskreften fra terminalen med udevadm ses.

code KERNEL[233.531550] add     /module/mygpio_basic (module) UDEV [233.538844] add      /module/mygpio_basic (module) KERNEL[233.544459] add     /class/myGpio (class) UDEV [233.551357] add      /class/myGpio (class) KERNEL[233.556240] add     /devices/virtual/myGpio/mygpio (myGpio) UDEV [233.571255] add      /devices/virtual/myGpio/mygpio (myGpio) 2000 Jan 1 00:03:50 beagleboard [  233.632476] Mygpio Module Inserte code

vi kan også finde mappen ved at bruge ls -l under /sys/class

neden under ses udskriften i terminalen for /dev/


 * e)** //Ændr driveren til at bruge dynamisk allokering af major numre. Ændr linien med "register_chr_dev_region" til://

Ændr driveren til at bruge dynamisk allokering af major numre. Ændr linien med "register_chr_dev_region" til følgende linje ændres code if((err=register_chrdev_region(devno,gpio_len, "myGpio"))<0){ code til code if((err=alloc_chrdev_region(&devno, 0, gpio_len, "myGpio"))<0){ code

de fårtagede ændring gør at mygpio får tildelt tilfældige numre. nedenfor ses outputtet på terminalen. code crw---  1  root     root      233       0 Jan  1 00:03 myGpio code

code static ssize_t gpio_value_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t gpio_value_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size);
 * f)** //Opret en attribute med tilhørende show/store metoder. Show metoden skal udelukkende lave en printk("hello from show"), den anden venter vi lidt med... Benyt nedenstående metoder.//
 * Global**

struct device_attribute mygpio_attr = __ATTR(name, 0777, gpio_value_show, gpio_value_store); code code device_create_file(mygpio_device, &mygpio_attr); code code device_remove_file(mygpio_device, &mygpio_attr); code
 * Init**
 * Exit**


 * g)** //Gør som i (e), men udtag dog først det gamle modul. bemærk at der er kommet en folder med forskellige attributter, incl den netop oprettede. Lav en cat på attributten og check i dmesg om du får en "hello from show".//

det gamle modul udtages med rmmod hvorefter at det nye modul indsættes med insmod. hvorefter vi kører en cat vores atribute fil /sys/class/mygpio/mygpio/output og en dmesg. hvorefter voresder fremkommer "//hello from show//".

vi tilføjer følgende kode code int gpio_no = 138;
 * h)** //Et hvert device kan gemme private data i driveren. Til dette benyttes drvdata som er en void pointer i "device_create" metoden. Show/store metoderne har hverisær en device pointer, således at man ved med hvilket device de er kaldt. Vha device pointeren kan de private data udtrækkes vha "dev_get_data" metoden. Opret en int gpio_no = 138 i init og tilføj referencen til denne som parameteren drvdata i "device_create". modificér nu din "show" metode til vise denne værdi, hertil benyttes metoden://

// init c_d = device_create(mygpio_class, NULL, devno, &gpio_no, "mygpio");

// gpio_value_show int *pVal = dev_get_drvdata(dev); printk("device gpio no: %d\n", *pVal); code

når der køres en cat fås //"Hello from show device gpio no: 138"// følgende kode indsættes code static ssize_t gpio_value_store(struct device *dev,       struct device_attribute *attr, const char *buf, size_t size) { int *num = dev_get_drvdata(dev); ssize_t ret = -EINVAL; char *after; unsigned long value = simple_strtoul(buf, &after, 10); size_t count = after - buf; if (isspace(*after)) count++;
 * i)** //Udfyld "store" metoden med indholdet vist og verificer at du nu kan sætte gpio porten både vha write til devicet oprettet under /dev/ samt ved at skrive til attributten.//

printk("using Store to set gpio #%i to %i\n", *num, (int)value); gpio_set_value(*num, value); return count; } code //når vi skriver til filen ved hjælp af write til vores device fås samme output som// ved at skrive til attributten. code [ 112.003784] using Store to set gpio #138 to 1 code

//der tilføjes en regl under// "/etc/udev/rules.d" for at give modulet et andet navn. code KERNEL=="mygpio", NAME="nyt_gpio" code dette giver gpio devicet navnet nyt_gpio
 * J)** //Evt. prøv at oprette en regel under /etc/udev/rules.d som giver gpio device't et andet navn.//