microcontrollers, advanced advanced challenges with real-time systems january 30, 2012 jack ganssle
TRANSCRIPT
8051 186usec/MHz usec/MHz
int = 36 12int + 90 8int - 120 8int * 462 20int / 1344 40int for 132 44long = 624 64long + 540 32long - 546 32long * 1128 1068long / 4878 3420long for 642 44
8051 8051 186 186Min Max Min Max
usec/MHz usec/MHz usec/MHz usec/MHz
acos 3690 52632 5232 5238asin 4950 53550 5232 5238atan 12300 26214 48096 102388cos 4944 23748 69644 82092sin 5406 23616 38696 79444exp 2844 35046 6832 189240sqrt 13800 15990 58644 59396tan 7878 35820 120428 179028
8051 8051 186 186Min Max Min Max
usec/MHz usec/MHz usec/MHz usec/MHz
cos 4944 23748 69644 82092
Hart cos 7.3 digits 6660 6744 4160 4216Hart cos 5.2 digits 5586 5670 3180 3236Hart cos 3.2 digits 4548 4632 2204 2260
Hart 7.3 digit cos(x):
a=.9999999523 - .4999990534 * b**2 + .04166358 * b**4
- .001385370 * b**6 + .000023233 * b**8
Computer Approximations, by John Hart
A Commercial ProductMicro Digital’s GoFast: www.smxrtos.com
For NIOS-II processor at 24 MHz, times in microseconds:
double precision single precisionGoFast GCC GoFast GCC
cos 16.0 120.9 4.0 38.4acos 32.2 201.5 9.6 59.6pow 43.5 542.0 10.6 163.6
Note GoFast is fully reentrant.
Reentrancy Problems
A function is reentrant if:• If it uses all shared variables in an atomic way, • If it does not call non-reentrant functions• If it does not use the hardware in a non-atomic way
Shared Variable PerilsUsing statics or globals non-atomically
makes the code non-reentrant.
void function(int *data){
count=data*2; data=count;}
int count;
Shared Variable PerilsUsing statics or globals non-atomically
makes the code non-reentrant.
void function(int *data){
count=data*2; data=count;}
int count;static
The Danger of DIlong i;void do_something(void){ disable_interrupts(); i+=0x1234; enable_interrupts();}
long i;void do_something(void){ int key; key=disable_interrupts(); i+=0x1234; restore_interrupts(key);}
NO!
Better
Using a Handshake Flag
while (in_use); //wait till resource freein_use=TRUE; //set resource busyDo non-reentrant stuffin_use=FALSE; //set resource available
Bad Code! An interrupt between the first two statements may cause two sections of code to think they both have exclusive access to the shared resource.
TSET Substitute
loop: mov al,0 ; 0 means “in use”lock xchg al,variablecmp al,0je loop ; loop if in use
If al=0, we swapped 0 with zero; nothing changed but the code loops since someone else is using the resource.
If al=1, we put a 0 into the “in use” variable, marking the resource as busy. We fall out of the loop, now having control of the resource.
On some ARM processors, use LDREX/STREXOn some ARM processors, use LDREX/STREX
Calling non-reentrant Routines
Calling a non-reentrant function makes thecaller non-reentrant.
Be wary of runtime packages, and purchasedcode.
Non-atomic Hardware Accesses
If you can’t manage a hardware resource atomically, then the code is non-reentrant.
/* swap peripheral modes*/peripheral_reg_1=0xaa;peripheral_reg_2=0x55;peripheral_reg_2=0x22;
Async Hardware/Software
High 16 bitsHigh 16 bits Low 16 bitsLow 16 bits
ISRISR
Hardware timer registerVariabletimer_hi
Overflow of timer register++timer_hi
Async Hardware/Softwareint timer_hi;interrupt timer(){ ++timer_hi;}
long timer_read(void){ unsigned int low, high; low =inword(hardware_register); high=timer_hi; return (((ulong)high<<16) + (ulong)low);}
Bad code! See next slide….
Async Hardware/Softwarelong timer_read(void){ unsigned int low, high;(hardware_register=ffff, timer_hi=0000) low =inword(hardware_register);(overflow; low=ffff, timer_hi=0001) high=timer_hi; return (((ulong)high<<16) + (ulong)low);(returns 0001ffff)}
Bad code! As you can see, an interrupt may corrupt the result.
long timer_read(void){ unsigned int low, high; push_interrupt_state; disable_interrupts; low=inword(hardware_register); high=timer_hi; if(timer_overflow) {++high; low=inword(hardware_register);} pop_interrupt_state; return (((ulong)high)<<16 + (ulong)low);}
Input Capture Register
RegisterRegister To CPU
Bits 0-15
Bits 16-31
Data hold
Metastable design! Will surely fail
32 bitcounter32 bit
counter
clock
Speed Kills
Required reading: High Speed Digital Design (a Handbook of Black Magic) by Howard Johnson and Martin Graham (1993 PTR Prentice Hall, NJ)
Power Spectrum
Tr = signal’s rise timeF = All frequencies higher than F are 40 dBV down in amplitude
If Tr = 20 nsec, F= 25 MHzIf Tr = 1 nsec, F= 500 MHz
Common Impedance Problems• ALE
• Edge sensitive interrupts (e.g., NMI)
• All signals going off-board
• Clock - particular problem as it goes all over the typical board. Few CPUs accept TTL clock signals; many won’t tolerate anything less than a perfect clock.
ResourcesAn Embedded Software Primer by David E. Simon
1999, Addison Wesley LongmanISBN 0-201-61569-X
MicroC/OS-II by Jean J. LaBrosse1999, Miller FreemanISBN 0-87930-543-6
http://embedded.com/design/205203908 - Great multicore articleMicroC/OS-III by Jean J. LaBrosse - MicroC/OS-IIIhttp://www.ecoscentric.com - ecos