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
14 aoˆ ut 2021
1 / 18
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 / 18
Electronique´ num´erique
J.-M Friedt
Protocoles de communication
Protocole parall` ele :
• un bit/fil : gourmand en ressources mat´ erielles (bus parall` eles)
• couplage entre signaux adjacents ` a haut d´ ebit ⇒ isolation (paires diff´ erentielles dans LVDS, masse entre les signaux dans SCSI)
Cam´era drone DJI
Protocoles s´ erie : bits transmis s´ equentiellement sur 1 ou 2 fil(s).
Asynchrone v.s synchrone :
• asynchrone : pas de partage d’horloge (historiquement, sur ligne t´ el´ ephonique)
• synchrone : partage d’horloge ⇒ d´ ebit plus ´ elev´ e
3 / 18
num´erique
J.-M Friedt
Protocole asynchrone (RS232) 1
• Pas d’horloge commune ⇒ cadencement des donn´ ees par convention (baudrate)
• D´ ebut : repos (1) → start bit (0)
• N bits de donn´ ees, N ∈ {7, 8}, LSB first
• bit de parit´ e optionnel (E, O, N)
• 1 ou 2 bit(s) de stop (1)
• Exercice : quel est le temps de transmission d’un octet ` a 115200 bauds en 8N1 ?
0 1T t
START
1 0 0 0
2T 3T 4T 5T 6T 7T 8T
lsb msb
9T
STOP
1 0 1 0
T=1000/baud ms
1. gtvhacker, Hack All The Things : 20 Devices in 45 Minutes, DEF CON 22 (2014)
`
a https://www.youtube.com/watch?v=h5PRvBpLuJs
4 / 18
Electronique´ num´erique
J.-M Friedt
Analyse de trame RS232
Que dit ce message ?
5 / 18
num´erique
J.-M Friedt
Analyse de trame RS232
1 identifier le baudrate (symbole le plus court)
2 ne pas oublier start (“s”) et stop (“S”) bit
3 resynchronisation sur front descendant du start bit
4 ´ eventuellement parit´ e et 2 stop bits (pas ici)
6 / 18
Electronique´ num´erique
J.-M Friedt
Protocoles synchrones (I 2 C, SPI)
Acc` es mat´ eriel : degr´ es de libert´ e
• ´ etat au repos de l’horloge, front d’´ echantillonnage : impos´ e dans I 2 C, libre dans SPI (CPHA, CPOL)
• ordre des bits : I 2 C : MSB first 6= SPI : LSB ou MSB first
• esclave SPI s´ electionne par CS#, I 2 C par l’adresse du destinataire impos´ ee par le mat´ eriel.
Exemple du XE1203F 2 : protocole s’apparentant au SPI 1 0 R/W# A4-A0 D7-D0
2. https://datasheet.digchip.com/531/531-00053-0-XE1203.pdf
7 / 18
num´erique
J.-M Friedt
Exemple SPI
XE1203F sur SPI2 3 (PB12 .. PB15), gestion manuelle de CS#
#i n c l u d e<l i b o p e n c m 3 / stm32 / s p i . h>
s t a t i c v o i d c l o c k s e t u p (v o i d)
{r c c c l o c k s e t u p i n h s e 8 m h z o u t 7 2 m h z ( ) ; // STM32F103 r c c p e r i p h c l o c k e n a b l e ( RCC GPIOB ) ; // S P I 2 = PORTB r c c p e r i p h c l o c k e n a b l e ( RCC AFIO ) ;
r c c p e r i p h c l o c k e n a b l e ( RCC SPI2 ) ; }
s t a t i c v o i d s p i s e t u p (v o i d){// SS=PB12 , SCK=PB13 , MISO=PB14 and MOSI=PB15∗/
g p i o s e t m o d e ( GPIOB , GPIO MODE OUTPUT 50 MHZ , GPIO CNF OUTPUT ALTFN PUSHPULL , GPIO13|GPIO15 ) ; g p i o s e t m o d e ( GPIOB , GPIO MODE OUTPUT 2 MHZ , GPIO CNF OUTPUT PUSHPULL , GPIO12 ) ;
g p i o s e t m o d e ( GPIOB , GPIO MODE INPUT , GPIO CNF INPUT FLOAT , GPIO14 ) ; s p i r e s e t ( S P I 2 ) ;
s p i i n i t m a s t e r ( SPI2 , SPI CR1 BAUDRATE FPCLK DIV 128 , SPI CR1 CPOL CLK TO 0 WHEN IDLE , SPI CR1 CPHA CLK TRANSITION 2 , SPI CR1 DFF 8BIT , SPI CR1 MSBFIRST ) ; s p i e n a b l e ( S P I 2 ) ;
}
i n t s p i t x r x (c h a r c ) {s p i s e n d ( SPI2 , c ) ;
r e t u r n( s p i r e a d ( S P I 2 ) ) ; // a l w a y s r e a d a f t e r w r i t e t o a v o i d a v e r f l o w }
i n t main ( ) {[ . . . ]
g p i o c l e a r ( GPIOB , GPIO12 ) ;
s p i t x r x ( 0 x 8 0 +( a d d r &0 x 1 f ) ) ; // w r i t e#
s p i t x r x ( 0 x 5 5 ) ; s p i t x r x ( 0 x f f ) ; g p i o s e t ( GPIOB , GPIO12 ) ; }
3. RM0008 ` a https://www.st.com/resource/en/reference_manual/
cd00171190-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.
Electronique´ num´erique J.-M Friedt
Ecriture ´ Lecture
9 / 18
num´erique
J.-M Friedt
Initialisation du port asynchrone
sur STM32
https://www.st.com/resource/
en/datasheet/stm32f410cb.pdf 1 activer l’horloge du
p´ eriph´ erique
2 configurer les broches dans leur fonction alternative
3 configurer le p´ eriph´ erique (8N1, 115200 bauds)
#i n c l u d e<l i b o p e n c m 3 / stm32 / g p i o . h>
#i n c l u d e<l i b o p e n c m 3 / stm32 / u s a r t . h>
r c c p e r i p h c l o c k e n a b l e ( RCC USART1 ) ;
g p i o m o d e s e t u p ( GPIOA , GPIO MODE AF , GPIO PUPD NONE , GPIO9 ) ; //TX g p i o m o d e s e t u p ( GPIOA , GPIO MODE AF , GPIO PUPD NONE , GPIO10 ) ; //RX g p i o s e t a f ( GPIOA , GPIO AF7 , GPIO9 ) ;
g p i o s e t a f ( GPIOA , GPIO AF7 , GPIO10 ) ; u s a r t s e t b a u d r a t e ( USART1 , 1 1 5 2 0 0 ) ; u s a r t s e t d a t a b i t s ( USART1 , 8 ) ;
u s a r t s e t s t o p b i t s ( USART1 , USART STOPBITS 1 ) ; u s a r t s e t m o d e ( USART1 , USART MODE TX RX ) ; u s a r t s e t p a r i t y ( USART1 , USART PARITY NONE ) ;
u s a r t s e t f l o w c o n t r o l ( USART1 , USART FLOWCONTROL NONE) ; u s a r t e n a b l e ( USART1 ) ;
https://www.st.com/resource/en/reference_manual/dm00180366.pdf section 24
10 / 18Electronique´ num´erique
J.-M Friedt
Initialisation du port sychrone sur
STM32
https://www.st.com/resource/
en/datasheet/stm32f410cb.pdf 1 activer l’horloge du
p´ eriph´ erique
2 configurer les broches dans leur fonction alternative
3 d´ ebit de communication (communication synchrone) 4 ´ etat au repos de l’horloge et
front d’´ echantillonnage des donn´ ees
#i n c l u d e<l i b o p e n c m 3 / stm32 / g p i o . h>
#i n c l u d e<l i b o p e n c m 3 / stm32 / s p i . h>
r c c p e r i p h c l o c k e n a b l e ( RCC SPI1 ) ;
g p i o m o d e s e t u p ( GPIOA , GPIO MODE AF , GPIO PUPD PULLUP , GPIO5|GPIO6|GPIO7 ) ; g p i o s e t a f ( GPIOA , GPIO AF5 , GPIO5|GPIO6|GPIO7 ) ; // A5=SCK 6=MISO 7=MOSI s p i d i s a b l e ( S P I 1 ) ;
s p i i n i t m a s t e r ( SPI1 ,
SPI CR1 BAUDRATE FPCLK DIV 256 , SPI CR1 CPOL CLK TO 1 WHEN IDLE , // c l k =1 when i d l e SPI CR1 CPHA CLK TRANSITION 1 , // f a l l i n g e d g e =>T r a n s i t i o n 1
SPI CR1 DFF 8BIT , // 8 b i t s
SPI CR1 MSBFIRST ) ; // MSB f i r s t
s p i e n a b l e s o f t w a r e s l a v e m a n a g e m e n t ( S P I 1 ) ; s p i s e t n s s h i g h ( S P I 1 ) ;
s p i e n a b l e ( S P I 1 ) ;
https://www.st.com/resource/en/reference_manual/dm00180366.pdf section 25
11 / 18num´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 ) ;}}
12 / 18
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 grand nombre de plateformes, simavr pour Atmega32U2
1 us + 0A
xx FF FD FC FB DB
Time
STACKH[7:0]=0A STACKL[7:0]=xxPr´ 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 };
13 / 18
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)
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
// c f l i b o p e n c m 3 : 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 ( ) {
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
14 / 18
Electronique´ 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]=440,188 ms
10 ms 20 ms
xx 46 39 44 38 30
Time
UDR1[7:0]=391,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)
15 / 18num´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
16 / 18
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 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
17 / 18
num´erique
J.-M Friedt
Exercice
1 Configurer le port de communication SPI
2 Envoyer des messages sur le bus SPI
3 Observer ` a l’oscilloscope les trames sur MOSI apr` es avoir identif´ e la broche du connecteur correspondant
4 Sont-elles coh´ erentes avec le signal CK en fonction des param` etres du bus SPI ? (CPHA, CPOL)
5 Observer les trames sur bus RS232 et v´ erifier la coh´ erence avec les messages transims
6 Ecrire dans un registre ´ du XE1203 (SPI2) et en relire la valeur pour v´ erifier qu’elle a ´ et´ e stock´ ee
(Penser ` a r´ einitialiser le microcontrˆ oleur ` a la main apr` es l’avoir flash´ e)
{c}SENSeOR2011 U$1
HMC470LP3
U1
R1
R2 R3
C1 C2
C3
C4 C6 C5
C7 C8 C11
Q3
C15 L2 C16
C17C18 C19
C20
C21
C22
L3L4
C25
L5
L6 C26 C27
L7 R5 C28C29
C30
U$4
U$5 RESET
R8C33
C34
C36 DLOAD
C10
C12 C13
D1 R4
R6
IC4
C39 X4
C9C14C23C24 C31C32C35C37
C38 Q4 Q5 Q_32K_SMD
R7
Xe1203
IC5
X2
Q1 R9
AD694
R10
X1 C40
TLV
R11
R12
R16 R17
ADM809
R13
R14R15
D2
L1 STM32F10XRXT6 5600
5600NC
13p 13p
13p 13p
100n
100n100n 100n100n
39MHz
5.6p22n 47p
4.7p 22p 6.8p
1p
68p
1u
22n22n
6.8p
33n 33n
1.5p
1.5p 100n 1.2k3.3n 220p
1p
SAW3.3
SAW3.3 RESET
0
100n
47u
NC
100p
100p 100p
1k 1K
FT232RL
100n
MINI-USB-SHIELD-UX60-MB-5ST 1.5p1.5p1.5p1.5p1.5p1.5p 1.5p 1.5p 100n
Q_8MHZ_SMD 5600
2n2222 5600
100n
5K
15k
4k7 10k
15k
NCNC
BB141
SCLK MOSI
MISO CS#
UART1
18 / 18