Click here to load reader
Upload
taghi
View
221
Download
3
Embed Size (px)
Citation preview
Real Time Operating System for AVR Microcontrollers
Taghi.Mohamadi
Iran University of Science and Technology (IUST), Tehran, Iran
Abstract
This paper presents a Real Time Operating System
(RTOS) for using in AVR microcontrollers. Using
RTOS can result to eliminating processor waiting
without doing any applicable work. By using RTOS a
lot of tasks can be run independently and
simultaneously. So the CPU’s efficiency will be higher
than conventional systems with infinite loops. Although
there are too many RTOS like QNX, they are not free
and cheep. Others like µC/OS-II need too much
memory space rather than simple microcontroller such
as AVR microcontrollers. This paper describes a
compact and efficient RTOS for AVR microcontrollers.
This RTOS is preemptive multitasking. The design has
good performance, small code size, and low memory
usage as the design was specifically implemented for
AVR devices. Finally a practical algorithm with its
suitable circuit with atmega32 is presented to test this
information about the designed RTOS.
1. Introduction
An operating system (OS) is software that uses all
the hardware such as RAM, ROM, CPU, and so on for
better management and controlling them. Generally,
based on the running programs, there are two operating
systems: single-task operating system and multi-task
operating systems. In multi-task OS there are too many
tasks in the system simultaneously; the OS divides
processor among all of them. That kind of processor
that divides times among them is called scheduler.
There are two kinds of scheduling algorithms:
preemptive algorithm and non preemptive algorithm.
In the latter each task can be run after finishing another
one, but in the former, scheduler can transform
programming control from a running program to
another one. Real time operating system (RTOS) is a
kind of OS that each task must run in a certain times
and if not, OS fails. So, based on the above mentioned
points RTOS should be multi-task and preemptive for
performing the scheduling mechanism. The main
purpose in these kinds of OS is to be performing in a
time limitation. There are too many kinds of RTOS
such as; µCOS, ECOS, QNX, Vxworks, Free RTOS,
and so on. In this paper a RTOS for AVR
microcontrollers has been designed by Atmel
Company. It has been designed by C language and also
it has been performed on Atmega32 microcontroller.
For compiling its code, Code vision AVR has been
used.
2. Introducing AVRs
AVR technology has been introduced in 1997, fist
time. It has been designed based on RISC technology.
It has 32 general purpose registers: R0 to R31. There
are too many kinds of AVR including LCD AVR,
Mega AVR, Xmega AVR, Tiny AVR, and AT90S
AVR. Like other microcontrollers there are different
languages for programming such as C and Assembly.
The favorite compiler and language for programming
is C and Code vision. For more information about
AVRs, refer to [8].
3. Proposed plan for RTOS
Most of the designed system will perform the
determined tasks after turning their power on. Those
systems will use too much memory space and are
somehow complex. Regarding low space memory in
AVR and determined tasks without any need to change
them in most cases, optimum plan will be presented as
follow.
First all tasks with their requirement time to
perform should be determined. A plan to compile tasks
and OS has been designed. In fact, each task in the
designed RTOS should use all hardware independently
from other tasks. Tasks should be able to run
978-1-4577-1958-5/11/$26.00 ©2011 IEEE
simultaneously without any need to reprogramming for
new codes. Users can change scheduling algorithm
according to their systems. A timer can be used to
generate the least timer tick according to the least time
slice and based on it; scheduler can manage and control
tasks according to their priority.
4. Main parts of RTOS’s code
4.1. Global variables
“os_central_table” is a structure that saves the needed
data of the system. typedef struct os_central_table {
// Timer ticks since last boot
os_systime; ULONG
os_dispcntr;//dispatch counter ULONG
os_idlecntr;// Counter for processor idle
time ULONG
// OS version os_version; UBYTE
// OS running flag os_running; UBYTE
os_schedrun;//scheduler flag UBYTE
// Pointer to used TCBs os_tcb
*tcb_used_list;
// Pointer to TCB freelist os_tcb
*tcb_free_list;
// Pointer to current running task TCB
os_tcb *tcb_current;
os_tcb *tcb_runq;//Pointer to highest
priority runnable task TCB
*scb_used_list; // Pointer to used
semaphores os_scb
*scb_free_list; // Pointer to semaphores
freelist os_scb
*mcb_used_list; // Pointer to used
message mailboxes os_mcb
*mcb_free_list; // Pointer to mailbox
freelist os_mcb
} os_cent_tbl;
4.2. Constants
In fact these constants are used to dedicate the
needed memory space to variables. Dedicating the
memory space is static not dynamic. All constants are
determined in “rtos.h” header file. Those include:
OS_TASK_MAX: the maximum number of tasks,
OS_SEM_MAX: the maximum number of semaphores,
OS_MBOX_MAX: the maximum number of mailboxes,
OS_TASK_HSTK_SIZE: the hardware stack size,
OS_TASK_DSTK_SIZE: the software stack size,
OS_TICK_TIME: duration of each slice time for
running for each task,
The value of OS_TICK_TIME is between 1 msec to
16 msec. CTC mode of timer0 has been used in 15.624
KHz while the main clock of microcontroller is 16
MHz. According to the application change may occur
in the used timer’s mode or others.
C. Types of data
There are these types of data in rtos.h:
typedef unsigned char UBYTE;
typedef unsigned int UWORD;
typedef unsigned long int UDWORD;
typedef unsigned long int ULONG;
4.3. Task Control Block (TCB)
OS performs the task with high priority in each timer
interrupts. The designed RTOS does not do any
memory protection and all tasks use a shared address
space. Each task has a TCB that all needed data about
that task are hold in it. All TCBs will link with each
other through operating system and a single linked list
will be created. TCB’s fields are as following: typedef struct os_task_control_block
{
// Pointer to task's hardware stack
*hwstk; void
// Pointer to task's data stack
*datastk; void
// Status of task status; UBYTE
// Priority of task prio; UBYTE
// Nbr of ticks to keep task sleeping
delay; UWORD
//for keep track task time ULONG
ttime;
//for keep track stack use *hstktop ;
void
//for keep track stack use *dstktop ;
void
struct os_task_control_block
*next_tcb;//Pointer to next task's
TCB
// Next task on semaphore waiting
list void *tcb_sem_q;
} os_tcb;
4.4. Creating Tasks
All the tasks will be created by “os_task_creat()”
function. This function will be called by OS to create
“NULL_Task()”. If any task is not determined by the
user, this task will be run to prohibit from occurring
any problems. “os_task_create()” has four parameters:
pointer to point this task’s code, pointers to dedicated
space for hardware stack, pointer to dedicated space for
software stack, and task priority. This function can be
seen in the designed example. In this function
hardware stack will be produced, firstly. This stack
should be compatible with Code vision compiler.
4.5 .Stack
Code vision compiler uses two hardware and
software stack for converting C codes to assembly
codes. Hardware stack is used to hold interrupt and
call- routines return’s addresses. So, when “posh” or
“pop” are bsed, the hardware stack is used practically.
Software stacks are used for sending parameters,
getting the returned value from subroutines, and saving
local variables. Each task should have these two
special stacks of it.
4.6. Null task
It is similar to other tasks that are defined by the user
but it has the lowest priority. It is always runable. This
task will run in “Idle” mode of the system’s modes. It
can light a LED to show the balance of the system.
5. Experimental task to test
5.1. Initializations
In this section, a simple system has been introduced
that was designed by the presented plan. There are four
main tasks: task1, task2, task3, and task4. The main
task is task1. The other tasks will be created by this
task. Others are infinite loops that will blink a
coordinate LED. Task1 interfaces with serial port of
microcontroller and waits for a command from PC.
This task toggles coordinate LED to itself based on the
receive character from computer. Based on the
received character, each task will be active or inactive.
Scheduler in these systems is “_os_schedule()” ;it has
been located in RTOS’s core. The “_” sign at the
initiation of function’s name means that this function is
dedicated to OS and cannot be called by tasks.
Algorithm uses preemptive system. Switching tasks is
done by “_os_dispatch()” function.
Each semaphore has a semaphore control block
(SCB) that dedicated to it. These SCB will link with
each other and create a linked list. SCB’s fields are as
following: typedef struct os_sema {
// Semaphore value count; UWORD
// Semaphore queue *scb_sem_q; os_tcb
struct os_sema *next_scb;// Pointer
next semaphore's SCB
} os_scb;
In designed RTOS “os_sem_create()” function
creates semaphores. Semaphore uses these two
functions; os_wait() and os_signal() .In the kernel code
their usage has been shown.
Each mailbox has a special control block (MCB) to
save its needed data. Each MCB is as following: typedef struct os_mail_box {
// Semaphore for sending to mailbox
*msend; os_scb
// Semaphore for receiving from
*mrecv; os_scb_mailbox
// Pointer to message *mmsg; void
// Pointer to next mailbox struct
os_mail_box *next_mcb;
} os_mcb;
MCB is created by “os_ mbox _create()” function. Its
usage has been indicated in kernel code.
5.2. Main Parts of Kernel Code
Task creator code: os_tcb *os_task_create( void
(*task)(void), UBYTE *hstack, UBYTE
*dstack,UBYTE p ){
UBYTE *stk, *dstk, *hstk;
UBYTE i;
os_tcb *tcb_new;
OS_ENTER_CRITICAL;
tcb_new = (os_tcb
*)os_ctbl.tcb_free_list;// Get next
free TCB
// TCBs left? if( tcb_new ) {
// Set up the hardware stack
hstk = (UBYTE *)hstack +
(OS_TASK_HSTK_SIZE - 1);// Stack
begins in the end of array
stk = hstk;
// Low part of task's address *stk--
= (UBYTE)(task);
// High part of task's *stk-- =
(UBYTE)(task >> 8);
address
for(i=0;i<30;i++) // Clear all other
registers
*stk-- = 0;
// SREG with interrupts enabled *stk-
- = 0x80;
// Set up data stack
dstk = (UBYTE *)dstack +
(OS_TASK_DSTK_SIZE - 1);// Stack
begins in the end of array
os_ctbl.tcb_free_list = (os_tcb
*)tcb_new->next_tcb;//
Release TCB from freelist
tcb_new->next_tcb = (os_tcb
*)os_ctbl.tcb_used_list;// Link
new TCB into TCB used list
os_ctbl.tcb_used_list = (os_tcb
*)tcb_new;
// Load data stack tcb_new->datastk =
(UBYTE *)dstk;
pointer to TCB
// Load hw stack tcb_new->hwstk =
(UBYTE *)stk;
pointer to TCB
//for keep track stk tcb_new->hstktop
= (UBYTE *)hstk;
//for keep track stk tcb_new->dstktop
= (UBYTE *)dstk;
// Make task runnable tcb_new->status
= OS_TASK_RUNNABLE;
// Set task's priority tcb_new->prio
= (UBYTE)p
// No initial delay tcb_new->delay =
(UWORD)0;
// Initialize semaphore tcb_new-
>tcb_sem_q = (os_tcb *)0;
queue }
OS_EXIT_CRITICAL;
return( tcb_new ); }
Scheduler algorithm:
void _os_schedule( void ){
Switch to the task with higher
priority in next timer tick. }
Dispatcher algorithm: void _os_dispatch( void ){
1. Save HW SP and data SP to current
task's PCB
2. Load SP from highest priority
task's TCB
3. Restore context and return to new
task }
5.3. Hardware design
Atmega32 has been used for testing the designed
RTOS.
The whole circuit is as fig. 1. Atmega32
microcontroller has been used in 16 MHz clock,
Max232 for serial interface with PC, capacitors and
LEDs.
Figure 1. Circuit to test RTOS
6. Discussing results
This paper has proposed algorithms to design RTOS.
And also a RTOS for AVR devices has been designed.
Customary programs for microcontrollers use infinite
loop and each task for running needs to be run after
finishing another one. So in these systems, the
processor cannot do some tasks simultaneously. Using
interrupts may seem like an option but it reduces the
interrupt latency as the computation has to take place
inside the ISR. Thus using a RTOS is an applicable
engineering solution. The main feature of such RTOS
rather than available RTOS such as ECOS is its low
memory usage and its small size. The practical circuit
indicates that the ROS works well. This RTOS can be
used with every kind of AVR. It is better to adjust the
registers and system clock in the kernel code according
to some special factors.
7. References
[1] Tran Nguyen,Bao Anh, “REAL-TIME OPERATING SYSTEMS
FOR SMALL MICROCONTROLLERS”, Published by the IEEE
Computer Society,pp.30-46, September 2009.
[2] EmbOS Real-Time Operating System, User & Reference Guide,
Segger Microcontroller 2008; http://www.segger.com/cms/admin/
uploads/productDocs/embOS_Generic.pdf.
[3]Yao Li and Paul Wilson, “PARTOS-11: an Efficient Real-Time
Operating System for Low-Cost Microcontrollers.” First IEEE
International Workshop on Electronic Design, Test and Applications
(DELTA.02), 2002.
[4] G. Lipari and S. K. Baruah, “Efficient scheduling of real-time
multi-task applications in dynamic systems,” 6th IEEE Real-Time
Technology and Applications Symposium, 2000
[5] Tao Wang, Qingjian Liu, Liwen Wang,” An RTOS-based
Embedded CNC System”, International Conference on Computer,
Mechatronics, Control and Electronic Engineering (CMCE), pp.33-
37,2010.
[6] Q. Han, "The needed characteristics of RTOS," Microcontrollers
& Embedded System, pp. 85-86, Feb. 2004.
[7] Gianluca Cena, Ranieri Cesarato, Ivan Cibrario Bertolotti,” An
RTOS-Based Design for Inexpensive Distributed Embedded
System”,IEEE,pp.1768-1774,2010.
[8] Atmel, http://www.atmel.com.
[9] atmega32 datasheet,www.datasheetcatalog.com
[10] F.A.Mohideen,” RTOS for PIC18 Microcontrollers”, 5th
International Conference on Industrial and Information Systems,
ICIIS 2010,pp.275-283, Jul 29 - Aug 01, 2010, India.
[11] Tanenbaum, Andrew S.,Operating Systems: Design and
Implementation
PB0/T0/XCK
1
PB1/T12
PB2/AIN0/INT23
PB3/AIN1/OC04
PB4/SS5
PB5/MOSI6
PB6/MISO7
PB7/SCK8
RESET9
XTAL212
XTAL113
PD0/RXD14
PD1/TXD15
PD2/INT016
PD3/INT117
PD4/OC1B18
PD5/OC1A19
PD6/ICP120
PD7/OC221
PC0/SCL22
PC1/SDA23
PC2/TCK24
PC3/TMS25
PC4/TDO26
PC5/TDI27
PC6/TOSC128
PC7/TOSC229
PA7/ADC733
PA6/ADC634
PA5/ADC535
PA4/ADC436
PA3/ADC337
PA2/ADC238
PA1/ADC139
PA0/ADC040
AREF32
AVCC30
U1
ATMEGA32
T1IN11
R1OUT12
T2IN10
R2OUT9
T1OUT14
R1IN13
T2OUT7
R2IN8
C2+
4
C2-
5
C1+
1
C1-
3
VS+2
VS-6
U2
MAX232
C1
1uF
C2
1uF
C3
1uF
C41uF
+5
1
6
2
7
3
8
4
9
5
SERIAL CONNECTORD1
D2
D3
D4