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()
 1 // 2: Number of Log entries.
 2 #define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64
 3 //----------------------------------------------------------------------------
 4 // 3: Number of tasks
 5 #define NUMBER_OF_TASKS                         8  // 1 to 255
 6 //----------------------------------------------------------------------------
 7 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
 8 //    Defaults to number of tasks, as each task should have aa least one job;
 9 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
10 #define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2
11 //----------------------------------------------------------------------------
12 // 5: Number of Mutexes
13 #define NUMBER_OF_MUTEXES                       1  // 0 to 63
14 //----------------------------------------------------------------------------
15 // 6: Number of Semaphores
16 #define NUMBER_OF_SEMAPHORES                    1  // 0 to 63
17 //----------------------------------------------------------------------------
18 // 7: Number of Data Qs
19 #define NUMBER_OF_DATAQS                        1  // 0 to 63
20 //----------------------------------------------------------------------------
21 // 8: LOG data array size
22 #define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual
23 //----------------------------------------------------------------------------
24 // 9: FIXED data array size
25 #define FIXED_DATA_ARRAY_SIZE_U32S              0x59// Calculated value. Read manual
26 //----------------------------------------------------------------------------
27 // 10: DYNAMIC data array size
28 #define DYN_DATA_ARRAY_SIZE_U32S                0x18D// Calculated value. Read manual
29 //----------------------------------------------------------------------------
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()