Embedded C programming Tutorial , Keil C ide , microsoftware.gr
Keil CRC and CAN BUS codes.
1. Shift led left
2.It's time for DAVE! <7/6/13>
3.Capture/Compare unit 6
6.Analog converter
7.Memory manipulation routines
8. Recursion
9.Understanding interrupt priorities using CAPCOM2 module
10. POINTERS TO FUNCTION <4/7/13>,<4/28/13>
11.Memory models, memory types
12. The heap , part 1
13. The heap , part 2
14. The heap , part 3
15. Structure example
16. Nested structures, Array of structures.
17. Passing array of structures to function using pointers.<1/5/13>
18. Self Referential Structures
20. Linked list example
21. Circular linked list
22. Union example
23. Enumeration example
24. Watchdog timer example
25. Void pointer example <7/4/13>
26. The sieve of Eratosthenes
27. The stack
28. Union and bitfields as flags example. <6/23/13>
29. Look up table example. <8/11/13>
30. Seven segment display multiplexing -four digits with dot- example
31. LCD character display example - JHD162A
32. Hash table introduction example <8/27/14>
33. Array of Linked Lists example
34. Array of Linked lists-more functions included.
35. Hash table construction,searching and printing.
36. Fininte state machines- a first approach.
37. Finite state machines- two events example.
38. SPI port and an AT25128 serial eeprom hardware.
40. Definite Integral Calculator for Scientists, Engineers...
41 .Hamming distance of a CRC polynomial
42. Linux play starting.
43. Galois GF(2^4) Finite Field
44. Construct your own time triggered real time operating system.
44. Construct your own time triggered real time operating system.

Tme triggered real time operating system.

At a time triggered real time operating syste we put the order of execution of tasks in a scheduler and the execution of the scheduler starts after a timer overlow interrupt . A timer tick "fires" the scheduler.
At this example the timer T2 of the microcontroller "fires" the scheduler every 1 sec , a big time set for educational purpose, in reallity it is some miliseconds only.
We can configure the tasks in such a way that ,may be, not all of the tasks to be executed at every "fire" of the scheduler. We will use three tasks , but you can add more.

Every task is a structure like:

 typedef struct task {
unsigned long period; // Rate at which the task should tick
unsigned long delay; // Time delay of the first execution
void (*tickfet)(void); // Function to call for task's tick
} task;
 task tasks[3];

The three tasks are:

void T0() {

 // Task: Toggle an output           
void T1() {
P1L_P1 = ~P1L_P1;

void T2() {
 printf(" %s ", "abc");

First configuration of the tasks.

tasks[0]= (period=1 tick, delay=1 tick,  tickfet= &T0)

tasks[1]= (period=2 tick, delay=2 tick,  tickfet= &T1)

tasks[2]= (period=3 tick, delay=2 tick, tickfet= &T2)

At the begging, the first time of execution of the scheduler.
When the delay of a task is equal to 1 then the task is ready to run. When delay=2 then the task
is ready to run at the second tick etc.
After it, the delay of its one of the tasks is equal to the corresponding period.

A function that controlls all of the above is the:

void SCH_Dispatch_Tasks(void)
int Index;
int Update_required = 0;
// Need to check for a timer interrupt since this
// function was last executed (in case idle mode is not being used)
if (t > 0)
 Update_required =1;
while (Update_required)
// Go through the task array
for (Index = 0; Index < 3; Index++)
// Check if there is a task at this location
if (tasks[Index].tickfet)
if (--tasks[Index].delay == 0)
// The task is due to run 

(*tasks[Index].tickfet)(); // Run the task
if (tasks[Index].period != 0)
// Schedule period tasks to run again
tasks[Index].delay = tasks[Index].period;
// Delete one-shot tasks
tasks[Index].tickfet = 0;

The main() function is the:

void main(void)
 // USER CODE BEGIN (Main,2)
   unsigned char i=0 ;
 // USER CODE BEGIN (Main,4)
tasks[i].period = 1;
tasks[i].delay = 1;                         
tasks[i].tickfet = &T0;
tasks[i].period = 2;                                        
tasks[i].delay = 2;                            
tasks[i].tickfet = &T1;

tasks[i].period = 3;                                        
tasks[i].delay = 2;                            
tasks[i].tickfet = &T2;
while(1) {                           
 GPT1_vLoadTmr_GPT1_TIMER_2((unsigned int)tasksPeriodGCD)   ;
   GPT1_vStartTmr_GPT1_TIMER_2( );

And the overflow interrupt of T2 timer is :

void GPT1_viTmr2(void) interrupt T2INT
 // USER CODE BEGIN (Tmr2,2)
// Note that an interrupt has occurred
t++ ;

Lts to see now what will be happened at the tasks for every one of the "firing" ticks of the scheduler:

First tick.

tasks[0]  EXECUTED, tasks[1] NOT EXECUTED, tasks[2] NOT EXECUTED.
new contents at the tasks:
tasks[0](1,1,&T0)    tasks[1](2,1,&T1)   tasks[2](3,1,&T2)

Next tick.
tasks[0] EXECUTED, tasks[1] EXECUTED, tasks[2]  EXECUTED.
new contents at the tasks:
tasks[0](1,1,&T0) tasks[1](2,2,&T1) tasks[2](3,3,&T2)

Next tick.
tasks[0] EXECUTED, tasks[1] NOT EXECUTED, tasks[2]  NOT EXECUTED.
new contents at the tasks:
tasks[0](1,1,&T0) tasks[1](2,1,&T1) tasks[2](3,2,&T2)

Next tick.
tasks[0] EXECUTED, tasks[1]  EXECUTED, tasks[2] NOT EXECUTED.
new contents at the tasks:
tasks[0](1,1,&T0) tasks[1](2,2,&T1) tasks[2](3,1,&T2)

Next tick.
tasks[0] EXECUTED, tasks[1]NOT  EXECUTED, tasks[2]  EXECUTED.
new contents at the tasks:
tasks[0](1,1,&T0) tasks[1](2,1,&T1) tasks[2](3,3,&T2)


The complete project is         here