22
Programming embedded systems Seminar 5 Embedded Operating System Dr. Tran Thanh Hung Department of Automation Technology, College of Engineering, Can Tho University Email: [email protected]

Seminar 5

  • Upload
    kt8815

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Seminar 5

Programming embedded systems

Seminar 5

Embedded Operating System

Dr. Tran Thanh Hung Department of Automation Technology,

College of Engineering, Can Tho UniversityEmail: [email protected]

Page 2: Seminar 5

Review

In the previous seminars, we use a “super loop” to run a task.

In this seminar, we will use a different way to run a task.

Page 3: Seminar 5

Outline

How to create an Embedded OS for embedded applications?

• Periodic functions

• Implement periodic functions

• Creating Embedded OS

• Using Embedded OS

Page 4: Seminar 5

Seminar objectives

At the end of this seminar, by referring the lecture notes, students will be able to:

• understand issue of periodic function

• use timer to create a simple Embedded OS (EOS)

• implement periodic functions running in EOS

Page 5: Seminar 5

How to run a task?

• We has used a “super loop” architecture to run a taskvoid main (void) {

X_Init() ; //Prepare for Task X()while(1) //super loop

{ X(); //Perform task X() }}

• With this architecture, it is very difficult to run the task at a precise interval of time.

Page 6: Seminar 5

Periodic function

There are many applications require to run tasks repeatedly, at precise intervals

• Keypad need to be scanned every 200ms• The display (PC monitor, LCD) must be refreshed 60

times every second• Music must be sampled at 44.100 times per second• Temperature sensors must be sampled once per second

In practice, many embedded systems must be able to support this type of “periodic function”

Page 7: Seminar 5

Periodic function

• If you need to run the function X() every 50 ms, how do you implement?

• If you know the function takes 10 ms to complete while(1) //super loop { X(); //Call the function (10 ms duration)

delay(40); //Delay for 40 ms }

This approach will be fine, if:1. We know the precise duration of X()2. This duration never varies

Page 8: Seminar 5

Periodic function

while(1) //super loop { X(); //Call the function (10 ms duration)

delay(40); //Delay for 40 ms }

However,1. It is very difficult to know the duration of X()2. This duration often vary 3. This approach is in inefficient: waste in a delay loop

Is there any way to implement periodic function, running at precise 50 ms interval ?

Page 9: Seminar 5

Timer delay: review

void delay_t0(tWord x){ TMOD &= 0xF0; TMOD |= 0x01; //set Timer 0 mode 1

x = 65536 - x + 26;TH0 = x/256;TL0 = x%256; //set initial value of TimerTF0 = 0; //make sure overflow flag off

TR0 = 1; //start Timer 0while(TF0==0); //wait Timer 0 overflow (TF = 1) TR0 = 0; //stop Timer 0

}Note:• 1 increment of timer takes (OSC_PER_INTS/OSC_FRE)*103 ms

• Instead of waiting for timer overflow, you can setup an interrupt from timer

Page 10: Seminar 5

Timer interrupt setup

• Run Example 4.1 in simulator, toggle Disassembler window• Chose PeripheralTimerTimer 0• Chose PeripheralInterrupt• Click Run and then Halt• In Interrupt System, click Timer 0• Check EA and ET0 • Now set TH0 TL0 = FF F1• Click until TH0 TL0 = FF FF• Look at the program while clicking one more time. • What happen to the program?

Page 11: Seminar 5

Timer interrupt setup

void Timer0_interrupt_init(tWord x){ TMOD &= 0xF0; TMOD |= 0x01; //set Timer 0 mode 1

x = 65536 - x;TH0 = x/256;TL0 = x%256; //set initial value of TimerET0 = 1; EA = 1; //Enable interruptTR0 = 1; //start Timer 0

}

Page 12: Seminar 5

Implement periodic function

Instead of writing a program like this:void main (void) {

X_Init() ; //Prepare for Task X()while(1) //super loop

{X(); //Call the function (10 ms duration)delay(40); //Delay for 40 ms

}

We use a better way to do:

Page 13: Seminar 5

Implement periodic function

#include <main.h>

static unsigned int x;

void main (void) { X_Init() ; //Prepare for Task X()

Timer0_interrupt_init(50000);//initialize timer1 to interrupt every 50 ms

while(1); //empty loop}

Timer0_ISR() interrupt INTERRUPT_Timer_0_Overflow{

TH0 = x/256;TL0 = x%256; //initialize timer1 againX(); //Call the function

} What is the value of timer after overflow ?

Page 14: Seminar 5

Exercise 1

• Put Timer0_interrupt_init() and Timer0_ISR() into file Interrupt.c and Interrupt.h

• Modify the program in Exercise 4.3, using Timer0_interrupt_init and Timer0_ISR()

Page 15: Seminar 5

Implement periodic function: Problem

void main (void) { X_Init() ; //Prepare for Task X()

Timer0_interrupt_init(50000);//initialize timer1 to interrupt every 50 ms

while(1); //empty loop}

Timer0_ISR() interrupt INTERRUPT_Timer_0_Overflow{

TH0 = x/256;TL0 = x%256; //initialize timer 0 againX(); //Call the function

}

It takes time to reload the initial value for the timer.• Sometime you forget to reload the value. This approach is not adequate if the system requires very precise

timing

Reload initial value

Page 16: Seminar 5

Embedded OS: Timer 2

• Run Example 4.1 in simulator• Chose PeripheralTimerTimer 2• Chose PeripheralInterrupt• Click Run and then Halt• Do you see any change on Timer 2?• Now check TR2, note value of T2CON• Now set T2 = FFF0 and RCAP2 = FFF0• Click until T2 = FFFF• Look at T2 while clicking one more time. • What happen to T2 ? (Repeat again with other value of RCAP2)• In Interrupt System, click Timer 2• Check EA and ET2, repeat again• What happen to the program when timer overflows?

Page 17: Seminar 5

Embedded OS: Initialize/******************************************************************************* * @fn EOS_init (unsigned int x) * @brief Initialize for Embedded Operating System: * - timer 2 interrupt in next x microsecond* - no reload required * @param x : number of microsecond * @return void*/void EOS_init(unsigned int x){ unsigned int _count = 65536 - x;

RCAP2H = _count/256; RCAP2L = _count%256;//set reload value TH2 = RCAP2H; TL2 = RCAP2L;//set initial value of TimerEA = 1; ET2 = 1; //enable timer 2 interruptT2CON = 0x04; //set Timer 2 as 16 bit timer, start timer

}

Page 18: Seminar 5

Embedded OS: Implement

void main (void) { Your_function _Init() ; //Initialize for Your_function

EOS_init(50000); //initialize timer 2 to interrupt every 50 ms

while(1); //empty loop}

EOS_ISR() interrupt INTERRUPT_Timer_2_Overflow{

TF2 = 0; Your_function(); //This function will be called every 50 ms

}

Problem ?

Page 19: Seminar 5

Embedded OS: Implementvoid main (void) { Your_function _Init() ; //Initialize for Your_function

EOS_init (50000);//initialize timer1 to interrupt every 50 ms

while(1); //empty loop { go_to_sleep(); }

}

EOS_ISR() interrupt INTERRUPT_Timer_2_Overflow{ TF2 = 0;

Your_function(); //This function will be called every 50 ms } void go_to_sleep(void){ PCON |= 0x01; // Enter idle mode}

Page 20: Seminar 5

Example 5.1

#include <main.h>#include <delay.h>void main (void){while(1) { P0=~P0; //

delay_t0(50000); }}

• Run Example 4.1 in simulator• Use Performance Analyzer (PA) to see the percentage

of time that delay_t0 taken• How many percent?

Page 21: Seminar 5

Example 5.2

#include "Main.h"#include "EOS.h"void main (void){ EOS_init(50000);

while(1) // Super Loop{ go_to_sleep(); // Enter idle mode to save power}

}EOS_ISR() interrupt INTERRUPT_Timer_2_Overflow //in file EOS.c{

TF2 = 0; // Put your code here

P0 = ~P0;} • Run Example 5.2 in simulator• Use Performance Analyzer (PA) to see the percentage of time that

go_to_sleep() taken• How many percent?

Page 22: Seminar 5

Exercise 2

• Put EOS_init() and EOS_ISR() into file Interrupt.c and Interrupt.h

• Modify the program in Exercise 5.1, using EOS • Only run the time if the switch connected to

P1.0 is pressed.• Reset the time if the switch connected to P1.3

is pressed.