Microcontrollers, Advanced Advanced Challenges With Real-Time Systems January 30, 2012 Jack Ganssle.

30
Microcontrollers, Advanced Advanced Challenges With Real- Time Systems January 30, 2012 Jack Ganssle

Transcript of Microcontrollers, Advanced Advanced Challenges With Real-Time Systems January 30, 2012 Jack Ganssle.

Microcontrollers, Advanced Advanced Challenges With Real-Time Systems

January 30, 2012Jack Ganssle

Design for Speed

Keep ISRs Short!Avoid loopsRemove all unneeded code

Understand the cost of a LOC

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

Shared Variable Perils

Atomic operations may not be atomic.

int data;void function(){ ++data;}

Shared Variable Perils

mov cx,[bx]add cx,1mov [bx],cx

Atomic alternative:inc [bx]lock

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)

Speed is a function of the edges, not clock rate.

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

Bouncing in a 10 Inch wire

TP1 - driving signal

TP2 - after 10” of wire

Now Terminated

TP4

TP3

The Tek TPP1000 Probe

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

Questions?