• Aucun résultat trouvé

´Electronique num´erique

N/A
N/A
Protected

Academic year: 2022

Partager "´Electronique num´erique"

Copied!
25
0
0

Texte intégral

(1)

Electronique´ num´erique J.-M Friedt

Electronique num´ ´ erique

J.-M Friedt

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

transparents ` a jmfriedt.free.fr

22 novembre 2020

1 / 25

(2)

num´erique

J.-M Friedt

Plan des interventions :

7 cours/TP d’introduction au STM32 en C baremetal :

1 Electronique num´ ´ erique et conception du circuit

L3 : aspects analogiques, consommation ´ electrique, lecture de datasheet Survol des divers p´ eriph´ eriques qui seront abord´ es (RS232, SPI, timer, ADC) repr´ esentation des donn´ ees (tailles/encodage), masques, architecture

Rappels sur Atmega32U4 (Makefile, compilation, masques ...)

2 Premiers pas sur le STM32, adresses des p´ eriph´ eriques, architecture

3 Fonctionnement de gcc et optimisations :

pr´ eprocess–compilateur–assembleur–linker, passage C ` a assembleur, pointeurs 4 biblioth` eques et s´ eparation algorithme/mat´ eriel, simulateurs

libopencm3, newlib & stubs, ressources requises par les biblioth` eques 5 Bus de communication s´ erie, synchrone/asynchrone

6 arithm´ etique sur syst` emes embarqu´ es

entiers, flottants, convertir un algorithme exprim´ e en nombres ` a virgules vers des entiers, timers

7 interruptions et acquisition de donn´ ees analogiques, fr´ equence d’´ echantillonnage

vecteurs d’interruption, gestion des horloges du STM32, ADC

2 / 25

(3)

Electronique´ num´erique

J.-M Friedt

Compiler son compilateur

Une chaˆıne de compilation n´ ecessite

1 le compilateur (gcc)

2 les outils pour convertir les divers formats de fichiers (binutils)

3 les biblioth` eques (newlib)

+ debugger (gdb) + outils de programmation du microcontrˆ oleur (avrdude, stm32flash, dfu-programmer ...)

configure --target=arm-none-eabi --prefix= $ {HOME}/sat

Automatiser ce processus dans un script pour g´ en´ erer un ensemble

“coh´ erent” d’outils 1 .

1. explication de son utilisation ` a http://jmfriedt.free.fr/summon_arm.pdf

3 / 25

(4)

num´erique

J.-M Friedt

newlib

Implication de la biblioth` eque de calculs flottants :

toujours en thumb :

sans stdio, avec une division flottante 12950 sans stdio, avec atan sur flottant 17090 avec stdio, avec une division flottante 80397 avec stdio, avec atan sur flottant 80397

Thumb est un sous-ensemble d’instructions pour processeur ARM cod´ e sur 16 bits au lieu de 32 bits

2

Diverses impl´ ementations libres des biblioth` eques standard du C :

• glibc (http://www.gnu.org/software/libc/, utilis´ ee par le noyau Linux) ...

• ... et eglibc (embedded glibc, http://www.eglibc.org/home) ont fusionn´ e,

• uClibc (http://www.uclibc.org/, utilis´ ee par uClinux),

2. J.-M Friedt, ´ E. Carry, D´ eveloppement sur processeur ` a base de cœur ARM7 sous GNU/Linux, GNU/Linux Magazine France 117 (Juin 2009), pp.40-59

4 / 25

(5)

Electronique´ num´erique

J.-M Friedt

Le probl` eme ...

Dans un programme en C, l’appel ` a malloc() se traduit par une erreur

`

a l’´ edition de liens

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-sbrkr.o): In function ‘_sbrk_r’:

newlib/libc/reent/sbrkr.c:58: undefined reference to ‘_sbrk’

Idem pour printf()

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-sbrkr.o): In function ‘_sbrk_r’:

newlib/libc/reent/sbrkr.c:58: undefined reference to ‘_sbrk’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-writer.o): In function ‘_write_r’:

newlib/libc/reent/writer.c:58: undefined reference to ‘_write’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-closer.o): In function ‘_close_r’:

newlib/libc/reent/closer.c:53: undefined reference to ‘_close’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-fstatr.o): In function ‘_fstat_r’:

newlib/libc/reent/fstatr.c:62: undefined reference to ‘_fstat’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-isattyr.o): In function ‘_isatty_r’:

newlib/libc/reent/isattyr.c:58: undefined reference to ‘_isatty’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-lseekr.o): In function ‘_lseek_r’:

newlib/libc/reent/lseekr.c:58: undefined reference to ‘_lseek’

arm-none-eabi/lib/thumb/cortex-m3/libc.a(lib_a-readr.o): In function ‘_read_r’:

newlib/libc/reent/readr.c:58: undefined reference to ‘_read’

5 / 25

(6)

num´erique

J.-M Friedt

Exploitation d’une biblioth` eque –

newlib

https://sourceware.org/newlib/libc.html#Stubs : 17 stubs, colle entre newlib et nos programmes 3 .

• exit : quitter un programme sans fermer les fichiers ouverts

• environ :

• execve :

• fork :

• fstat :

• getpid :

• isatty :

• kill :

• link :

• lseek :

• open :

• read : lire depuis un fichier

• sbrk : utilis´ e par malloc

• stat :

• times :

• unlink :

• wait :

• write : ´ ecrire dans un fichier, incluant stdout

3. http://wiki.osdev.org/Porting_Newlib

6 / 25

(7)

Electronique´ num´erique

J.-M Friedt

Exploitation d’une biblioth` eque –

newlib

Exemple d’impl´ ementation (envoyer stdio sur port s´ erie)

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

p = (u n s i g n e d c h a r∗) p t r ; f o r ( i = 0 ; i<l e n ; i ++)

{w h i l e ( g l o b a l i n d e x == 0 ){}// ! u a r t 0 k b h i t ( ) ) ; c = g l o b a l t a b [ 0 ] ; g l o b a l i n d e x =0; // ( c h a r ) u a r t 0 g e t c ( ) ; i f ( c == 0x0D ) {∗p=’ \0 ’;b r e a k;}

∗p++ = c ; j m f p u t c h a r ( c , NULL , 0 , 0 ) ; }

r e t u r n l e n−i ; }

s s i z e t w r i t e r ( s t r u c t r e e n t ∗r , i n t f i l e , c o n s t v o i d∗p t r , s i z e t l e n ) {i n t i ; c o n s t u n s i g n e d c h a r ∗p ;

p = (c o n s t u n s i g n e d c h a r∗) p t r ; f o r ( i = 0 ; i<l e n ; i ++)

{i f (∗p ==’ \ n ’ ) j m f p u t c h a r (’ \ r ’, NULL , 0 , 0 ) ; j m f p u t c h a r (∗p++,NULL , 0 , 0 ) ;

} r e t u r n l e n ; }

v o i d j m f p u t c h a r (i n t a ,c h a r∗c h a i n e , i n t∗c h a i n e i n d e x ,i n t USARTx )

{ i f ( c h a i n e != NULL ){c h a i n e [∗c h a i n e i n d e x ]= a ;∗c h a i n e i n d e x =∗c h a i n e i n d e x +1;}

e l s e {i f ( u s a r t p o r t ==1)

{USART SendData ( USART1 , a ) ;

w h i l e( U S A R T G e t F l a g S t a t u s ( USART1 , USART FLAG TC ) == RESET ){; } }

e l s e

{USART SendData ( USART2 , a ) ;

w h i l e( U S A R T G e t F l a g S t a t u s ( USART2 , USART FLAG TC ) == RESET ){; } }

}

} 7 / 25

(8)

num´erique

J.-M Friedt

D´ emonstration

#i f d e f u s e s t d i o

f o r ( tempe =1; tempe <10; tempe++) { mf=mf ∗ l f ;}

p r i n t f (" \ n + mf =% d \ n " , ( i n t ) mf ) ;

t =( c h a r ∗ ) m a l l o c ( 2 0 0 ) ; // m a l l o c r e q u i e r t s b r k p r i n t f (" ^% x \ n ^% x \ n " , ( i n t ) t [ 0 ] , t [ 1 9 9 ] ) ;

memset ( t , 0 x55 , 2 0 0 ) ;

p r i n t f (" ^% x \ n ^% x \ n " , ( i n t ) t [ 0 ] , t [ 1 9 9 ] ) ;

#e n d i f w h i l e ( 1 ) {

#i f n d e f u s e s t d i o p u t c h a r s ( welcome ) ;

#e l s e

p r i n t f (" % s " , welcome ) ;

#e n d i f

i f ( i <10) p u t c h a r ( USART1 , i +’ 0 ’ ) ;

e l s e p u t c h a r ( USART1 , i +’ A ’ − 10) ; i ++; i f ( i ==16) i =0;

. . .

8 / 25

(9)

Electronique´ num´erique

J.-M Friedt

D´ emonstration

Compromis entre temps de d´ eveloppement, fonctionnalit´ es et occupation de ressources

3240 main.bin 31824 main_stdio.bin

Ici, affichage par printf(), allocation de m´ emoire par malloc(), calculs flottants

Un ´ emulateur pour tester ses programmes en l’absence du mat´ eriel : https://github.com/beckus/qemu_stm32

qemu-system-arm -M stm32-p103 -serial stdio -serial stdio -kernel main.bin suppose n´ eanmoins une impl´ ementation “correcte” des p´ eriph´ eriques.

simavr pour Atmega32U2

9 / 25

(10)

num´erique

J.-M Friedt

Stubs

• Un programme principal contient toute l’“intelligence” du code : algorithmique

• Ce programme fait exclusivement appel ` a des fonctions g´ en´ eriques ind´ ependantes du mat´ eriel : stubs

• L’acc` es de ces fonctions au mat´ eriel est impl´ ement´ e dans des fichiers s´ epar´ es

• Algorithmique est li´ e aux appels mat´ eriel par le compilation (compilation s´ epar´ ee)

• Possibilit´ e de passer des arguments par Makefile : variables et tests conditionnels

• Edition de lien g´ ´ en` ere un ex´ ecutable

algorithmique led_on() led_off() communique()

matériel1

GP3DAT |= 0x00070000;

GP3DAT |&= (~0x00070000);

COMTX = a;

matériel2, bibliothèque2 gpio_set (GPIOA, GPIO4);

gpio_clear(GPIOA, GPIO4);

usart_send_blocking (USART1,a)

#include makefile.cortex_AD9958

#include makefile.cortex_XE1203 include makefile.aduc MODBUS = 0

ifeq ($(MODBUS),1) endif

...

matériel2, bibliothèque1

GPIO_SetBits(GPIOC,GPIO_Pin_2);

GPIO_ResetBits(GPIOC,GPIO_Pin_1);

USART_SendData (USART1, a);

Makefile

Edition de liens −> exécutable

→ remplacement “ais´ e” de la plateforme mat´ erielle sans modifier l’algorithme (HAL)

→ “fausses fonctions” sur PC pour ´ emuler les appels : test unitaire

10 / 25

(11)

Electronique´ num´erique

J.-M Friedt

HAL : Hardware Abstraction Layer HAL

Android

ST Microelectronics development fra- mework

https://source.android.com/devices/architecture

https://www.st.com/en/embedded-software/x-cube-spn14.html

11 / 25

(12)

num´erique

J.-M Friedt

Conception de logiciels

1 S´ eparer le code li´ e au mat´ eriel (initialisation et acc` es aux ressources mat´ erielles) de l’algorithmique

2 Compilation s´ epar´ ee : choisir une impl´ ementation du mat´ eriel ou une

´

emulation logicielle (gcc supporte une multitude de plateformes)

3 Permet de tester son code sur PC avant de le porter au

microcontrˆ oleur (simulation de diverses conditions mat´ erielles) – test automatique, en particulier de cas pathologiques

4 Exploitation d’un simulateur pour connaˆıtre l’´ etat interne de la machine qui s´ equence le code

5 qemu pour grand nombre de plateformes, simavr pour Atmega32U2

unsigned short interroge (unsigned short puissance, unsigned int freq,unsigned int offset,unsigned char chan) { unsigned int v12;

FTW0[1] = (freq & 0xFF000000) >> 24;

FTW0[2] = (freq & 0xFF0000) >> 16;

FTW0[3] = (freq & 0xFF00) >> 8;

FTW0[4] = (freq & 0xFF);

[...]

v12 = readADC12 ();

readerF2_CLR; // coupe reception

TIM_ITConfig (TIM3, TIM_IT_Update, ENABLE);

return (v&0x03F);

}

12 / 25

(13)

Electronique´ num´erique

J.-M Friedt

Conception de logiciels

1 S´ eparer le code li´ e au mat´ eriel (initialisation et acc` es aux ressources mat´ erielles) de l’algorithmique

2 Compilation s´ epar´ ee : choisir une impl´ ementation du mat´ eriel ou une

´

emulation logicielle (gcc supporte une multitude de plateformes)

3 Permet de tester son code sur PC avant de le porter au

microcontrˆ oleur (simulation de diverses conditions mat´ erielles) – test automatique, en particulier de cas pathologiques

4 Exploitation d’un simulateur pour connaˆıtre l’´ etat interne de la machine qui s´ equence le code

5 qemu pour un grand nombre de plateformes, simavr pour Atmega32U2

unsigned short interroge(unsigned short puissance,unsigned int freq, \

__attribute__((unused))unsigned int offset,__attribute__((unused))unsigned char chan) {float reponse;

reponse =exp(-(((float)freq-f01)/df)*(((float)freq-f01)/df))*3100.;

reponse+=exp(-(((float)freq-f02)/df)*(((float)freq-f02)/df))*3100.;

reponse+=(float)((rand()-RAND_MAX/2)/bruit); // ajout du bruit;

if (reponse<0.) reponse=0.;

if (reponse>4095.) reponse=4095.;

usleep(60);

return((unsigned short)reponse);

}

13 / 25

(14)

num´erique

J.-M Friedt

Cas des interruptions

Version PC

v o i d h a n d l e a l a r m (i n t x x x )

{// p r i n t f ( ”RTC : %d %d %d\n ” , s e c o n d e ,→

,→m i n u t e , h e u r e ) ; t i m 0 +=10;

s e c o n d e +=10;

i f ( s e c o n d e>600){m i n u t e ++; s e c o n d e =0;}

i f ( m i n u t e>60){h e u r e ++; m i n u t e =0;}

a l a r m ( 1 ) ; }

v o i d h a n d l e i o (i n t x x x ) {// i o h a p p e n e d =1;

g l o b a l t a b [ g l o b a l i n d e x ] = g e t c h a r ( ) ; i f ( g l o b a l i n d e x<( NB CHARS−1 ) )

g l o b a l i n d e x ++;

}

i n t main ( ){

s i g n a l ( SIGALRM , h a n d l e a l a r m ) ; i o h a p p e n e d =0;

s t r u c t t e r m i o s b u f ; t c g e t a t t r ( 0 , &b u f ) ;

b u f . c l f l a g &= ˜ (ECHO| ICANON ) ; b u f . c c c [ VMIN ] = 1 ;

b u f . c c c [ VTIME ] = 0 ;

t c s e t a t t r ( 0 , TCSAFLUSH , &b u f ) ; s i g n a l ( SIGIO , h a n d l e i o ) ;

i n t s a v e d f l a g s= f c n t l ( 0 , F GETFL , 0 ) ; f c n t l ( 0 , F SETFL , s a v e d f l a g s |O ASYNC| →

,→O NONBLOCK ) ; f c n t l ( 0 , F SETOWN , g e t p i d ( ) ) ;

a l a r m ( 1 ) ; // s i on v e u t s i m u l e r l e t i m e o u t }

Version microcontroleur

v o i d t i m 3 i s r (v o i d) // VERSION LIBOPENCM3 {

i f ( T I M G e t I T S t a t u s ( TIM3 , T I M I T U p d a t e ) !=→

,→RESET )

{T I M C l e a r I T P e n d i n g B i t ( TIM3 , T I M I T U p d a t e ) ; t i m 0 ++;

s e c o n d e ++; // s e c o n d e en 1/10→ ,→s e c o n d e

i f ( s e c o n d e>6 0 0 ) {s e c o n d e = 0 ; m i n u t e++;}

i f ( m i n u t e>6 0 ) {m i n u t e = 0 ; h e u r e ++;}

i f ( h e u r e>2 4 ) {h e u r e = 0;}

} }

v o i d u s a r t 1 i s r (v o i d) {

i f( U S A R T G e t I T S t a t u s ( USART1 , USART IT RXNE→

,→) )

{U S A R T C l e a r I T P e n d i n g B i t ( USART1 ,→

,→USART IT RXNE ) ;

U S A R T C l e a r F l a g ( USART1 , USART IT RXNE ) ; {

g l o b a l t a b [ g l o b a l i n d e x ]=→

,→USART ReceiveData ( USART1 ) ; i f ( g l o b a l i n d e x<(NB CHARS−1) ) →

,→g l o b a l i n d e x ++;

} } }

14 / 25

(15)

Electronique´ num´erique

J.-M Friedt

Profiter des outils d’analyse

valgrind pour ´ etudier les fuites de m´ emoire

i n t main ( ) { c h a r ∗ c ;

c =(c h a r ∗ ) m a l l o c ( 1 0 0 ) ; }

est analys´ e par

valgrind --leak-check=full ./programme pour indiquer que

==20235== HEAP SUMMARY:

==20235== in use at exit: 100 bytes in 1 blocks

==20235== total heap usage: 1 allocs, 0 frees, 100 bytes allocated

==20235==

==20235== 100 bytes in 1 blocks are definitely lost in loss record 1 of 1

==20235== at 0x483577F: malloc (vg_replace_malloc.c:309)

==20235== by 0x109146: main (in ...)

==20235==

==20235== LEAK SUMMARY:

==20235== definitely lost: 100 bytes in 1 blocks

valgrind a d´ etect´ e que le tas n’est pas vide en fin d’ex´ ecution

15 / 25

(16)

num´erique

J.-M Friedt

Profiter des outils d’analyse

valgrind pour ´ etudier les acc` es ill´ egaux de m´ emoire

i n t main ( ) { c h a r ∗ c ;

c =(c h a r ∗ ) m a l l o c ( 1 0 0 ) ; c [ 1 0 0 ] = 1 0 ;

f r e e ( c ) ; }

est analys´ e par

valgrind -q ./programme pour indiquer que

==21801== Invalid write of size 1

==21801== at 0x109163: main (in ...)

==21801== Address 0x4a490a4 is 0 bytes after a block of size 100 alloc’d

==21801== at 0x483577F: malloc (vg_replace_malloc.c:309)

==21801== by 0x109156: main (in ...) Etrangement, alors que ´

char *c; c=(char*)malloc(100); c[100]=10; free(c);

et

static char c[100]; c[100]=10;

assignent tous deux c sur le tas, seule la premi` ere erreur d’allocation est d´ etect´ ee par valgrind.

16 / 25

(17)

Electronique´ num´erique

J.-M Friedt

Profiter des outils d’analyse

valgrind pour ´ etudier acc` es ` a une zone m´ emoire non-allou´ ee (moins ´ evident ` a analyser sur la pile : corruption du compteur de programme au retour de la fonction printf())

i n t main ( ) { i n t i [ 3 ] , k ;

f o r ( k =0; k <10; k++) { i [ k ]= k ; p r i n t f ( " % d " , i [ k ] ) ; } }

qui s’ex´ ecute pour donner Segmentation fault ...

... est analys´ e par valgrind -q ./mon programme et donne

==22408== Jump to the invalid address stated on the next line

==22408== at 0x700000006: ???

==22408== by 0x900000007: ???

==22408== by 0x48ACBBA: (below main) (libc-start.c:308)

==22408== Address 0x700000006 is not stack’d, malloc’d or (recently) free’d

==22408==

==22408==

==22408== Process terminating with default action of signal 11 (SIGSEGV)

==22408== Access not within mapped region at address 0x700000006

==22408== at 0x700000006: ???

==22408== by 0x900000007: ???

==22408== by 0x48ACBBA: (below main) (libc-start.c:308)

17 / 25

(18)

num´erique

J.-M Friedt

Profiter des outils d’analyse

gprof pour ´ etudier le temps d’ex´ ecution de chaque fonction

v o i d f o n c t i o n 1 s ( )

{ v o l a t i l e i n t k ; f o r ( k =0; k<0x 1 0 0 0 0 0 0 ; k++) { } ;}

v o i d f o n c t i o n 2 s ( )

{ v o l a t i l e i n t k ; f o r ( k =0; k<0x 2 0 0 0 0 0 0 ; k++) { } ;}

v o i d f o n c t i o n 3 s ( )

{ v o l a t i l e i n t k ; f o r ( k =0; k<0x 3 0 0 0 0 0 0 ; k++) { } ;}

i n t main ( ) { f o n c t i o n 1 s ( ) ;

f o n c t i o n 2 s ( ) ; f o n c t i o n 3 s ( ) ; }

qui se compile avec l’option -pg pour g´ en´ erer ` a l’ex´ ecution gmon.out ...

... qui s’analyse par gprof -bp ./mon programme et donne

% cumulative self self total

time seconds seconds calls ms/call ms/call name 55.56 0.10 0.10 1 100.00 100.00 fonction3s

33.33 0.16 0.06 1 60.00 60.00 fonction2s

11.11 0.18 0.02 1 20.00 20.00 fonction1s

18 / 25

(19)

Electronique´ num´erique

J.-M Friedt

Simulateur

1 Exploitation d’un simulateur pour connaˆıtre l’´ etat interne de la machine qui s´ equence le code

2 qemu pour un grand nombre de plateformes, simavr pour Atmega32U2

Capture d’´ ecran de gtkwave utilis´ e pour afficher l’´ evolution du port C.

Pr´ efixer son programme des d´ eclarations de simulations :

#i n c l u d e " a v r _ m c u _ s e c t i o n . h "

AVR MCU( F CPU , " a t m e g a 3 2 ") ;

c o n s t s t r u c t a v r m m c u v c d t r a c e t m y t r a c e [ ] MMCU ={

{AVR MCU VCD SYMBOL(" P O R T B ") , . what = (v o i d∗)&PORTB, }, };

i n t main{DDRB|=1<<PORTB5 ; w h i l e ( 1 ){PORTBˆ=1<<PORTB5 ; d e l a y m s ( 1 0 0 0 ) ;}}

19 / 25

(20)

num´erique

J.-M Friedt

Simulateur

1 Exploitation d’un simulateur pour connaˆıtre l’´ etat interne de la machine qui s´ equence le code

2 qemu pour grand nombre de plateformes, simavr pour Atmega32U2

1 us + 0A

xx FF FD FC FB DB

Time

STACKH[7:0]=0A STACKL[7:0]=xx

Pr´ efixer son programme des d´ eclarations de simulations :

#i n c l u d e " a v r _ m c u _ s e c t i o n . h "

AVR MCU( F CPU , " a t m e g a 3 2 ") ;

c o n s t s t r u c t a v r m m c u v c d t r a c e t m y t r a c e [ ] MMCU ={

{AVR MCU VCD SYMBOL(" P O R T C ") , . what = (v o i d∗) ( 0 x 2 8 ) , }, // &PORTC

{AVR MCU VCD SYMBOL(" S T A C K L ") , . what = (v o i d∗) ( 0 x5D ) , }, // s t a c k =0x3{DE}+0x 2 0 {AVR MCU VCD SYMBOL(" S T A C K H ") , . what = (v o i d∗) ( 0 x5E ) , }, // s t a c k =0x3{DE}+0x 2 0 };

20 / 25

(21)

Electronique´ num´erique

J.-M Friedt

Emulation des p´ ´ eriph´ eriques

Un ´ emulateur simule le comportement du cœur du processeur, mais comment ´ emuler les p´ eriph´ eriques 4 ?

Exemple du convertisseur analogique-num´ erique du STM32 :

s t a t i c v o i d s t m 3 2 a d c s t a r t c o n v ( Stm32Adc∗s )

{u i n t 6 4 t c u r r t i m e = q e m u c l o c k g e t n s ( QEMU CLOCK VIRTUAL ) ; i n t c h a n n e l n u m b e r=s t m 3 2 A D C g e t c h a n n e l n u m b e r ( s , 1 ) ; i f ( c h a n n e l n u m b e r ==16)

{s−>Vdda=r a n d ( ) %(1200+1) + 2 4 0 0 ; // Vdda b e l o n g s t o t h e i n t e r v a l [ 2 4 0 0 3 6 0 0 ] mv

s−>V r e f=r a n d ( ) %(s−>Vdda−2400+1) + 2 4 0 0 ; // V r e f b e l o n g s t o t h e i n t e r v a l [ 2 4 0 0 Vdda ] mv

s−>ADC DR= s−>Vdda−s−>V r e f ; }

e l s e i f ( c h a n n e l n u m b e r ==17) i

{s−>ADC DR= ( s−>V r e f=r a n d ( ) %(s−>Vdda−2400+1) + 2 4 0 0 ) ; // V r e f [ 2 4 0 0 Vdda ] mv }

e l s e

{s−>ADC DR=((i n t) ( 1 0 2 4 .∗( s i n (2∗M PI∗q e m u c l o c k g e t n s ( QEMU CLOCK VIRTUAL ) /1 e 9 ) + 1 . ) ) &0 x f f f→

,→) ; }

s−>ADC SR&=˜ADC SR EOC ; // i n d i c a t e s o n g o i n g c o n v e r s i o n s−>ADC CR2&=˜ADC CR2 SWSTART ;

// c a l l s c o n v c o m p l e t e when e x p i r e s

t i m e r m o d ( s−>c o n v t i m e r , c u r r t i m e + s t m 3 2 A D C g e t n b r c y c l e p e r s a m p l e ( s , c h a n n e l n u m b e r ) ) ; }

4. https://github.com/beckus/qemu stm32/blob/stm32/hw/arm/stm32 adc.c#L700

21 / 25

(22)

num´erique

J.-M Friedt

Communication RS232 5 (32U4)

#i n c l u d e " a v r _ m c u _ s e c t i o n . h "

AVR MCU( F CPU , " a t m e g a 3 2 ") ;

AVR MCU VCD FILE (" t r a c e _ f i l e . vcd ", 1 0 0 0 ) ;

c o n s t s t r u c t a v r m m c u v c d t r a c e t m y t r a c e [ ] MMCU ={ {AVR MCU VCD SYMBOL(" U D R 1 ") , . what = (v o i d∗)&UDR1 , }, };

pour d´ eclarer le registre observ´ e (UDR1), puis

#d e f i n e UART BAUDRATE ( 5 7 6 0 0 ) //#d e f i n e UART BAUDRATE ( 9 6 0 0 ) v o i d i n i t u a r t (v o i d) {u n s i g n e d s h o r t baud ;

UCSR1A = (1<<UDRE1) ; // i m p o r t a n t l y U2X1 = 0

UCSR1B = ( 1<<RXEN1 )|( 1<<TXEN1) ; // e n a b l e r e c e i v e r and t r a n s m i t t e r

UCSR1C = (1<<UCSZ11 )|(1<<UCSZ10 ) ; // 8N1 // UCSR1D = 0 ; // no r t c / c t s baud = ( ( ( ( F CPU / ( UART BAUDRATE∗16UL ) ) )−1 ) ) ;

UBRR1H = (u n s i g n e d c h a r) ( baud>>8);

UBRR1L = (u n s i g n e d c h a r) baud ; }

v o i d u a r t t r a n s m i t (u n s i g n e d c h a r d a t a )

{w h i l e ( ! ( UCSR1A & (1<<UDRE1) ) ) ; // w a i t w h i l e r e g i s t e r i s f r e e

UDR1 = d a t a ; // l o a d d a t a i n t h e r e g i s t e r

}

v o i d s e n d b y t e (u n s i g n e d c h a r c ) {u n s i g n e d c h a r tmp ;

tmp=c>>4; i f ( tmp<10) u a r t t r a n s m i t ( tmp+’ 0 ’) ; e l s e u a r t t r a n s m i t ( tmp+’ A ’−10) ; tmp=( c&0 x 0 f ) ; i f ( tmp<10) u a r t t r a n s m i t ( tmp+’ 0 ’) ; e l s e u a r t t r a n s m i t ( tmp+’ A ’−10) ; }

13 ms

xx 46 39 44 38 30

Time

UDR1[7:0]=44

0,188 ms

10 ms 20 ms

xx 46 39 44 38 30

Time

UDR1[7:0]=39

1,234 ms

5. J.-M Friedt, D´ evelopper sur microcontrˆ oleur sans microcontrˆ oleur : les

´

emulateurs, GNU/Linux Magazine France HS 103 (Juillet-Aout 2019)

22 / 25

(23)

Electronique´ num´erique

J.-M Friedt

Nouvelle architecture : RISC V

#i n c l u d e<s t d i o . h>

i n t main ( ) {l o n g x=0x 1 2 3 4 5 6 7 8 ;

c h a r ∗c =(c h a r∗)&x ;

p r i n t f (" \ n % d \ n ",s i z e o f(l o n g) ) ;

p r i n t f (" % hhx % hhx % hhx % hhx \ n ", c [ 0 ] , c [ 1 ] , c [ 2 ] , c [ 3 ] ) ; }

Rappel : newlib n´ ecessite le stub write() pour afficher

FEMTO=[...]/riscv-probe/

riscv64-unknown-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medany -c h.c riscv64-unknown-elf-gcc -march=rv32imac -mabi=ilp32 -mcmodel=medany \

-nostartfiles -nostdlib -nostdinc -static -lgcc \ -T $(FEMTO)/env/qemu-sifive_e/default.lds \

$(FEMTO)/build/obj/rv32imac/env/qemu-sifive_e/crt.o \

$(FEMTO)/build/obj/rv32imac/env/qemu-sifive_e/setup.o h.o \

$(FEMTO)/build/lib/rv32imac/libfemto.a -o hello32

s’ex´ ecute dans qemu par

$ [...]/riscv-qemu/riscv32-softmmu/qemu-system-riscv32 -M sifive_e \ -nographic -kernel hello32

4

00000078 00000056 00000034 00000012

→ long est cod´ e sur cette architecture 32 bits sur 4 octets

→ 0x78 apparaˆıt en premier, l’octet de poids faible est ` a l’adresse la plus faible : little endian

23 / 25

(24)

num´erique

J.-M Friedt

Nouvelle architecture : RISC V

#i n c l u d e<s t d i o . h>

i n t main ( ) {l o n g x=0x 1 2 3 4 5 6 7 8 ;

c h a r ∗c =(c h a r∗)&x ;

p r i n t f (" \ n % d \ n ",s i z e o f(l o n g) ) ;

p r i n t f (" % hhx % hhx % hhx % hhx \ n ", c [ 0 ] , c [ 1 ] , c [ 2 ] , c [ 3 ] ) ; }

Rappel : newlib n´ ecessite le stub write() pour afficher En compilant en 64 bits par (options -march= et -mabi) :

riscv64-unknown-elf-gcc -march=rv64imac -mabi=lp64 -mcmodel=medany -c h.c riscv64-unknown-elf-gcc -march=rv64imac -mabi=lp64 -mcmodel=medany \

-nostartfiles -nostdlib -nostdinc -static -lgcc \ -T $(FEMTO)/env/qemu-sifive_e/default.lds \

$(FEMTO)/build/obj/rv64imac/env/qemu-sifive_e/crt.o \

$(FEMTO)/build/obj/rv64imac/env/qemu-sifive_e/setup.o h.o

$(FEMTO)/build/lib/rv64imac/libfemto.a -o hello64

nous obtenons sous la version 64 bits de qemu le r´ esultat

$ [...]/riscv-qemu/riscv64-softmmu/qemu-system-riscv64 -M sifive_e \ -nographic -kernel hello64

8

00000078 00000056 00000034 00000012

→ long occupe 8 octets (64 bits)

→ toujours little endian

24 / 25

(25)

Electronique´ num´erique

J.-M Friedt

Cette s´ eparation permet d’utiliser Conclusion

• outils de profilage et d’analyse de code (lint, valgrind ...)

• outils de test unitaire (cunit)

• un nouveau processeur avec le mˆ eme algorithme de traitement Unique convertisseur analogique- num´ erique : 1×12-bit ` a 2,4 MSPS

v o i d i n i t a d c (v o i d)

{g p i o m o d e s e t u p ( GPIOB , GPIO MODE ANALOG , → ,→GPIO PUPD NONE , GPIO0|GPIO1 ) ; a d c p o w e r o f f (ADC1) ;

a d c d i s a b l e s c a n m o d e (ADC1) ;

// ADCCLOCK<30 MHz, f r o m APB2 =>p r e s c a l e → ,→t q APB2/DIV<30 MHz

a d c s e t c l k p r e s c a l e ( ADC CCR ADCPRE BY4 ) ; a d c s e t s a m p l e t i m e o n a l l c h a n n e l s ( ADC1 , →

,→ADC SMPR SMP 112CYC ) ;

// s i ADCCLOCK = 21 MHz, s a m p l e t i m e = 144 =>→ ,→Tconv = 7 . 4 2 8 6 u s .

a d c p o w e r o n (ADC1) ; }

u n s i g n e d s h o r t r e a d a d c (u n s i g n e d c h a r → ,→c h a n n e l )

{u i n t 8 t c h a n n e l a r r a y [ 1 6 ] ; c h a n n e l a r r a y [ 0 ] = c h a n n e l ; a d c s e t r e g u l a r s e q u e n c e ( ADC1 , 1 ,→

,→c h a n n e l a r r a y ) ; // u s e d c h a n n e l a d c s t a r t c o n v e r s i o n r e g u l a r (ADC1) ; w h i l e ( ! a d c e o c (ADC1) ) ;

r e t u r n( a d c r e a d r e g u l a r (ADC1) ) ; }

25 / 25

Références

Documents relatifs

• Le gestionnaire d’interruption (ISR) doit ˆ etre le plus court possible car aucune autre interruption ne peut survenir pendant ISR. • Bien penser ` a laisser le microprocesseur

• Analyser la datasheet pour comprendre le lien entre mat´ eriel (p´ eriph´ eriques tels que GPIO, timer, USART, WDT ...) et logiciel (adresses des registres).. • gcc (GNU

Liste des registres dans la datasheet du microcontrˆ oleur (STM32F4) ⇒ utilisation des masques pour d´ efinir un bit individuel. Extraits de datasheets

2 En gardant le mˆ eme programme principal, proposer une architecture de programme qui permette d’ex´ ecuter ce mˆ eme programme sur STM32. 3 Proposer deux Makefile qui automatisent

• virgule flottante simple pr´ ecision float et double pr´ ecision double Utiliser le type pr´ esentant le meilleur compromis espace/pr´ ecision des donn´ ees (analyse

6 N´ ecessit´ e de connaˆıtre la fr´ equence d’´ echantillonnage f e pour tout traitement num´ erique du signal (axe des fr´ equences normalis´ e par f e /2). Exercice :

Nous fournissons un squelette de programme qui ne contient que des fonctions ind´ ependantes du mat´ eriel : ce pro- gramme se charge d’acqu´ erir des donn´ ees d’un

La capture d’´ ecran de droite propose une ex´ ecution de ce code dans l’´ emulateur de ZXSpectrum (aussi sur un Z80, mais avec une carte m´ emoire un peu diff´ erente de la