OCEOS Tutorials
Tutorials
Introduction
This section presents some typical real-time tasks and how they can be addressed using OCEOS.
Getting started
Section 9.5 provides guidance on how to structure an OCEOS application. The file asw.c provided with OCEOS is a simple example.
The directives to initialise and start OCEOS are:
- application_init – Initialise fixed data and start system timer(s)
- oceos_task_create - Create task setting priority, no of jobs, ..etc.
- oceos_init_finish – Initilise dynamic data area
- oceos_start – Start the scheduler and pass control to first task
After steps 1 to 4 above tasks implement application functionality. If mutexes, semaphores, or dataqs are required they are also created at step 2.
Note: it is mandatory to create the number of mutexes, semaphores, and dataqs declared otherwise oceos_init_finish() will return an error.
Tutorials
Tutorial 1 – Starting tasks
This exercise demonstrates starting tasks with different priorities.
- Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.
- Each task outputs a message when it starts, another message when it exits.
- Start OCEOS with the low priority task.
- This starts the high priority task and then exits.
- The high priority task starts the low priority tasks and exits.
For code example see below.
1 /*
2 *********************************************************************************************************
3 * OCEOS
4 * Real-Time Operating System
5 * for
6 * GR716 Microcontroller
7 *
8 * User Manual Section 11 Example
9 *
10 * (c) Copyright 2020, O.C.E. Technology
11 * All Rights Reserved
12 *
13 * File : tut1.c
14 ********************************************************************************************************
15 */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include "tut1.h" // application header
19
20 /* N.B. Application header is included first */
21 #include "oceos_config.h" // OCEOS header for this application
22
23
24
25
26 /*
27 * Application specific
28 *
29 */
30 extern U32_t fixed_data[]; // will be in data segment. Should this be in oceos.h
31
32 int main(void) {
33 int status;
34
35 /*
36 * Initialise the application configuration and OCEOS
37 *
38 * This application function creates the application configuration
39 * and passes it to oceos_init(), which initialises the fixed data
40 * and enables the system log
41 */
42 if ( !application_init()) {
43 //LOG
44 return -1;
45 }
46
47 // Create Main task to
48 if ( oceos_task_create(
49 t_0, // taskID, used as index, must be in range 0 to 254
50 100, // priority, must be in range 1 to 254, lower value is higher priority
51 100, // threshold, must be in range 1 to task priority
52 2, // jobs_max, must be in range 1 to 15
53 0, // FALSE -> floating point hardware not used by task
54 1, // FALSE -> task initially not enabled
55 fun0, // main body of task
56 nullFun, // task end function
57 0, // time_deadline, must finish no later than this after start, 0 => ignore
58 0 // minimum time expected between start requests, 0 => no restriction
59 ) != SUCCESSFUL )
60 return 1;
61
62 if ( oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)!= SUCCESSFUL )
63 return 2;
64
65 /*
66 * Finish initialising OCEOS and setting up the fixed data
67 */
68 status = oceos_init_finish();
69 if(SUCCESSFUL != status){
70 return 3;
71 } // if
72
73 /*
74 * Start OCEOS scheduling
75 *
76 * The OCEOS fixed data provides all the information required.
77 *
78 * If a valid task is specified, it is started and passed the pointer.
79 * Otherwise the system is put in sleep mode
80 */
81 status = oceos_start(fixed_data, t_1, (void *)nullPtr); // Start OCEOS with lower prioroty task
82 return status;
83 } // main
84
85
86 /*
87 * Application code functions, functions declared in asw.h
88 */
89 void fun0(void * ptr){
90 printf ("Entered high priority task\n");
91 oceos_task_start(t_1,ptr);
92 printf ("Leaving high priority task\n");
93 return;
94 } // fun0()
95
96
97 void fun1(void * ptr){
98 printf ("Entered low priority task\n");
99 oceos_task_start(t_0,ptr);
100 printf ("Leaving low priority task\n");
101 return;
102 } // fun1()
Tutorial 2 – Using a mutex
This exercise will familiarise the developer with the use a mutexes.
- Two tasks as before.
- One mutex. Note the priority ceiling of the mutex..
- Both tasks output message when they get the mutex and when they return it
- Start OCEOS with the low priority task
- This grabs mutex, then starts high priority task
- Low priority task returns mutex then exits
- High priority task returns mutex, start low priority task and exits
For code example see example below:
1 /*
2 *********************************************************************************************************
3 * OCEOS
4 * Real-Time Operating System
5 * for
6 * GR716 Microcontroller
7 *
8 * User Manual Section 11 Example 2
9 *
10 * (c) Copyright 2020, O.C.E. Technology
11 * All Rights Reserved
12 *
13 * File : tut2.c
14 ********************************************************************************************************
15 */
16 #include "tut2.h" // application header
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 /* N.B. Application header is included first */
22 #include "oceos_config.h" // OCEOS header for this application
23
24 /*
25 * Application specific
26 *
27 */
28 extern U32_t fixed_data[]; // will be in data segment. Should this be in oceos.h
29
30 int main(void) {
31 int status;
32
33 /*
34 * Initialise the application configuration and OCEOS
35 *
36 * This application function creates the application configuration
37 * and passes it to oceos_init(), which initialises the fixed data
38 * and enables the system log
39 */
40 if ( !application_init()) {
41 //LOG
42 return -1;
43 }
44
45 // Create Main task to
46 if ( oceos_task_create(
47 t_0, // taskID, used as index, must be in range 0 to 254
48 100, // priority, must be in range 1 to 254, lower value is higher priority
49 100, // threshold, must be in range 1 to task priority
50 2, // jobs_max, must be in range 1 to 15
51 0, // FALSE -> floating point hardware not used by task
52 1, // FALSE -> task initially not enabled
53 fun0, // main body of task
54 nullFun, // task end function
55 0, // time_deadline, must finish no later than this after start, 0 => ignore
56 0 // minimum time expected between start requests, 0 => no restriction
57 ) != SUCCESSFUL )
58 return 1;
59
60 if ( oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)!= SUCCESSFUL )
61 return 2;
62
63 if ( oceos_mutex_create(m_0, 100)!= SUCCESSFUL ) // Create mutex with ceiling of highest priority task using it
64 return 3;
65
66
67 /*
68 * Finish initialising OCEOS and setting up the fixed data
69 */
70 status = oceos_init_finish();
71 if(SUCCESSFUL != status){
72 return 4;
73 } // if
74
75 /*
76 * Start OCEOS scheduling
77 *
78 * The OCEOS fixed data provides all the information required.
79 *
80 * If a valid task is specified, it is started and passed the pointer.
81 * Otherwise the system is put in sleep mode
82 */
83 status = oceos_start(fixed_data, t_1, (void *)nullPtr); // Start OCEOS with lower prioroty task
84 return status;
85 } // main
86
87
88 /*
89 * Application code functions, functions declared in asw.h
90 */
91 void fun0(void * ptr){
92 if (oceos_mutex_wait(m_0) != SUCCESSFUL) {
93 printf ("Error from high priority task getting mutex\n");
94 } else {
95 printf ("high priority task got mutex\n");
96 }
97 oceos_task_start(t_1,ptr); // Start lower priority task
98
99 if (oceos_mutex_signal(m_0) != SUCCESSFUL) {
100 printf ("Error from high priority task releasing mutex\n");
101 } else {
102 printf ("High priority task released mutex\n");
103 }
104 return;
105 } // fun0()
106
107
108 void fun1(void * ptr){
109 if (oceos_mutex_wait(m_0) != SUCCESSFUL) {
110 printf ("Error from low priority task getting mutex\n");
111 } else {
112 printf ("Low priority task got mutex\n");
113 }
114 oceos_task_start(t_0,ptr); // Start higher priority task
115
116 if (oceos_mutex_signal(m_0) != SUCCESSFUL) {
117 printf ("Error from low priority task releasing mutex\n");
118 } else {
119 printf ("Low priority task released mutex\n");
120 }
121 return;
122 } // fun1()
Tutorial 3 – Using Semaphores
Semaphores can be used to synchronise task actions as in this exercise.
- Three tasks this time, one high priority and the other two with the same lower priority
- Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’
- First task starts second and third tasks
- Second task loops
- wait_restart spaces
- signal items
- Output ‘item done’ message
- Third task loops
- wait_restart items
- Output ‘got item’ message
- signal spaces
For code example see below:
1 /*
2 *********************************************************************************************************
3 * OCEOS
4 * Real-Time Operating System
5 * for
6 * GR716 Microcontroller
7 *
8 * User Manual Section 11 Example 3
9 *
10 * (c) Copyright 2020, O.C.E. Technology
11 * All Rights Reserved
12 *
13 * File : tut3.c
14 ********************************************************************************************************
15 */
16 #include "tut3.h" // application header
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 /* N.B. Application header is included first */
22 #include "oceos_config.h" // OCEOS header for this application
23
24 /*
25 * Application specific
26 *
27 */
28 extern U32_t fixed_data[]; // will be in data segment. Should this be in oceos.h
29
30 int main(void) {
31 int status;
32 /*
33 * Initialise the application configuration and OCEOS
34 *
35 * This application function creates the application configuration
36 * and passes it to oceos_init(), which initialises the fixed data
37 * and enables the system log
38 */
39 if ( !application_init()) {
40 //LOG
41 return -1;
42 }
43 // Create Main task to
44 if ( oceos_task_create(
45 t_0, // taskID, used as index, must be in range 0 to 254
46 10, // priority, must be in range 1 to 254, lower value is higher priority
47 10, // threshold, must be in range 1 to task priority
48 1, // jobs_max, must be in range 1 to 15
49 0, // FALSE -> floating point hardware not used by task
50 1, // FALSE -> task initially not enabled
51 fun0, // main body of task
52 nullFun, // task end function
53 0, // time_deadline, must finish no later than this after start, 0 => ignore
54 0 // minimum time expected between start requests, 0 => no restriction
55 ) != SUCCESSFUL )
56 return 1;
57
58 if ( oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)!= SUCCESSFUL )
59 return 2;
60
61 if ( oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)!= SUCCESSFUL )
62 return 3;
63
64 if ( oceos_sem_create(items, 10, 0, 2, TRUE) != SUCCESSFUL ) // items semaphore with max permits of 10, initial permits of 0, max jobs 2
65 return 4;
66
67 if ( oceos_sem_create(spaces, 10, 4, 2, TRUE) != SUCCESSFUL ) // spaces semaphore with max permits of 10, initial permits of 4, max jobs 2
68 return 4;
69 /*
70 * Finish initialising OCEOS and setting up the fixed data
71 */
72 status = oceos_init_finish();
73 if(SUCCESSFUL != status){
74 return 6;
75 } // if
76 /*
77 * Start OCEOS scheduling
78 *
79 * The OCEOS fixed data provides all the information required.
80 *
81 * If a valid task is specified, it is started and passed the pointer.
82 * Otherwise the system is put in sleep mode
83 */
84 status = oceos_start(fixed_data, t_0, (void *)nullPtr); // Start OCEOS with task to start other tasks
85 return status;
86 } // main
87
88 /*
89 * Application code functions, functions declared in asw.h
90 */
91 void fun0(void * ptr){
92 oceos_task_start(t_1,ptr); // Start consumer task
93 oceos_task_start(t_2,ptr); // Start consumer task
94 } // fun0()
95
96 void fun1(void * ptr){
97 while (1){ // loop forever
98 if (oceos_sem_wait_restart_timeout(items,0) != SUCCESSFUL) {
99 printf ("Error from task t_0 task waiting items\n");
100 }
101 printf ("Got item\n");
102 if (oceos_sem_signal(spaces) != SUCCESSFUL) {
103 printf ("Error from task t_0 signalling spaces\n");
104 }
105 }
106 } // fun0()
107
108 void fun2(void * ptr){
109 while (1){ // loop forever
110 if (oceos_sem_wait_restart_timeout(spaces,0) != SUCCESSFUL) {
111 printf ("Error from task t_1 task waiting spaces\n");
112 }
113 if (oceos_sem_signal(items) != SUCCESSFUL) {
114 printf ("Error from task t_1 signalling items\n");
115 } else {
116 printf ("Item done\n");
117 }
118 }
119 return;
120 } // fun1()
Tutorial 4 – Timer interrupt starts task
This exercise introduces the use of timer interrupts.
- Create one task
- Set a timer to interrupt every 2 seconds
- Set timer handler to start task
- Task outputs message, then exits
For code example see below:
1 /*
2 *********************************************************************************************************
3 * OCEOS
4 * Real-Time Operating System
5 * for
6 * GR716 Microcontroller
7 *
8 * User Manual Section 11 Example 4
9 *
10 * (c) Copyright 2020, O.C.E. Technology
11 * All Rights Reserved
12 *
13 * File : tut4.c
14 ********************************************************************************************************
15 */
16 #include "tut4.h" // application header
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 /* N.B. Application header is included first */
22 #include "oceos_config.h" // OCEOS header for this application
23 #include <bcc/regs/gptimer.h>
24
25 #include "oceos_interrupt.h"
26 /*
27 * Application specific
28 *
29 */
30 extern U32_t fixed_data[]; // will be in data segment. Should this be in oceos.h
31
32 struct gptimer_regs *timer_regs = (void *)OCEOS_TA_TIMER_ADDRESS;
33 struct gptimer_timer_regs *task_timer;
34 struct bcc_isr_node node;
35
36 int main(void) {
37 int status;
38 /*
39 * Initialise the application configuration and OCEOS
40 *
41 * This application function creates the application configuration
42 * and passes it to oceos_init(), which initialises the fixed data
43 * and enables the system log
44 */
45 if ( !application_init()) {
46 //LOG
47 return -1;
48 }
49 // Create Main task to
50 if ( oceos_task_create(
51 t_0, // taskID, used as index, must be in range 0 to 254
52 10, // priority, must be in range 1 to 254, lower value is higher priority
53 10, // threshold, must be in range 1 to task priority
54 1, // jobs_max, must be in range 1 to 15
55 0, // FALSE -> floating point hardware not used by task
56 1, // FALSE -> task initially not enabled
57 fun0, // main body of task
58 nullFun, // task end function
59 0, // time_deadline, must finish no later than this after start, 0 => ignore
60 0 // minimum time expected between start requests, 0 => no restriction
61 ) != SUCCESSFUL )
62 return 1;
63
64 if ( oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)!= SUCCESSFUL )
65 return 2;
66 /*
67 * Finish initialising OCEOS and setting up the fixed data
68 */
69 status = oceos_init_finish();
70 if(SUCCESSFUL != status){
71 return 3;
72 } // if
73 /*
74 * Start OCEOS scheduling
75 *
76 * The OCEOS fixed data provides all the information required.
77 *
78 * If a valid task is specified, it is started and passed the pointer.
79 * Otherwise the system is put in sleep mode
80 */
81 status = oceos_start(fixed_data, t_0, (void *)nullPtr); // Start OCEOS
82 return status;
83 } // main
84
85 /*
86 * Application code functions, functions declared in asw.h
87 */
88 void fun0(void * ptr){
89 //set up timer and add handle
90 task_timer = &timer_regs->timer[3];
91 task_timer->ctrl = 0x0;
92 enum DIRECTIVE_STATUS ret = 0;
93 #ifdef TARGET_PM
94 node.source = 9;
95 #endif
96 #ifdef TARGET_GR716
97 node.source = 12;
98 #endif
99 node.handler = start_task;
100 node.arg = ptr;
101 ret = oceos_interrupt_handle_register(&node);
102 if (SUCCESSFUL != ret) {
103 printf("ERROR :: Failed to add ISR handler\n");
104 }
105 #ifdef TARGET_PM
106 bcc_int_unmask(9);
107 #endif
108 #ifdef TARGET_GR716
109 bcc_int_unmask(12);
110 #endif
111 task_timer->reload = 0x2DC6C0; // 3 seconds
112 task_timer->counter = 0x2DC6C0; // 3 seconds
113 task_timer->ctrl = GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | GPTIMER_CTRL_IE; // 0x1 | (1 << 1) | (1 << 3);
114
115 // The interrupt shoud keep starting t_1 so this task can exit
116 } // fun0()
117 /*
118 * Handler for timer interrupt
119 */
120 void start_task(void *arg, int source){
121 oceos_task_start(t_1,arg);
122 }
123
124 void fun1(void * ptr){
125 printf ("Task started\n");
126 } // fun1()