• Aucun résultat trouvé

Informatique embarqu´ee 14/16

N/A
N/A
Protected

Academic year: 2022

Partager "Informatique embarqu´ee 14/16"

Copied!
17
0
0

Texte intégral

(1)

embarqu´ee 14/16 J.-M Friedt

Informatique embarqu´ ee 14/16

J.-M Friedt

FEMTO-ST/d´epartement temps-fr´equence jmfriedt@femto-st.fr

transparents `ajmfriedt.free.fr

20 mars 2018

1 / 17

(2)

embarqu´ee 14/16

J.-M Friedt

Acc` es m´ emoire par le noyau

• Liste des ressources occup´ees

# cat /proc/iomem ...

01c20800-01c20bff : /soc@01c00000/pinctrl@01c20800

• Requˆete de ressource par un pilote

#d e f i n e PWM BASE 0 x 0 1 c 2 0 c 0 0

i n t h e l l o s t a r t ( ) // i n i t m o d u l e ( v o i d )

{s t a=r e q u e s t m e m r e g i o n (PWM BASE, 1 2 ," PWM t e s t ") ; i f ( s t a==NULL )

p r i n t k ( KERN ALERT " mem r e q u e s t f a i l e d ") ; e l s e

{j m f g p i o = ( u32 ) i o r e m a p (PWM BASE, 1 2 ) ;

w r i t e l ((1< <4) , (v o i d) ( j m f g p i o ) ) ; // 24000/120=200 kHz w r i t e l ((100< <16) +50 ,(v o i d∗) ( j m f g p i o +4) ) ;

} r e t u r n 0 ; }

# cat /proc/iomem

01c20800-01c20bff : /soc@01c00000/pinctrl@01c20800 ...

01c20c00-01c20c0b : PWM test

(3)

embarqu´ee 14/16

J.-M Friedt

Acc` es aux GPIO par le noyau :

gpiolib

Configuration du noyau Linux pour int´egrergpiolib

CONFIG_GPIO_ZYNQ:

Say yes here to support Xilinx Zynq GPIO controller.

Symbol: GPIO_ZYNQ [=y]

Type : tristate

Prompt: Xilinx Zynq GPIO support Location:

-> Device Drivers

-> GPIO Support (GPIOLIB [=y]) -> Memory mapped GPIO drivers Defined at drivers/gpio/Kconfig:514

Depends on: GPIOLIB [=y] && HAS_IOMEM [=y] && (ARCH_ZYNQ [=y] || \ ARCH_ZYNQMP)

Selects: GPIOLIB_IRQCHIP [=y]

Pour utiliser PS-MIO Redpitaya : 906+broche (comme en espace utilisateur)

3 / 17

(4)

embarqu´ee 14/16

J.-M Friedt

Acc` es aux GPIO par le noyau :

gpiolib

Le noyau fournit des m´ethodes pour acc´eder aux GPIO :

#i n c l u d e <l i n u x / g p i o . h>

i n t m y g p i o =906+7; // GPIO ID

g p i o i s v a l i d ( m y g p i o ) ;

g p i o r e q u e s t o n e ( m y g p i o , GPIOF OUT INIT LOW , " j m f _ g p i o ") ; g p i o s e t v a l u e ( m y g p i o , j m f s t a t ) ;

g p i o f r e e ( m y g p i o ) ;

1 V´erifier si le GPIO existe sur cette architecture (906+pin)

2 Requ´erir la broche (direction, ´etat par d´efaut)

3 Manipuler l’´etat de la broche

4 Relacher la ressource

MODULE LICENSE (" GPL ") ;

sinon

[ 525.704550] 4mymod_version_gpiolib: module license ’unspecified’ taints kern.

[ 525.711983] Disabling lock debugging due to kernel taint

[ 525.717944] 4mymod_version_gpiolib: Unknown symbol gpiod_set_raw_value (err ) [ 525.725256] 4mymod_version_gpiolib: Unknown symbol gpio_free (err 0) [ 525.731627] 4mymod_version_gpiolib: Unknown symbol gpio_request_one (err 0) [ 525.738610] 4mymod_version_gpiolib: Unknown symbol gpio_to_desc (err 0)

(5)

embarqu´ee 14/16

J.-M Friedt

Module noyau : gestion des

interruptions

Seul un module noyau peut acc´eder aux interruptions du processeur (exemple : interruption 7 est associ´ee `a la broche 10 du port parall`ele).

jmfriedt@(none):~$ cat /proc/interrupts | grep parp 7: 0 IO-APIC-edge parport0

qui se g`ere par1

#d e f i n e PARALLEL PORT INTERRUPT 7

#d e f i n e BASEPORT 0 x 3 7 8

i n t s =0;

s t a t i c i n t i n t h a n d l e r (v o i d){p r i n t k (" > > > P A R A L L E L P O R T INT \ n ") ; s =1;}

s t a t i c i n t i n i t j m f p p o r t i n i t m o d u l e (v o i d){ r e t = r e q u e s t i r q ( PARALLEL PORT INTERRUPT , &i n t h a n d l e r ,

SA INTERRUPT , " p a r a l l e l p o r t ", NULL ) ; e n a b l e i r q ( 7 ) ;

o u t b p ( 0 x10 , BASEPORT + 2 ) ; }

s t a t i c s s i z e t s k e l e t o n r e a d (s t r u c t f i l e ∗f i l e , c h a r∗b u f , s i z e t c o u n t , l o f f t ∗p p o s ){

[ . . . ]

do{}w h i l e ( s o r t i r ==0) ; // i n t e r r u p t i b l e s l e e p o n (& s k e l e t o n w a i t ) ; e r r = c o p y t o u s e r ( b u f , s t r i n g , c o u n t e r ) ;

. . . }

1. www.captain.at/howto-linux-device-driver-template-skeleton.php

5 / 17

(6)

embarqu´ee 14/16

J.-M Friedt

Interruptions et gpiolib

(Probl`eme d’incompatibilit´e avec Xenomai sur Repditaya pour le moment ...) m y g p i o =(’ B ’−’ A ’)32+2; // PB2

e r r= g p i o i s v a l i d ( m y g p i o ) ;

e r r=g p i o r e q u e s t o n e ( m y g p i o , GPIOF IN , " j m f _ i r q ") ; i r q = g p i o t o i r q ( m y g p i o ) ;

i r q s e t i r q t y p e ( i r q , IRQ TYPE EDGE BOTH ) ;

e r r = r e q u e s t i r q ( i r q , i r q h a n d l e r , IRQF SHARED , " G P I O jmf→

,→", &d e v i d ) ; . . .

f r e e i r q ( i r q ,& d e v i d ) ;

g p i o f r e e ( m y g p i o ) ; // l i b e r e GPIO

appellerairq handlerchaque fois que l’interruption se d´eclenche.

irq handlerfinit par return IRQ HANDLED;

[ 4446.692969] gpio_request 34=0 [ 4446.696059] gpio_to_irq=47 [ 4446.698827] finished IRQ: error=0

# cat /proc/interrupts ...

47: 1 sunxi_pio_edge 16 Edge GPIO jmf

(7)

embarqu´ee 14/16

J.-M Friedt

Les signaux : pr´ evenir d’un

´

ev` enement

Equivalent logiciel : les signaux´

#i n c l u d e <s i g n a l . h>

v o i d m y h a n d l e r (i n t s i g ) {

p r i n t f (" I got SIGINT , n u m b e r % d \ n ", s i g ) ;}

i n t main ( v o i d ) {

s i g n a l ( SIGINT , m y h a n d l e r ) ; w h i l e ( 1 ) {}

}

qui donne chaque fois qu’on appuie sur CTRL-C (tuer parkill -9 PID) jmfriedt@(none):~$ ./sigint

I got SIGINT, number 2 I got SIGINT, number 2

7 / 17

(8)

embarqu´ee 14/16

J.-M Friedt

Distribution du signal

d’interruption

Distribution d’interruption par signaux

1 un unique point de gestion d’une interruption mat´erielle (module noyau)

2 une multitude de processus utilisateurs r´eagissent `a l’interruption

3 chaque processus s’enregistre aupr`es du module

4 le module r´eagit au plus vite `a l’interruption ...

5 ... puis, quand il a le temps, pr´evient tous les processus identif´es par leur ID.

(9)

embarqu´ee 14/16

J.-M Friedt

G´ en´ eration du signal

Depuis le noyau : identifier le processus par son PID et envoyer le signal

s t r u c t s i g i n f o s i n f o ; s t r u c t t a s k s t r u c t∗t a s k ;

// on c h e r c h e PID au c a s ou ‘ l e p r o c e s s a u r a i t d i s p a r u memset(& s i n f o , 0 , s i z e o f(s t r u c t s i g i n f o ) ) ;

s i n f o . s i s i g n o = SIGUSR1 ; // d e p u i s s o n e n r e g i s t r e m e n t s i n f o . s i c o d e = SI USER ;

t a s k = p i d t a s k ( f i n d v p i d ( p i d ) , PIDTYPE PID ) ; i f ( t a s k == NULL ) {p r i n f o (" C a n n o t f i n d PID \ r \ n ") ;}

e l s e s e n d s i g i n f o ( SIGUSR1 , &s i n f o , t a s k ) ;

Processus potentiellement lent ⇒ex´ecuter dans une sous-tˆache

s t a t i c v o i d d o s o m e t h i n g (u n s i g n e d l o n g d a t a ) {. . . } i n t h e l l o s t a r t ( ) // i n i t m o d u l e ( v o i d )

{INIT WORK(& i r q w o r k , d o s o m e t h i n g ) ;

r e q u e s t i r q ( i r q , i r q h a n d l e r , IRQF SHARED , " G P I O jmf ", & i r q i d ) ; . . .

}

s t a t i c i r q r e t u r n t i r q h a n d l e r (i n t i r q , v o i d∗d e v i d )

{s c h e d u l e w o r k (& i r q w o r k ) ; // on l e f e r a quand on a u r a l e te m p s r e t u r n IRQ HANDLED ;

}

9 / 17

(10)

embarqu´ee 14/16

J.-M Friedt

Distribution du signal

d’interruption

Solution alternative (thread)

1 un processus d´esire ˆetre inform´e de l’interruption au cours de son ex´ecution

2 g´en`ere un thread qui bloque en lecture sur un point d’entr´ee de /sys/class ou/dev

3 quand l’interruption se d´eclenche, le module d´ebloque le processus en lecture ...2 3

4 ... et le thread pr´evient son p`ere de l’´ev`enement.

2. http://www.makelinux.net/ldd3/chp-6-sect-2

3. http://www.makelinux.net/ldd3/chp-5-sect-3pour les s´emaphores en espace noyau

(11)

embarqu´ee 14/16

J.-M Friedt

S´ emaphore

... pour d´ebloquer la lecture, ici sur un timer.

s t a t i c i n t d e v r e a d (s t r u c t f i l e f i l ,c h a r b u f f , s i z e t l e n ,→, l o f f t o f f )

{

down (&mysem ) ; . . .

r e t u r n l e n ; }

s t a t i c v o i d d o s o m e t h i n g (u n s i g n e d l o n g d a t a ) {up (&mysem ) ;}

i n t h e l l o s t a r t ( ) // i n i t m o d u l e ( v o i d )

{s e m a i n i t (&mysem , 1 ) ; / i n i t t h e s e m a p h o r e a s f u l l ∗/

// s i m u l e d e c l . i n t e r r u p t i o n p o u r d e b l o q u e r s e m a p h o r e i n i t t i m e r o n s t a c k (& e x p t i m e r ) ;

e x p t i m e r . e x p i r e s = j i f f i e s + d e l a y HZ ; e x p t i m e r . d a t a = 0 ;

e x p t i m e r . f u n c t i o n = d o s o m e t h i n g ; a d d t i m e r (& e x p t i m e r ) ;

r e t u r n t ; }

m o d u l e i n i t ( h e l l o s t a r t ) ;

11 / 17

(12)

embarqu´ee 14/16

J.-M Friedt

Protection des donn´ ees

Plusieurs tˆaches g`erent une mˆeme donn´ee⇒risque d’incoh´erence Trois m´ethodes pour prot´eger une donn´ee :

• s´emaphore (compteur)

• mutex (binaire avec passage en mode veille de la tˆache)

• spin-lock (binaire avec test du v´erou)

Producteur-consommateur :

1 une tˆache produit des donn´ees

2 un utilisateur demande ces donn´ees

3 la lecture estbloqu´eetant que les donn´ees n’ont pas ´et´e produites

tableau de donn´ees Production

(e.g. ADC)

Consommation

(e.g. affichage, traitement)

(13)

embarqu´ee 14/16

J.-M Friedt

Protection des donn´ ees :

s´ emaphore

• Abaisser le s´emaphore bloque s’il est nul

• Relever le s´emaphore d´ebloque le processus en attent

• Le compteur peut croˆıtre pour d´ebloquer plusieurs processus

#include <linux/semaphore.h>

struct semaphore mysem;

sema_init(&mysem, 0); // init the semaphore as empty down (&mysem); // bloque le consommateur

...

up (&mysem); // producteur debloque

13 / 17

(14)

embarqu´ee 14/16

J.-M Friedt

Protection des donn´ ees : mutex

Bloque-d´ebloque une zone de code qui acc`ede `a une ressource commune :

une seule instance d’un mutex peut acc´eder `a ce segment de code `a un instant donn´e

#include <linux/mutex.h>

struct mutex mymutex;

mutex_init(&mymutex);

mutex_lock(&mymutex); // bloque ...

mutex_unlock(&mymutex); // debloque

(15)

embarqu´ee 14/16

J.-M Friedt

Protection des donn´ ees : spinlock

Le mutex met la tˆache en veille ⇒proc´edure lourde et lente

Pour des op´erations rapides (interruptions), sonder continuellement le v´erou :spinlock

#include <linux/spinlock.h>

static DEFINE_SPINLOCK(myspin);

spin_lock_init(&myspin);

spin_lock(&myspin);

...

spin_unlock(&myspin);

MODULE_LICENSE("GPL");

Probl`eme dedeadlock: deux processus faisant appel `a un m´ecanisme de bloquage sont imbriqu´es.

15 / 17

(16)

embarqu´ee 14/16

J.-M Friedt

Protection des donn´ ees : spinlock

Le mutex met la tˆache en veille ⇒proc´edure lourde et lente

Pour des op´erations rapides (interruptions), sonder continuellement le v´erou :spinlock

#include <linux/spinlock.h>

static DEFINE_SPINLOCK(myspin);

spin_lock_init(&myspin);

spin_lock(&myspin);

...

spin_unlock(&myspin);

MODULE_LICENSE("GPL");

...

...

Consommateur Mutex prot`ege emaphore bloque Mutex lib`ere

Mutex prot`ege

Mutex lib`ere emaphore d´ebloque Producteur

Probl`eme dedeadlock: deux processus faisant appel `a un m´ecanisme de bloquage sont imbriqu´es.

(17)

embarqu´ee 14/16

J.-M Friedt

Mise en pratique

1 Mise en pratique degpiolibpour exploiter une broche

2 ... et s’en attribuer l’interruption mat´erielle (complexe `a la lecture de ladatasheet)

3 License GNU pour pouvoir exploiter les fonctionnalit´es d’autres modules noyau (abstraction du mat´eriel)

4 Exploitation des fonctionnalit´es du noyau pour ´echanger avec l’espace utilisateur : s´emaphore et tasklet/timer.

Exercices :

1 requ´erir une broche et la commander par gpiolib

2 faire clignoter cette broche sous contrˆole d’untimerdu noyau

3 clignoter la LED sur d´eclenchement de cette interruptionavec attenteavant de changer `a nouveau d’´etat (debounce)

17 / 17

Références

Documents relatifs

embarqu´ ee 2/16 J.-M Friedt

• synchrone est g´ en´ eralement plus rapide mais n´ ecessite un signal additionnel pour l’horloge (sauf codage Manchester – ethernet). • asynchrone n´ ecessite l’accord

Taille du fichier .hex intel 1 : avec stdio 80336 sans stdio 4048 sans stdio, avec une division flottante 12950 sans stdio, avec atan sur flottant 17090 avec stdio, avec une

• summon-arm-toolchain fournit un script pour g´ en´ erer un ensemble “coh´ erent” d’outils – explication de sa compilation ` a http://jmfriedt.free.fr/summon_arm.pdf. •

• thread : occupe les mˆ emes ressources m´ emoire que le p` ere mais contient sa propre pile ⇒ partage de ressources mais ´ elimine les probl` emes de communication entre

2 un ´ emulateur permet de connaˆıtre l’´ etat interne du processeur et de pr´ evenir l’utilisateur d’erreurs ...

• Pourquoi un syst` eme d’exploitation : un scheduler, un gestionnaire de m´ emoire (multitˆ ache), une couche d’abstraction suppos´ ee cacher le mat´ eriel au programmeur,

• m´ emoire mat´ erielle : une adresse sur le bus d’adresse pour identifier un p´ eriph´ erique. • chaque p´ eriph´ erique d´ ecode le bus d’adresse pour savoir si le