Informatique Embarquée 3/12
Total Page:16
File Type:pdf, Size:1020Kb
Informatique embarqu´ee3/12 J.-M Friedt Informatique embarqu´ee3/12 J.-M Friedt FEMTO-ST/d´epartement temps-fr´equence [email protected] transparents `a jmfriedt.free.fr 24 janvier 2015 1 / 15 Informatique embarqu´ee3/12 J.-M Friedt Exploitation d'une biblioth`eque 1 dangers d'une biblioth`eque 2 utilit´ed'une biblioth`eque Les ressources additionnelles ne se justifient que sur microcontr^oleur haut de gamme (> 16 bits) Diverses impl´ementations libres des biblioth`equesstandard du C : • glibc (http://www.gnu.org/software/libc/, utilis´eepar le noyau Linux) ... • ... et eglibc (embedded glibc, http://www.eglibc.org/home) ont fusionn´e, • uClibc (http://www.uclibc.org/, utilis´eepar uClinux), • ... 2 / 15 Informatique embarqu´ee3/12 J.-M Friedt Exploitation d'une biblioth`eque{ newlib Newlib : impl´ementationde libc r´epondant `atoutes les exigences d'un OS ) complet, mais complexe et lourd L'utilisation de printf et du calcul flottant n'est pas `aprendre `ala l´eg`ere: avec stdio 80336 Taille du fichier .hex intel 1 : sans stdio 4048 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 1. J.-M Friedt, E.´ Carry, D´eveloppement sur processeur `abase de cœur ARM7 sous GNU/Linux, GNU/Linux Magazine France 117 (Juin 2009), pp.40-59 3 / 15 Informatique embarqu´ee3/12 J.-M Friedt Le probl`eme... Dans un programme en C, l'appel `a malloc() se traduit par une erreur `al'´editionde 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' 4 / 15 Informatique embarqu´ee3/12 J.-M Friedt Exploitation d'une biblioth`eque{ newlib https://sourceware.org/newlib/libc.html#Stubs : 17 stubs, colle entre newlib et nos programmes 2. • exit : quitter un programme • lseek : sans fermer les fichiers ouverts • open : • environ : • read : lire depuis un fichier • execve : • sbrk : utilis´epar malloc • fork : • stat : • fstat : • times : • getpid : • unlink : • isatty : • wait : • kill : • write : ´ecriredans un fichier, • link : incluant stdout 2. http://wiki.osdev.org/Porting_Newlib 5 / 15 Informatique embarqu´ee3/12 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 (struct r e e n t ∗r , int file, void ∗ptr , s i z e t l e n ) fc h a r c; int i; unsigned char ∗p ; p = (unsigned char ∗) p t r ; f o r (i=0; i < l e n ; i ++) fw h i l e ( global i n d e x == 0) fg //!uart0 k b h i t()); c = g l o b a l tab [0]; global i n d e x =0; //(char) uart0 g e t c(); i f (c == 0x0D) f∗p='\0' ;break; g ∗p++ = c ; j m f putchar(c,NULL,0 ,0) ; g r e t u r n len − i ; g s s i z e t w r i t e r ( struct r e e n t ∗r , int file, const void ∗ptr , s i z e t l e n ) f i n t i; const unsigned char ∗p ; p = (const unsigned char ∗) p t r ; f o r (i=0; i < l e n ; i ++) f 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 ) ; g r e t u r n len; g v o i d jmf p u t c h a r (int a,char ∗chaine , int ∗ c h a i n e i n d e x ,int USARTx) f i f (chaine != NULL) fc 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;g e l s e f i f (usart p o r t ==1) fUSART SendData (USART1, a); w h i l e(USART GetFlagStatus(USART1, USART FLAG TC) == RESET) f ; g g e l s e fUSART SendData (USART2, a); w h i l e(USART GetFlagStatus(USART2, USART FLAG TC) == RESET) f ; g g g g 6 / 15 Informatique embarqu´ee3/12 J.-M Friedt D´emonstration #ifdef use s t d i o f o r (tempe=1;tempe <10;tempe++) fmf=mf∗ l f ; g p r i n t f ( "\n+mf=%d\n" ,(int)mf); t =(char ∗)malloc(200); // malloc requiert s b r k p r i n t f ( "^%x\n^%x\n" ,(int)t[0],t[199]); memset(t ,0x55,200) ; p r i n t f ( "^%x\n^%x\n" ,(int)t[0],t[199]); #endif w h i l e (1) f #ifndef use s t d i o p u t chars(welcome); #else p r i n t f ( "%s" , welcome ) ; #endif i f (i <10) p u t c h a r (USART1 , i+'0' ); e l s e put c h a r (USART1 , i+'A' −10) ; i ++;if (i==16) i=0; ... 7 / 15 Informatique embarqu´ee3/12 J.-M Friedt D´emonstration Compromis entre temps de d´eveloppement, fonctionnalit´eset occupation de ressources 3240 main.bin 31824 main_stdio.bin Ici, affichage par printf(), allocation de m´emoirepar malloc(), calculs flottants Un ´emulateurpour 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´eanmoinsune impl´ementation\correcte" des p´eriph´eriques. 8 / 15 Informatique embarqu´ee3/12 J.-M Friedt M´ethodes de d´everminagede code embarqu´e 1 la partie algorithmique du code est portable et se compile sur PC ) bien s´eparer les parties algorithmiques et acc`esau mat´eriel + donne acc`esaux outils de profilage et anayse du PC 2 l'´emulateur(plus souple que le mat´eriel,et permet de sonder la machine `a´etatsqu'est le processeur) 3 sonde JTAG et gdb (si disponible) : ex´ecutionsur le \vrai" mat´eriel avec points d'arr^etet avance pas `apas. 9 / 15 Informatique embarqu´ee3/12 J.-M Friedt Compilation s´epar´eepour qualifier un logiciel • tester des conditions de fonctionnement impr´evuesou rarement accessibles exp´erimentalement • exploiter des outils de d´everminage (valgrind) ou de profilage • test unitaire Programme principal, biblioth`eque i n t main() f initialisation(); w h i l e (1) f interroge();traitements();g g Programme pour microcontr^oleur u n s i g n e d short interroge (unsigned int freq) f GPIO SetBits(GPIOB, GPIO Pin 1 ) ; v = readADC1 (ADC Channel 8 ) ; GPIO ResetBits (GPIOB,GPIO Pin 1 ) ; ... r e t u r n (v); g 10 / 15 Informatique embarqu´ee3/12 J.-M Friedt Compilation s´epar´eepour qualifier un logiciel • tester des conditions de fonctionnement impr´evuesou rarement accessibles exp´erimentalement • exploiter des outils de d´everminage (valgrind) ou de profilage • test unitaire Programme principale, biblioth`eque i n t main() f initialisation(); w h i l e (1) f interroge();traitements();g g Programme pour PC u n s i g n e d short interroge (unsigned int freq) reponse =exp(−(((float)freq −f 0 1 ) / d f ) ∗(((float)freq −f 0 1 ) / d f ) ) ∗3100.; reponse+=exp(−(((float)freq −f 0 2 ) / d f ) ∗(((float)freq −f 0 2 ) / d f ) ) ∗3100.; r e p o n s e+=(float)((rand() −RAND MAX/2)/bruit ); // ajout du bruit; i f (reponse <0.) reponse=0.; i f (reponse >4095.) reponse=4095.; usleep(60); r e t u r n((unsigned short)reponse); 11 / 15 Informatique embarqu´ee3/12 J.-M Friedt Cas des interruptions Version PC v o i d handle a l a r m (int xxx) Version microcontroleur f // printf("RTC:%d%d%d nn",seconde, ! v o i d tim3 i s r (void) // VERSION LIBOPENCM3 ,!minute,heure); f tim0 +=10; i f(TIM GetITStatus(TIM3, TIM IT Update ) !=! seconde+=10; ,!RESET) i f (seconde >600)fminute++;seconde=0;g fTIM ClearITPendingBit(TIM3,TIM IT Update ) ; i f (minute >60) fheure++;minute=0;g tim0++; alarm ( 1 ) ; seconde++; // seconde en 1/10 ! g ,!seconde i f (seconde > 600) v o i d handle i o (int xxx) fseconde = 0;minute++;g f // io h a p p e n e d=1; i f (minute > 60) g l o b a l t a b [ g l o b a l index] = getchar (); fminute = 0;heure++;g i f (global i n d e x < (NB CHARS − 1) ) i f (heure > 24) g l o b a l i n d e x ++; fh e u r e = 0;g g g g i n t main() f signal(SIGALRM, handle a l a r m ) ; v o i d usart1 i s r (void) f i o happened=0; i f(USART GetITStatus(USART1, USART IT RXNE! s t r u c t termios buf; ,!)) tcgetattr(0, &buf); fUSART ClearITPendingBit(USART1, ! buf .