182.694 Microcontroller VU Kyrill Winkler SS 2014 Featuring Today: - - PDF document

182 694 microcontroller vu
SMART_READER_LITE
LIVE PREVIEW

182.694 Microcontroller VU Kyrill Winkler SS 2014 Featuring Today: - - PDF document

182.694 Microcontroller VU Kyrill Winkler SS 2014 Featuring Today: Structured C Programming 136 Weekly Training Objective Already done 3.1.1 C demo program 3.1.3 Floating point operations 3.3.2 Interrupts 3.4.3 Generating periodic


slide-1
SLIDE 1

182.694 Microcontroller VU

Kyrill Winkler SS 2014

Featuring Today: Structured C Programming

136

Weekly Training Objective

◮ Already done

3.1.1 C demo program 3.1.3 Floating point operations 3.3.2 Interrupts 3.4.3 Generating periodic signals

◮ This week

3.3.1 Interrupt & callback demo 3.4.1 Input capture 3.6.1 UART receiver 3.6.2 UART sender 3.9.1 Keypad

◮ Next week

3.4.4 PWM signals and glitches 3.6.4 TWI (I2C) 3.8.2 Button debouncing 3.8.4 LCD

137

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

138

slide-2
SLIDE 2

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

It depends.

138

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

It depends. What data-type does z have? Lets assume it is int, then it has . . . bits!

138

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

It depends. What data-type does z have? Lets assume it is int, then it has 16 bits!

138

slide-3
SLIDE 3

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

It depends. What data-type does z have? Lets assume it is int, then it has 16 bits! So the snipplet negates the lower 8 bits of z.

138

Follow-up from last time: My dear compiler

int o = y + (z ^ 255);

What does (z ^ 255) do?

It depends. What data-type does z have? Lets assume it is int, then it has 16 bits! So the snipplet negates the lower 8 bits of z.

The size of int is varies across toolchains/architectures!

Therefore be explicit and use uint8 t or uint16 t etc.!

138

While on the topic of variable declarations. . .

bool timeout = f a l s e ; ISR (MY TIMER INTERRUPT , ISR NOBLOCK){ timeout = t r u e ; } i n t main ( void ) { i f ( timeout == t r u e ) { t u r n o n l e d s ( ) ; } }

139

slide-4
SLIDE 4

While on the topic of variable declarations. . .

bool timeout = f a l s e ; ISR (MY TIMER INTERRUPT , ISR NOBLOCK){ timeout = t r u e ; } i n t main ( void ) { i f ( timeout == t r u e ) { t u r n o n l e d s ( ) ; } }

On some versions of the toolchain the if-statement will be interpreted as always false!

139

The volatile keyword

bool v o l a t i l e timeout = f a l s e ; ISR (MY TIMER INTERRUPT , ISR NOBLOCK){ timeout = t r u e ; } i n t main ( void ) { i f ( timeout == t r u e ) { t u r n o n l e d s ( ) ; } }

volatile prevents the compiler from optimizing timeout, in particular it won’t assume that timeout is never changed.

140

The const keyword

◮ const is used to declare variables that are written to only once

(more on that later)

141

slide-5
SLIDE 5

The const keyword

◮ const is used to declare variables that are written to only once

(more on that later)

◮ C allows using pointers as output parameters

141

The const keyword

◮ const is used to declare variables that are written to only once

(more on that later)

◮ C allows using pointers as output parameters ◮ You should declare whether this is your intention or not:

myfunc(uint8 t *str) myfunc(const uint8 t *str).

141

Side effects

◮ Avoid side effects! Never use printf("%i", i++) etc.

142

slide-6
SLIDE 6

Side effects

◮ Avoid side effects! Never use printf("%i", i++) etc. ◮ Be aware of short-circuit evaluation:

if (a != 0 && myfunc(b) != 0)

142

Side effects

◮ Avoid side effects! Never use printf("%i", i++) etc. ◮ Be aware of short-circuit evaluation:

if (a != 0 && myfunc(b) != 0)

◮ Depending on value of a, myfunc(b) may or may not be

called!

142

Structured C Programming

2 important pradigms:

◮ background (BG) tasks vs. interrupt service routines (ISRs) ◮ callback functions

143

slide-7
SLIDE 7

Structured C Programming

2 important pradigms:

◮ background (BG) tasks vs. interrupt service routines (ISRs) ◮ callback functions

Helpful extensions (“-std=c99”)

◮ <util/atomic.h> ◮ <stdbool.h> ◮ useful macros for

interrupts, eeprom, sleepmode, crc, baudrate, watchdog, . . .

◮ detailed documentation: avr-libc manual

143

Backgrounding

Basic structure of a C-program:

i n t main ( void ){ i n i t ( ) ; // c a l l s i n i t i a l i z t i o n s

  • f

used modules for ( ; ; ) { background ( ) ; // c a l l s background t a s k s s l e e p ( ) ; } }

Every interrupt executes the background code once.

144

Backgrounding

Basic structure of a background task:

void background ( void ){ i f ( mystate == i n i t ){ b g t a s k p l a y I n t r o M u s i c ( ) ; bgtask showIntroAnimation ( ) ; } e l s e i f ( mystate == goal ){ . . . } }

145

slide-8
SLIDE 8

Backgrounding

Basic structure of a background task:

void background ( void ){ i f ( mystate == i n i t ){ b g t a s k p l a y I n t r o M u s i c ( ) ; bgtask showIntroAnimation ( ) ; } e l s e i f ( mystate == goal ){ . . . } }

Beware of monopolizing background tasks! Animation will be played after bgtask playIntroMusic returned.

145

Backgrounding

Implementing a basic scheduler:

void background ( void ){ while ( t h e r e i s s o m e t h i n g t o d o ( ) ){ i f ( mystate==i n i t ){ i f ( ! done music ) done music=b g t a s k p l a y I n t r o M u s i c ( ) ; i f ( ! done anim ) done anim=bgtask showIntroAnimation ( ) ; } e l s e i f ( mystate==goal ){ . . . } } }

146

Callback functions

147

slide-9
SLIDE 9

Callback functions

1 void (∗ myCallbackFunction )( u i n t 8 t ) ; // g l o b a l f u n c t i o n p o i n t e r v a r i a b l e 2 3 ISR (MY TIMER INTERRUPT , ISR NOBLOCK){ 4 /∗ execute the c a l l b a c k f u n c t i o n ∗/ 5 myCallbackFunction ( 1 ) ; 6 } 7 void s e t c a l l b a c k ( void (∗ c a l l b a c k )( u i n t 8 t )){ 8 myCallbackFunction = c a l l b a c k ; 9 } 10 void myfunc ( u i n t 8 t i ){ 11 . . . 12 } 13 14 i n t main ( void ){ 15 s e t c a l l b a c k ( myfunc ) ; // r e g i s t e r myfunc as c a l l b a c k f u n c t i o n 16 } 147

ATMega1280’s memories

◮ 128 KB program memory (flash)

◮ Biggest memory in ATMega1280 ◮ Great for storing constants

◮ 8 KB internal RAM

◮ RAM size is quite restricted ◮ Beware of stack overflow

◮ 4 KB EEPROM

◮ Useful for storing values that rarely change ◮ Limited number of read/write cycles 148

Using ATMega1280’s memories in C

◮ Memory sections available:

◮ .text: program memory, flash ◮ .data: RAM and flash ◮ .bss: RAM ◮ .eeprom

◮ The .data memory section contains constants and variable

initializations; it occupies both RAM and flash space.

◮ RAM is volatile and therfore not programmable (before

run-time).

◮ Therefore: put constant values into flash alone!

◮ No need to occupy twice the required memory! ◮ How? See Section 5 of the avr-libc manual. 149

slide-10
SLIDE 10

The .initN sections (section 4.6 avr-libc)

.init0 Weakly bound to init(). If user defines init(), it will be jumped into immediately after a reset. .init1 Unused. User definable. .init2 In C programs, weakly bound to initialize the stack, and to clear zero reg (r1). .init3 Unused. User definable. .init4 For devices with > 64 KB of ROM, .init4 defines the code which takes care of copying the contents of .data from the flash to SRAM. For all other devices, this code as well as the code to zero out the .bss section is loaded from libgcc.a. .init5 Unused. User definable. .init6 Unused for C programs, but used for constructors in C++ programs. .init7 Unused. User definable. .init8 Unused. User definable. .init9 Jumps into main().

150

Using .initN sections

Applying attributes to functions

void m y i n i t p o r t b ( void ) a t t r i b u t e (( naked , used , s e c t i o n ( ” . i n i t 3 ” ) ) ) ; void m y i n i t p o r t b ( void ) { PORTB = 0 x f f ; DDRB = 0 x f f ; } 151

Benchmarking memory usage

◮ After compilation, the static memory usage of your program

can be analyzed via avr-size.

◮ Analyzing the dynamic memory usage can be done by

(1) Code analysis (requires bounding recursion depth and heap usage). (2) Run-time analysis directly on the µc or via simulation (needs a software that monitors memory access).

152

slide-11
SLIDE 11

Dynamic memory benchmark example

void memstatInit ( void ) a t t r i b u t e (( naked , used , s e c t i o n ( ” . i n i t 3 ” ) ) ) ; extern u i n t 8 t end ; // end

  • f

bss // never c a l l t h i s f u n c t i o n ! void memstatInit () { r e g i s t e r u i n t 1 6 t i ; f o r ( i =( u i n t 1 6 t )& end ; i< RAMEND; i ++) { ∗( u i n t 8 t ∗) i = ( u i n t 8 t ) i ; } } 153

Dynamic memory benchmark example

1 mem stat t ∗memstatGetStat ( void ) { 2 s t a t i c mem stat t s t a t ; 3 u i n t 1 6 t i ; 4 u i n t 8 t u n i n i t ; 5 6 s t a t . maxStackSize = 0 x f f f f ; 7 s t a t . maxHeapSize = 0 x f f f f ; 8 // s e a r c h end

  • f

stack , s t a r t at SP and go down 9 . . . 10 // s e a r c h end

  • f

heap , s t a r t at bss end and go up 11 u n i n i t = 0; 12 f o r ( i =( u i n t 1 6 t )& end ; i< RAMEND; i ++) { 13 i f (∗( u i n t 8 t ∗) i == ( u i n t 8 t ) i ) { 14 u n i n i t ++; 15 i f ( u n i n i t == 10) { 16 s t a t . maxHeapSize = i − ( u i n t 1 6 t )& end − 9; 17 break ; 18 } 19 } e l s e { u n i n i t = 0; } 20 } 21 return &s t a t ; 22 } 154

Linker scripts

◮ (in the lab) located at /usr/avr/lib/ldscripts/ ◮ Mapping of virtual memory adresses for the ELF-file ◮ Very powerful!

155

slide-12
SLIDE 12

Bit tricks

◮ Memory constraints demand efficient programming; in

particular, using a byte to store a single bit (flag) is infeasible.

◮ Thus: pack eight bits in a byte using techniques that

efficiently pack and upack bytes (union, struct).

◮ Other bitwise techniques also come in handy, e.g. swap

contents of two registers without using a temp register.

156

Struct/union example

RTC Config Register:

typedef struct { u i n t 8 t r s : 2 ; u i n t 8 t : 2 ; u i n t 8 t sqwe : 1 ; u i n t 8 t : 2 ; u i n t 8 t

  • ut

: 1 ; } d s 1 3 0 7 s q w c o n f i g t ; typedef union { d s 1 3 0 7 s q w c o n f i g t r eg s ; u i n t 8 t raw ; } ds1307 sqw mem t ;

157

Summary

◮ Put constants into the flash (program) memory. ◮ Analyze the static and dynamic memory usage of your

programs.

◮ Apply bitwise techniques. ◮ Read avr-libc manual.

158

slide-13
SLIDE 13

Weekly Training Objective

◮ Already done

3.1.1 C demo program 3.1.3 Floating point operations 3.3.2 Interrupts 3.4.3 Generating periodic signals

◮ This week

3.3.1 Interrupt & callback demo 3.4.1 Input capture 3.6.1 UART receiver 3.6.2 UART sender 3.9.1 Keypad

◮ Next week

3.4.4 PWM signals and glitches 3.6.4 TWI (I2C) 3.8.2 Button debouncing 3.8.4 LCD

159