embarqu´es 4 J.-M Friedt
Syst` emes embarqu´ es 4
J.-M Friedt
FEMTO-ST/d´ epartement temps-fr´ equence jmfriedt@femto-st.fr
transparents ` a jmfriedt.free.fr
5 septembre 2020
embarqu´es 4
J.-M Friedt
Interfaces de communication
• Le noyau acc` ede au mat´ eriel et garantit l’int´ egrit´ e des acc` es
• L’espace utilisateur (plusieurs processus) acc` ede aux ressources au travers des requˆ etes au noyau
• Interface “classique” : /dev o` u “tout” est fichier
1• Interface uniforme en terme de p´ eriph´ erique repr´ esent´ e :
/sys/class (PWM, IIO, ...) et /sys/bus (PCI, USB, SPI ...) : pas de nouvel IOCTL pour chaque p´ eriph´ erique de la mˆ eme classe
• communication par chaˆınes ASCII
• contient ` a la fois les canaux de donn´ ees (ex-read/write) et de configuration (ex-ioctl)
1. cependant, chaque ioctl etait unique `a chaque p´eriph´erique, donc 2 DACs devaient ˆetre reprogramm´es selon les ioctl sp´ecifiques
2 / 11
embarqu´es 4
J.-M Friedt
Plateforme/pilote
• des pilotes sont charg´ es en m´ emoire et sont associ´ es ` a certains p´ eriph´ eriques (VID :PID en USB, nom en SPI)
• les pilotes sont appel´ es par une plateforme, potentiellement plusieurs fois, avec la configuration mat´ erielle acquise lors du boot ou de l’insertion du p´ eriph´ erique,
• ⇒ appels ´ ev` enementiels aux pilotes
• platform est le p´ eriph´ erique g´ en´ erique : /sys/devices/platform
embarqu´es 4
J.-M Friedt
Plateforme
• cr´ e´ ee en fonction de la description du p´ eriph´ erique : pour une plateforme g´ en´ erique (/sys/bus/platform/devices/simple*)
s t a t i c s t r u c t p l a t f o r m d r i v e r g p i o s i m p l e d r i v e r = { . p r o b e = g p i o s i m p l e p r o b e ,
. r e m o v e = g p i o s i m p l e r e m o v e , . d r i v e r = { . name = " s i m p l e ", },
};
alors que pour une interface SPI
s t a t i c s t r u c t s p i d r i v e r a d 5 6 2 4 r d r i v e r = { . p r o b e = a d 5 6 2 4 r p r o b e ,
. r e m o v e = a d 5 6 2 4 r r e m o v e , . d r i v e r = { . name = " a d 5 6 2 4 r ",
. o w n e r = THIS MODULE , },
. i d t a b l e = a d 5 6 2 4 r i d , };
⇒ d´ efinition des fonctions appel´ ees lors du chargement (probe) et d´ echargement (remove)
4 / 11
embarqu´es 4
J.-M Friedt
Plateforme
Enregistrement de la plateforme aupr` es du noyau :
s t a t i c s t r u c t p l a t f o r m d e v i c e ∗p d e v ; s t a t i c i n t i n i t g p i o s i m p l e i n i t (v o i d)
{r e t = p l a t f o r m d r i v e r r e g i s t e r (& g p i o s i m p l e d r i v e r ) ; p d e v= p l a t f o r m d e v i c e r e g i s t e r s i m p l e (" s i m p l e ", 0 , NULL , 0 ) ; }
s t a t i c v o i d e x i t g p i o s i m p l e e x i t (v o i d) {p l a t f o r m d e v i c e u n r e g i s t e r ( p d e v ) ;
p l a t f o r m d r i v e r u n r e g i s t e r (& g p i o s i m p l e d r i v e r ) ; }
m o d u l e i n i t ( g p i o s i m p l e i n i t ) m o d u l e e x i t ( g p i o s i m p l e e x i t )
fait appel aux m´ ethodes probe (insmod) ou remove (rmmod)
⇒ cr´ eation de /sys/bus/platform/drivers/simple* et
/sys/bus/platform/devices/simple*
embarqu´es 4
J.-M Friedt
Communication avec le pilote
Exemple de d´ efinition des points d’entr´ ee de chaque instance du pilote :
s t a t i c DEVICE ATTR ( v a l u e 1 , 0 4 4 0 , show1 , NULL ) ; // show s t a t i c DEVICE ATTR ( v a l u e 2 , 0 4 4 0 , show2 , NULL ) ; // show s t a t i c DEVICE ATTR ( v a l u e 3 , 0 2 2 0 , NULL , r e a d 1 ) ; // s t o r e
se traduit par
# ls /sys/bus/platform/drivers/simple/simple.0/
driver driver_override modalias power subsystem uevent value1 value2 value3
dont les actions sont par exemple
i n t show1 (s t r u c t d e v i c e ∗dev , s t r u c t d e v i c e a t t r i b u t e \
∗a t t r , c h a r ∗b u f )
{ r e t u r n s p r i n t f ( b u f , " H e l l o W o r l d 1\ n ") ;}
Utilisation intensive des macros :
linux-headers.../include/linux/device.h indique
#d e f i n e DEVICE ATTR ( name , mode , show , s t o r e ) \
s t r u c t d e v i c e a t t r i b u t e d e v a t t r ## name = ATTR ( name , → ,→ mode , show , s t o r e )
⇒ cr´ eation de la variable dev attr value appel´ ee par
device create file(&pdev->dev, &dev attr value); (init) et device remove file(&pdev->dev, &dev attr value); (exit)
6 / 11
embarqu´es 4
J.-M Friedt
Plateforme v.s pilote
• Un module se charge par init et se d´ echarge par exit
• un seul module peut ˆ etre charg´ e ` a un instant donn´ e
insmod: ERROR: could not insert module xxx.ko: File exists
• un module ne peut pas recevoir de configuration au moment du chargement par le noyau
• un module peut charger une plateforme :
s t a t i c s t r u c t p l a t f o r m d e v i c e ∗pd1 ,∗pd2 ; s t a t i c i n t i n i t g p i o s i m p l e i n i t (v o i d)
{pd1= p l a t f o r m d e v i c e r e g i s t e r s i m p l e (" jmf ", 0 , NULL , 0 ) ; pd2= p l a t f o r m d e v i c e r e g i s t e r s i m p l e (" jmf ", 1 , NULL , 0 ) ; r e t u r n( 0 ) ;
}
• la plateforme d´ ecrit le mat´ eriel
embarqu´es 4
J.-M Friedt
Plateforme v.s pilote
• les pilotes se voient passer un argument
s t a t i c s t r u c t p l a t f o r m d r i v e r j m f d r i v e r = { . p r o b e = j m f p r o b e ,
. r e m o v e = j m f r m ,
. d r i v e r = {. name = " jmf ",}, };
s t a t i c i n t j m f r m (s t r u c t p l a t f o r m d e v i c e ∗p d e v ) {p r i n t k ( KERN ALERT " dr bye % d \ n ", pdev−>i d ) ;r e t u r n 0 ;}
s t a t i c i n t j m f p r o b e (s t r u c t p l a t f o r m d e v i c e ∗p d e v ) {p r i n t k ( KERN ALERT " dr lo % d \ n ", pdev−>i d ) ;r e t u r n 0 ;}
// $LINUX/ D o c u m e n t a t i o n / d r i v e r−m o d e l / p l a t f o r m . t x t // ∗ p l a t f o r m d e v i c e . i d . . . t h e d e v i c e i n s t a n c e // number , o r e l s e ”−1” t o i n d i c a t e t h e r e ’ s o n l y o n e .
s t a t i c i n t i n i t j m f i n i t (v o i d)
{p l a t f o r m d r i v e r r e g i s t e r (& j m f d r i v e r ) ;r e t u r n 0 ;}
•
[ 1238.117164] platform init # insmod pl [ 1240.112258] driver init # insmod dr [ 1240.112283] jmf hello 0[ 1240.112298] jmf hello 1
[ 1262.529881] jmf bye 0 # rmmod pl [ 1262.529914] jmf bye 1
[ 1262.529922] platform exit # rmmod dr 8 / 11
embarqu´es 4
J.-M Friedt
S´ eparation module/pilote
• un module charge plusieurs instances d’une plateforme (device)
s t a t i c s t r u c t p l a t f o r m d e v i c e ∗p1 , ∗p2 ; s t a t i c i n t i n i t g p i o s i m p l e i n i t (v o i d)
{p1= p l a t f o r m d e v i c e r e g i s t e r s i m p l e (" jmf ", 0 , NULL , 0 ) ; p2= p l a t f o r m d e v i c e r e g i s t e r s i m p l e (" jmf ", 1 , NULL , 0 ) ; . . .
• le driver ne contient que la d´ efinition du pilote : les m´ ethodes init et exit ne contiennent que platform driver register(); et platform driver unregister();
• ⇒ d´ efinition implicite des m´ ethodes init et exit du module par module platform driver(gpio simple driver); avec
s t a t i c s t r u c t p l a t f o r m d r i v e r g p i o s i m p l e d r i v e r = { . p r o b e = g p i o s i m p l e p r o b e ,
. r e m o v e = g p i o s i m p l e r e m o v e , . d r i v e r = {. name = " jmf ",},
};
m o d u l e p l a t f o r m d r i v e r ( g p i o s i m p l e d r i v e r ) ;
embarqu´es 4
J.-M Friedt
Protection des acc` es par mutex
Si par exemple la valeur renvoy´ ee par une lecture est celle transmise au cours d’une ´ ecriture : penser ` a prot´ eger lecture et ´ ecriture par un mutex.
#include <linux/mutex.h>
struct mutex mymutex;
mutex_init(&mymutex);
mutex_lock(&mymutex); // bloque ...
mutex_unlock(&mymutex); // debloque
10 / 11
embarqu´es 4
J.-M Friedt