Lecture 10 Hardware Accelerators Ingo Sander [email protected].
Lecture 9 RTOS: Inter-process communication Ingo Sander [email protected].
-
Upload
tobias-randall -
Category
Documents
-
view
238 -
download
4
Transcript of Lecture 9 RTOS: Inter-process communication Ingo Sander [email protected].
April 19, 2023 IL2206 Embedded Systems 2
How do processes communicate? We have discussed
how a preemptive RTOS schedules processes
how to derive a feasible schedule
But how do processes communicate with each other? Operating systems provide
communication mechanisms Semaphores Message Queue …
P1
P2 P3
System
Environment
April 19, 2023 IL2206 Embedded Systems 3
Components in an RTOS
An RTOS has typically the following components: Scheduler
Determines which task is running at each time instant
Objects Special constructs like
tasks, semaphores or message queues
Services operations that the kernel
performs on objects
Scheduler
Services
Objects
Events
Message Queues
Semaphores Tasks
Timers
Time ManagementMemory ManagementInterrupt HandlingDevice ManagementOther Services
ISR
April 19, 2023 IL2206 Embedded Systems 4
Process (Task) States A task can be in several states The three basic states are
ready state: task is ready to run, but a higher priority task is executing
blocked state: a task has requested a resource that is not available, has to wait for some event to occur or has delayed itself for some duration
running state: task has highest priority and is running
Models with more states exist, for instance dormant or interrupted
Ready
Blocked Running
Task isunblocked
Task hashighest priority
Task is blocked due to unavailable resource
Task is pre-empted by a
higher-prioritytask
April 19, 2023 IL2206 Embedded Systems 5
Interprocess communication
RTOS provides mechanisms so that processes can pass data. Depending on the RTOS different mechanisms
are supportedSemaphores, message queues, event flags, …
Communication can be blocking: sending process waits for response non-blocking: sending process continues
April 19, 2023 IL2206 Embedded Systems 6
Shared Memory Communication
Processes share some common memory locations concept reflects system
architecture order of accessing
common location is important
source for errors disciplined design is
required
CPU 1
CPU 2
LocalMemory
LocalMemory
SharedMemory Location
April 19, 2023 IL2206 Embedded Systems 7
Message Passing Processes send
messages along a communication channel
Information is forwarded by messages
Abstract concept that fits to asynchronous distributed architectures
Since memory is not shared less sensible for bugs
Requires more advanced protocol
P1
P2
P3
April 19, 2023 IL2206 Embedded Systems 8
Advantages of a Layered Model
Mem P1 P2
uses Hardware Drivers
Hardware
Operating Systemuses OS Comm. Primitives
Compiled Programuses Comm. Primitives
Source Code
here Shared Memory Comm.
• A programming model based on message passing can still be implemented by a shared memory architecture
• Each layer has to use the primitives that are provided by their lower layer neighbour
April 19, 2023 IL2206 Embedded Systems 9
Critical Sections Simultaneous use of a shared resource can lead to disastrous
consequences Resources that can only be used by one at a time, are called
serially reuseable and the use of the resource cannot be interrupted
The code that accesses a serially reusable resource is called a critical section or critical region
Thus there must be a mechanism that prevents a collision, i.e. the simultaneous use of such a resource)
Examples: Access to I/O-device Writing to memory
April 19, 2023 IL2206 Embedded Systems 10
Example Critical Sections
task1()
{
printf(”I am Task 1”);
}
task2()
{
printf(”I am Task 2”);
}
Possible Output: I am I am Task 2 Task1
April 19, 2023 IL2206 Embedded Systems 11
RTOS Kernel Objects for Synchronization and Communication
RTOS kernel provide several objects for synchronization and communication Semaphores Message Queues Event Registers …
Semaphores
Introduced by Dijkstra in 1965 Synchronization device with an integer value S Two atomic (must not be interrupted) operations
are defined P(S) (or DOWN, WAIT) – check if the current value is
greater than zero YES – s is decremented and calling thread continues NO – calling thread is blocked
V(S) (or UP, POST, SIGNAL) – increments the variable s
April 19, 2023 IL2206 Embedded Systems 12
April 19, 2023 IL2206 Embedded Systems 13
Semaphore
A semaphore is a kernel object that one or more threads of execution can acquire or release for the purpose of synchronization or mutual exclusion
April 19, 2023 IL2206 Embedded Systems 14
Semaphore
A semaphore is like a key that allows a task to carry out some operation or to access a resource
There maybe several keys for each semaphore If the task can acquire the semaphore, it can carry
out the intended operation or access the resource Otherwise the task is blocked, if it chooses to wait
for the release of the semaphore
April 19, 2023 IL2206 Embedded Systems 15
Definitions of Access to Binary Semaphores
void p(sem s) {
if (s.value == 1 {
s.value = 0;
}
else {
place process in queue;
block process;
}
}
void v(sem s)
{
if(s.queue is empty)
s.value = 1;
else {
remove a process P from queue;
place process P on ready list;
}
p(s) waits until s.value is 1 (the ’key’ is available). When task gets key, it sets s.value to 0. The key is released with v(s) (s.value is set to 1).
April 19, 2023 IL2206 Embedded Systems 16
Example Critical Regions
task1(){
p(s);printf(”I am Task 1”);v(s);
}
task2(){
p(s);printf(”I am Task 2”);v(s);
}
The critical region printf(...) is protected by a binary semaphore (only values 0 and 1 are used)!
April 19, 2023 IL2206 Embedded Systems 17
Semaphore
Blocked tasks are kept in a task-waiting list When the semaphore is released, one task of
the task waiting list gets access to the semaphore and is put into ready state
The exact implementation of the task-waiting list depends on the RTOS kernel
April 19, 2023 IL2206 Embedded Systems 18
Creation of a semaphore
When a semaphore is first created, the kernel assigns it to it an associated semaphore
control block (SCB) unique ID value (binary or a count) task-waiting list
SemaphoreControl Block
Value(Binary or a Count)
SemaphoreName or ID
Task 2Task 1
Task Waiting List
April 19, 2023 IL2206 Embedded Systems 19
Binary semaphore
A binary semaphore has either a value of
0 (unavailable) or 1 (available)
A binary semaphore is a shared resource Any task can release it!
Unavailable0
Available1
ReleaseAcquire
B
April 19, 2023 IL2206 Embedded Systems 20
Counting semaphore A counting semaphore uses
a count to be able to give more than one task access
0 (unavailable) or > 0 (available)
The count can be bounded (initial value gives
maximum number) unbounded (no maximum
value) A counting semaphore is a
shared resource Any task can release it!
Unavailable
Available
Release(Count = 1)
Acquire(Count = 0)
Release(Count = Count + 1)
Acquire(Count = Count - 1)
C
April 19, 2023 IL2206 Embedded Systems 21
Mutual exclusion semaphore(Mutex)
A mutex is a special binary semaphore that supports ownership and often recursive access (recursive mutex)
Only the task that has locked a mutex can release it
Mutex is created in unlocked state
Unlocked
Locked
Acquire(Count = 1)
Release(Count = 0)
Acquire (recursive)(Count = Count + 1)
Release (recursive)(Count = Count - 1)
M
Initial(Count = 0)
April 19, 2023 IL2206 Embedded Systems 22
Wait-and-signal synchronization
Semaphores can be used to synchronize tasks The example below shows how a binary semaphore
can be used to coordinate the execution of control The task WaitTask has to wait until the task SignalTask releases the binary semaphore
SignalTask WaitTaskB
April 19, 2023 IL2206 Embedded Systems 23
Multiple shared-resource-access synchronization
The example below shows how a counting semaphore can be used to protect a pool of equivalent shared resources
Task1
Task2
Task3
C
EquivalentShared Resource
EquivalentShared Resource
April 19, 2023 IL2206 Embedded Systems 24
Semaphore
Low-level mechanism Advantage: Low implementation overhead Disadvantage: Conceptually very difficult to
analyze systems with multiple semaphores
Be very restrictive when using semaphores!
April 19, 2023 IL2206 Embedded Systems 25
Message passing
Message passing between processes:
P1 P2
Mailbox/Mesage Queuemsg
msgmsg
Dimensioning of message queue buffers is an important task!
April 19, 2023 IL2206 Embedded Systems 26
Message passing
Message passing is an abstract communication scheme
Processes communicate by sending and receiving messages
A received message can initiate new actions (like an interrupt)
Message passing can also be implemented on shared memory architectures
April 19, 2023 IL2206 Embedded Systems 27
Message queue
A message queue is a buffer-like object through which tasks and ISRs send and receive messages to communicate and synchronize with data
A message queue holds temporariliy messages from a sender until the intended receiver is ready to read them
Temporary buffering decouples sending from receiving
A message queue with a single buffer is called a mailbox
April 19, 2023 IL2206 Embedded Systems 28
Creating a message queue
When a message queue is created, it is assigned a queue control block, a queue name, an ID, memory buffers, a queue length, a maximum message length, and one or more task-waiting lists
Queue Control Block Memory
Task 2Task 1
Sending Task Waiting List
Task 4Task 3
Receiving Task Waiting ListQueue Name / ID
Maximum Message Length
Queue Length
April 19, 2023 IL2206 Embedded Systems 29
Message queue status
The message queue is operated by means of an FSM with 3 states
Empty Not Empty Full
Msg Arrived(msgs++)
Msg Arrived(msgs=queueLength)
Msg Delivered(msgs--)
Msg Delivered(msgs--)
Msg Arrived (msgs++)
Msg Delivered (msgs--)
Queue Created(msgs=0)
April 19, 2023 IL2206 Embedded Systems 30
Message queue status
If the queue is full, the sending task will not be successful and has to wait before sending its message (sending task waiting list)
Empty Not Empty Full
Msg Arrived(msgs++)
Msg Arrived(msgs=queueLength)
Msg Delivered(msgs--)
Msg Delivered(msgs--)
Msg Arrived (msgs++)
Msg Delivered (msgs--)
Queue Created(msgs=0)
April 19, 2023 IL2206 Embedded Systems 31
Message queue status
If the queue is empty, the receiving task has to wait for its messages (receiving task waiting list)
Empty Not Empty Full
Msg Arrived(msgs++)
Msg Arrived(msgs=queueLength)
Msg Delivered(msgs--)
Msg Delivered(msgs--)
Msg Arrived (msgs++)
Msg Delivered (msgs--)
Queue Created(msgs=0)
April 19, 2023 IL2206 Embedded Systems 32
Message queue storage
Different kernels store message queues in different locations in memory System Pool
All queues are stored in the same part of the memory Advantage: may save memory, since queues can share
memory space Disadvantage: queue with large messages may not leave
enough space to other queues Private Buffers
Each queue has its own buffer (full size) Advantage: ensures that messages are not overwritten Disadvantage: inefficient memory use
April 19, 2023 IL2206 Embedded Systems 33
Pointers
Instead of operating with full messages, it is often more useful to use pointers to a message in the queue memory is more efficiently used, since messages
can have different length, but pointers have not copying overhead can be reduced
during sending of messages, messages are copied between the sending task, the message queue and the receiving task
April 19, 2023 IL2206 Embedded Systems 34
Sending messages
Kernels typically fill a message queue from head to tail in FIFO order
Many implementations also allow urgent messages to go straight to the head of the queue
April 19, 2023 IL2206 Embedded Systems 35
Sending messages
Messages are sent to the queue in the following ways: non-blocking (ISR and tasks)
sending task does not wait, if the send call is successful
if the queue is full the send call returns an error block with a timeout (tasks only)
send call waits if the queue is full for a defined period block forever (task only)
send call wait until message can be send
April 19, 2023 IL2206 Embedded Systems 36
Receiving messages
Messages are received from the queue in the following way: non-blocking blocking with timeout blocking
Blocking occurs when the message queue is empty
April 19, 2023 IL2206 Embedded Systems 37
Receiving messages
Which task receives the message? Kernels support two policies for the waiting lists
FIFO: First task that requests the message is given the message
Priority-Based: Task in waiting list with highest priority receives the message
April 19, 2023 IL2206 Embedded Systems 38
Receiving messages
Messages can be read from the head of the message queue in two different ways: destructive read
receiving task removes message from queue non-destructive read
receiving task reads message without removing it
Most kernels only support only destructive read
April 19, 2023 IL2206 Embedded Systems 39
Event registers
Some kernels provide a special event register as part of each task’s control block
Tasks can set or clear event flags Tasks can wait for a special combination of event
flags ((event 2 and 3) or event 5)
Task
ISRs
0 1 0 0 1 0 0 0
Event Register
AND/OR?Conditional Checks Task
Waiting Task
Events
April 19, 2023 IL2206 Embedded Systems 40
ISR-to-task synchronization
Interrupt service routines can be synchronized with tasks in several ways
During the interrupt control is passed to the ISR who for instance releases a semaphore, sets an event flag or sends a message
When the task continues execution it can take appropriate action
ISR TaskB
ISR Task
ISR Task
April 19, 2023 IL2206 Embedded Systems 41
Deadlock
procedure Task A;begin
…P(S);use_resource_1;…P(R);use_resource_2;V(R);V(S);
end;
procedure Task B;begin
…P(R);use_resource_2;…P(S);use_resource_1;V(S);V(R);
end;
Task 1 waits for resource 2
Task 2 waits for resource 1
April 19, 2023 IL2206 Embedded Systems 42
Deadlock and Lifelock
In deadlock no process can satisfy its requirements because all are blocked
In lifelock (starvation) at least one process is satisfying its requirements, while one or more are not Starvation occurs when a task does not receive sufficient
resources to complete processing in its allocated time Deadlock is a serious problem because it cannot
always be detected by testing and does only occur very infrequently, which makes it extremely dangerous!
April 19, 2023 IL2206 Embedded Systems 43
Deadlock and Starvation
When using parallel processes deadlock or starvation may occur
R1
P1
R2
P2
P1 holds R1
P2 holds R2P1 waits for R2
P2 waits for R1
Deadlock
Both processes P1 and P2 cannot proceed, because each process needs access to a resource that is held by the other process.
April 19, 2023 IL2206 Embedded Systems 44
Deadlock and Starvation
When using parallel processes deadlock or starvation may occur
Starvation
A1
A2
B1
B2
Msg1
Msg1
Msg2
Msg2
P1 P2
P3
Priorities: P1 > P2 > P3
Process P3 is never executed, since either P1 or P2 has access to the needed resource
April 19, 2023 IL2206 Embedded Systems 45
Memory Management
Memory is a limited resource in an embedded system and should be used efficiently
Standard C-procedures like malloc and free are dangerous (Labrosse), since because of fragmentation may prevent to obtain a
single contiguous memory area execution times are in general non-deterministic
due to the algorithms used for the location of a contiguous block of memory
April 19, 2023 IL2206 Embedded Systems 46
Alternatives to malloc and free
Definition of user-defined memory partitions with a defined block size
Allocation and deallocation of memory blocks is done in constant time and is deterministic
No fragmentation
Partition
Block Size
April 19, 2023 IL2206 Embedded Systems 47
Alternatives to malloc and free
There can be different partitions with blocks of different size Memory is allocated and released with well-defined functions MicroC/OS-II uses these memory management technique
Partition 1 Partition 2 Partition 3
April 19, 2023 IL2206 Embedded Systems 48
Priority inversion
Priority inversion occurs, when a low-priority task executes while a ready higher-priority task waits
April 19, 2023 IL2206 Embedded Systems 49
Example for priority inversion Priority: T1 > T2 > T3 T1 and T3 share resource R
T1:: begin ... lock(R);CS1;unlock(R) ... end;T2:: begin ... ... end;T3:: begin ... lock(R);CS1;unlock(R) ... end;
T3
T2
T1
t1 t3 t4 t5Enter CS1
t2
Block
Leave CS1
Enter CS1
T1 is blocked by T3 for a long time, T2 prolongs the blocking!
April 19, 2023 IL2206 Embedded Systems 50
Possible solutions for priority inversion
Critical sections could be made non-preemtable May work for short critical sections
Critical sections are executed at the highest priority of any process that might use it
Research has proposed solutions in form of priority inheritance protocols such as Device that gets access to critical sections gets
highest priority
Priority Inversion will be discussed in more detail in IL2212 Embedded Software
Timer
Timers are an integral part of an embedded system
Hardware timers are available as peripheral components to an embedded processor core
Many real-time operating systems provide soft timers as services to the user MicroC/OS-II offers soft timers from version 2.81
Usually multiple soft timers can run at the same time
April 19, 2023 IL2206 Embedded Systems 51
Soft Timer
A soft timer can usually be operated in two modes Periodic:
Timer runs for some period and restarts One-Shot:
Timer runs once for a defined period Action can be defined to be executed, when
period is expired (callback function)
April 19, 2023 IL2206 Embedded Systems 52
Soft Timer
Soft timer needs to be triggered by an external signal (Timer Tick)
The resolution of the soft timer depends on the frequency of the external timer tick
April 19, 2023 IL2206 Embedded Systems 53
Soft Timer
Timer Tick
Periodic Tasks
Soft timers can be used to implement periodic tasks Periodic timer signals a
semaphore every time interval
Task waits for semaphore after operation
April 19, 2023 IL2206 Embedded Systems 54
T1 = (4,8,8); T2 = (1,3,3)
Timer 1(Period = 8)
Timer 2(Period = 2)
B
B
Task1
Task2
IL2206 Embedded Systems 56
MicroC/OS-IIHardware/Software Architecture
Application Software (Your Code)!
MicroC/OSII(Processor-Independent Code)
OS_CORE.C, OS_FLAG.C,OS_MBOX.C, OS_MEM.C,OS_MUTEX.C, OS_Q.C,OS_SEM.C, OS_TASK.COS_TIME.C, uCOS_II.C
uCOS_II.H(Do not touch!)
MicroC/OSII(Application-Specific)
OS_CFG.HINCLUDES.H(APP_CFG.H)
Change parameters in OS_CFG.H tocustomize MicroC/OS-II
MicroC/OS-II Port (Processor-Specific Code)OS_CPU.H, OS_CPU_A.ASM, OS_CPU_C.C
Software
HardwareCPU TimerApril 19, 2023
IL2206 Embedded Systems 57
Task States in MicroC/OS-II
TaskWaiting
TaskDormant
TaskReady
TaskRunning
ISRRunning
OSFlagPend()OSMboxPend()OSMutexPend()
OSQPend()OSSemPend()
OSTaskSuspend()OSTimeDly()
OSTimeDlyHMSM()
Interrupt
OSIntExit()
OSFlagPost()OSMboxPost()
OSMutexPost()OSQPost()
OSSemPost()OSTaskResume()
OSTimeDlyResume()OSTimeTick()
OSTaskDel()
OSTaskDel()
OSTaskDel()
OSTaskCreate()
OSStart()OSIntExit()
OS_TASK_SW()
Task is preempted
Not all RTOS functions are shown in the diagram!
April 19, 2023
IL2206 Embedded Systems 58
Initializing MicroC/OS-II In order to initialize MicroC/OS-II follow the following
template:void main(void){
OSInit();/* Create Startup task (here TaskStart()
with OSTaskCreateExt())*/OSStart();
} NOTE: At least in earlier versions of the Altera Port, the
function OSInit() should not be executed before OSStart()
April 19, 2023
IL2206 Embedded Systems 59
OSInit()
OSInit() initializes all MicroC/OS-II variables and data
structures OSInit() creates the idle task, which is always
ready to run and executes on priority OS_LOWEST_PRIO
OSInit() also creates the statistic task OS_Task_Stat() and makes it ready to run, if OS_TASK_STAT_EN and OS_TASK_CREATE_EXT_EN are set to 1 in OS_CFG.H
April 19, 2023
IL2206 Embedded Systems 60
OSStart()
OSStart() starts multitasking Before you execute OSStart() at least one
task shall be created
April 19, 2023
IL2206 Embedded Systems 61
Statistics in MicroC/OS-II In order to get statistics about CPU Utilization, the statistics
task must be initialized Follow the following template:
void TaskStart (void *pdata){
/* Install and initialize ucosII ticker */
OSStatInit(); /* Initialize statistics task */
/* Create your application task(s) */while (1) {
/* Code for TaskStart()*/}
}
April 19, 2023
IL2206 Embedded Systems 62
Statistics Task OSStatInit() determines how high the idle counter
(OSIdleCtr) can count, if no other task in the application is executing
OSStatInit() delays itself (TaskStart()) for one full second During that time OSIdleCtr is continuously incremented
After one second TaskStart() (still in OSStatInit() is resumed) and the value that OSIdleCtr has reached is stored in OSIdleCtrMax
Further on, every second, the new value of the idle counter is copied into the global variable OSIdleCtrMax
April 19, 2023
IL2206 Embedded Systems 63
Statistics Task
You can access the variables OSCPUUsage OSIdleCtr OSIdleCtrMax
April 19, 2023
IL2206 Embedded Systems 64
Stack Statistics OSTaskStkChk() determines a task’s statistics
calculates amount of free and used stack space Example:
void Task (*pdata){
OS_STK_DATA stk_data;while(1) {
err = OSTaskStkChk(10, &stk_data);if (err = OS_NO_ERR) { printf(“Free: %d\n”, stk_data.OSFree; printf(“Used: %d\n”, stk_data.OSUsed;
}}
Priority
April 19, 2023
IL2206 Embedded Systems 65
Memory Management
MicroC/OS-II provides a memory management mechanism that is based on fixed-sized memory blocks from a partition of a
contiguous memory area Allocation and deallocation of these blocks is done in
constant time and is deterministic Memory management does not lead to fragmentation
In contrast standard C-functions like malloc() och free() have a non-deterministic execution time can lead to fragmentation
April 19, 2023
IL2206 Embedded Systems 66
Memory Management
A memory partition consists of several blocks of the same size
Several partitions may exist
Functions: OSMemCreate() OSMemGet() OSMemPut() OSMemQuery()
Block
Partition
April 19, 2023
IL2206 Embedded Systems 67
Creating a Memory Partition
Creating a partition with 10 Blocks of 16 BytesOSMem *MemBuf;INT8U MemPart[10][16]; /* INT8U is one byte */
void main(void){
INT8U err;OSInit();…MemBuf = OSMemCreate(MemPart, 10, 16, &err);…OSStart();
}
April 19, 2023
IL2206 Embedded Systems 68
Accessing the memory
The function OSMemGet() obtains a memory block, if there is a free memory block available
The memory block shall be returned using the function OSMemPut()
You must be aware of the size of the memory blocks, so that the data you want to use fits into the memory block
April 19, 2023
IL2206 Embedded Systems 69
Statistics: Usage of Memory The function OSMemQuery() can be used to
determine the number of blocks that are in useOSMEM *MemBufvoid Task(void *pdata){
OS_MEM_DATA mem_data;while(1) {
err = OSMemQuery(MemBuf, &mem_data); printf(“Free: %d\n”, mem_data.OSNFree); printf(“Used: %d\n”, mem_data.OSNUsed);}
}
April 19, 2023
IL2206 Embedded Systems 70
Interrupts
In MicroC/OS-II the code for an interrupt service routine shall usually be written in assembler
As the Altera HAL provides an abstraction of the hardware, the code for the ISR can also be written in C (as done in the Embedded Systems course)
Interrupts are also initialized in the same way as done in the Embedded Systems course
April 19, 2023
IL2206 Embedded Systems 71
Interrupts The beginning of the ISR shall be declared by OSIntEnter()
The end of the ISR shall be declared by OSIntExit()
static void handle_button_interrupts(void* context, alt_u32 id){ volatile int* edge_capture_ptr = (volatile int*) context; OSIntEnter(); // Read the edge capture register on the button PIO *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE); … OSIntExit();}
April 19, 2023
IL2206 Embedded Systems 72
Error Handling
MicroC/OS-II functions usually return an error code
Please check the return error code, so that you are able to find mistakes when the occur
err = OSTaskStkChk(10, &stk_data);
if (err = OS_NO_ERR) {
printf(“Free: %d\n”, stk_data.OSFree;
printf(“Used: %d\n”, stk_data.OSUsed;
}
April 19, 2023
IL2206 Embedded Systems 73
Configuration
The application specific file OS_CFG.H defines which configurable elements shall be available in your project
It consists of a lot of #define statements, where you can define settings and select available mechanisms
In the Nios II IDE you can instead select features in the properties for the system library
Your settings will affect the size of the code!
April 19, 2023
IL2206 Embedded Systems 74
Configuration Extract of OS_CFG.H
#define OS_LOWEST_PRIO 63 /* Defines the lowest priority that can be
assigned ... *//* ... MUST NEVER be higher than 63 (since V2.8x:
254)! */#define OS_TASK_STAT_EN 1 /* Enable (1) or Disable(0) the statistics task */#define OS_TICKS_PER_SEC 1 /* Set the
number of ticks in one second */#define OS_MEM_EN 1 /* Enable
(1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_QUERY_EN 1 /* Include code for OSMemQuery() */
April 19, 2023
IL2206 Embedded Systems 75
Coding Conventions
There exists a huge amount of different coding conventions for C/C++
It is very important to write readable and well-documented programs, so that your work can be reused Use self-explanatory variable and function names
e.g. lineNumber instead of ln Use indentation to make the program readable Document the program so that reader understand without
difficulties Use comments to separate parts of the program
April 19, 2023
IL2206 Embedded Systems 76
Coding Conventions
We expect from all students in the course that your programs are well-documented and readable
If you are not sure, how to write readable and well-documented code, search web for the term “c coding conventions”
April 19, 2023
IL2206 Embedded Systems 77
C Preprocessor
The C preprocessor allows to use compiler directives like #ifdef or #ifndef
You can use these directives to easily remove debugging
statements from your code define code segments for a
particular environment More information on the
web!
#define ALTERA
#define DEBUG
…
#ifdef DEBUG
printf(“State is %d\n”, s);
#endif
#ifndef ALTERA
OSInit()
#endif
April 19, 2023
April 19, 2023 IL2206 Embedded Systems 78
MicroC/OS-II
supports Semaphores Message Queues Events
Please check the documentation in the Labrosse book (chapter 16), which is accessible via Ping-Pong!
April 19, 2023 IL2206 Embedded Systems 79
MicroC-OSIITask Creation
For each task a task stack must be defined, where local variables are stored. Stacksize is measured in bytes.
Each task is assigned a priority, where 1 is the highest priority
It is not allowed to assign two tasks the same priority
/* Definition of Task Stacks */
/* Stack grows from HIGH to LOW memory */
#define TASK_STACKSIZE 2048
OS_STK task1_stk[TASK_STACKSIZE];
OS_STK task2_stk[TASK_STACKSIZE];
OS_STK task3_stk[TASK_STACKSIZE];
/* Definition of Task Priorities */
#define TASK1_PRIORITY 6 // highest priority
#define TASK2_PRIORITY 10
#define TASK3_PRIORITY 14 // lowest priority
April 19, 2023 IL2206 Embedded Systems 80
MicroC-OSIITask Definition
The RTOS is started from the application program The function OSTaskCreaOSTaskCreatExtte creates a new
task (to get statistics you have to use this function!) OSStart() starts the RTOS and stays in an infinite loopint main(void){ OSTaskCreate(task1, // Pointer to task code NULL, // Pointer to argument that is // passed to task (void *)&task1_stk[TASK_STACKSIZE-1], // Pointer to top of task stack TASK1_PRIORITY // Desired Task priority
); … OSStart();
April 19, 2023 IL2206 Embedded Systems 81
MicroC-OSIIA simple Task A task can either run only once or be an infinite loop Since the task can be preempted reentrant functions shall be used The function OSTimeDlyHMSM makes a context switch and makes
the task ready after the specified delay
void task1(void* pdata){ while (1) {
printf(”Hello from Task 1\n”); OSTimeDlyHMSM(0, 0, 5, 0); // Context Switch to next task // Task will go to the ready state // after the specified delay }}
April 19, 2023 IL2206 Embedded Systems 82
MicroC-OSIISemaphores
A semaphore has to be declared as an OS_EVENT In the main program the semaphore must be
created by OSSemCreate(n), where n is the number of ”keys”, which are available from start.
OS_EVENT *SharedOutput;…int main(void){ SharedOutput = OSSemCreate(1); // one key available from start …
April 19, 2023 IL2206 Embedded Systems 83
MicroC-OSIISemaphores
Accessing the semaphore is done by OSSemPend()
Releasing the semaphore is done by OSSemPost()
void task1(void* pdata){ INT8U err; … OSSemPend(SharedOutput, 0, &err); // Critical Section OSSemPost(SharedOutput); … }
April 19, 2023 IL2206 Embedded Systems 84
MicroC-OSII and Altera
MicroC-OSII is integrated into the Altera Nios II IDE … but not in the evaluation version
It works also with the Instruction Set Simulator