OCEOS Tutorials

From wiki
Jump to navigation Jump to search

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:

  1. application_init – Initialise fixed data and start system timer(s)
  2. oceos_task_create - Create task setting priority, no of jobs, ..etc.
  3. oceos_init_finish – Initilise dynamic data area
  4. 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.

  1. 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.
  2. Each task outputs a message when it starts, another message when it exits.
  3. Start OCEOS with the low priority task.
  4. This starts the high priority task and then exits.
  5. The high priority task starts the low priority tasks and exits.

For code example see below.

tut.h

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
17  */
18 #ifndef TUT1_H_
19 #define TUT1_H_
20 
21 /* Sample Task names - all here start with t_ to help avoid name confusion */
22 enum TASK_NAME{
23     t_0,                 // High priority task
24     t_1                  // Low priority task
25 };
26 
27 char* nullPtr = "";			// Need pointer to pass to oceos_start
28 void (*nullFun)(void *);	// Null function
29 
30 /*
31  * APPLICATION FUNCTION DECLARATIONS
32  */
33 void fun0(void *);
34 void fun1(void *);
35 
36 #endif /* TUT1_H_ */

oceos_config.h

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #ifndef INCLUDE_OCEOS_CONFIG_H_
 19 #define INCLUDE_OCEOS_CONFIG_H_
 20 
 21 // 1: Includes OCEOS main header file
 22 #include "oceos.h"
 23 //----------------------------------------------------------------------------
 24 // 2: Number of Log entries.
 25 #define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64
 26 //----------------------------------------------------------------------------
 27 // 3: Number of tasks
 28 #define NUMBER_OF_TASKS                         2  // 1 to 255
 29 //----------------------------------------------------------------------------
 30 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
 31 //    Defaults to number of tasks, as each task should have aa least one job;
 32 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
 33 #define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2
 34 //----------------------------------------------------------------------------
 35 // 5: Number of Mutexes
 36 #define NUMBER_OF_MUTEXES                       0  // 0 to 63
 37 //----------------------------------------------------------------------------
 38 // 6: Number of Semaphores
 39 #define NUMBER_OF_SEMAPHORES                    0  // 0 to 63
 40 //----------------------------------------------------------------------------
 41 // 7: Number of Data Qs
 42 #define NUMBER_OF_DATAQS                        0  // 0 to 63
 43 //----------------------------------------------------------------------------
 44 // 8: LOG data array size
 45 #define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual
 46 //----------------------------------------------------------------------------
 47 // 9: FIXED data array size
 48 #define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual
 49 //----------------------------------------------------------------------------
 50 // 10: DYNAMIC data array size
 51 #define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual
 52 //----------------------------------------------------------------------------
 53 // 11: Timed Actions
 54 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field
 55 //----------------------------------------------------------------------------
 56 // 12: Log entries base 2
 57 #define CS_LOG_DEF_ENTRIES_BASE2                0
 58 //----------------------------------------------------------------------------
 59 // 13: OCEOS stack start Address
 60 #define OCEOS_STACK_START_ADDRESS               0
 61 //----------------------------------------------------------------------------
 62 // 14: OCEOS stack end address
 63 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0
 64 //----------------------------------------------------------------------------
 65 /**
 66  * Target specific configurations
 67  */
 68 /*
 69  * ARM specific configurations
 70  */
 71 #ifdef __SAM3X8E__
 72 #ifndef BSP_SYSFREQ
 73 #define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz
 74 #endif
 75 #endif
 76 #ifdef __SAMV71Q21__
 77 #ifndef BSP_SYSFREQ
 78 #define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz
 79 #endif
 80 #endif
 81 #ifdef __VA41620__
 82 #ifndef BSP_SYSFREQ
 83 #define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz
 84 #endif
 85 #endif
 86 //--------------------------------------------------------------------
 87 // User defined function to deal with system errors
 88 void oceos_on_error(void);
 89 //---------------------------------------------------------------------
 90 // User defined function to deal with log 2/3 full
 91 void oceos_on_full_log(void);
 92 //---------------------------------------------------------------------
 93 extern U32_t log_data[];
 94 extern U32_t fixed_data[];
 95 extern U32_t dynamic_data[];
 96 extern const unsigned int __oceos_bsp_sysfreq;
 97 /**
 98  * Initialize OCEOS with user configurations
 99  */
100 int application_init(void);
101 #endif /* INCLUDE_OCEOS_CONFIG_H_ */

oceos_config.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include "oceos_config.h"
 20 
 21 /*
 22  * OCEOS INTERNAL DATA STORAGE
 23  *
 24  * This application defines arrays to hold OCEOS internal data.
 25  * The array sizes are provided by DMON by running "oceos info" command:</br>
 26  *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>
 27  *  *Run DMON command "oceos info" to get size for each array.</br>
 28  *  *Update array sizes below
 29  */
 30 U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];
 31 
 32 U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment
 33 
 34 U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];
 35 
 36 const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO
 37 
 38 static BOOLE_t log_full_was_called = FALSE;
 39 
 40 /**
 41  * Must be defined if Application is using :
 42  *      Dataq with timeout
 43  *      Semaphore with timeout
 44  *      Timed Actions
 45  */
 46 /*
 47  * Set up the application configuration structure and pass it to oceos_init
 48  * (done this way the memory used for the structure is returned automatically)
 49  */
 50 
 51 int application_init(){
 52 
 53     /*
 54      * Create the application configuration structure
 55      */
 56     struct application_configuration           app_config = {0};
 57 
 58     /*
 59      * Fill in the application parameters
 60      */
 61     app_config.log_address                   = (adrs_t)log_data;              // required
 62     app_config.fixed_data_address            = (adrs_t)fixed_data;            // required
 63     app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required
 64 
 65     app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check
 66     app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check
 67 
 68     app_config.system_error_function         = &oceos_on_error;               // NULL => ignore
 69     app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore
 70     // used in setting up system log and fixed data array
 71     app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default
 72 
 73     app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1
 74     app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size
 75 
 76     app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;
 77     app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
 78     app_config.number_of_data_queues         = NUMBER_OF_DATAQS;
 79 
 80     app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
 81     app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
 82     app_config.use_oceos_system_time         = TRUE;
 83 
 84     // initialise OCEOS
 85     enum DIRECTIVE_STATUS status;
 86     status = oceos_init(app_config);
 87 
 88     if (SUCCESSFUL == status) {
 89         return 1;
 90     } else {
 91         printf("\n oceos_init failure\n");
 92         return -1;
 93     }   // else
 94 }   // application_init()
 95 /**
 96  * User to implement in case of system error;
 97  * Comment it out if not used and set field system_error_function in app_config to NULL
 98  */
 99 void oceos_on_error() {
100   return;
101 }
102 /**
103  * User to implement in case of system log is 2/3 full;
104  * Comment it out if not used and set field log_full_function in app_config to NULL
105  */
106 void oceos_on_full_log(){
107   log_full_was_called = TRUE;
108   return;
109 }

tut1.c

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
17  */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include "tut1.h"                        // application header
21 #include "oceos_config.h"                // OCEOS header
22 
23 int main(void) {
24   int status;
25 
26   /*
27    * Initialise the application configuration and OCEOS
28    *
29    * This application function creates the application configuration
30    * and passes it to oceos_init(), which initialises the fixed data
31    * and enables the system log
32    */
33   if (!application_init()) {
34     //LOG
35     return -1;
36   }
37 
38   // Create Main task to
39   if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254
40                         100,// priority,  must be in range 1 to 254, lower value is higher priority
41                         100,	// threshold, must be in range 1 to task priority
42                         2,				// jobs_max, must be in range 1 to 15
43                         0,// FALSE -> floating point hardware not used by task
44                         1,				// FALSE -> task initially not enabled
45                         fun0,			// main body of task
46                         nullFun,		// task end function
47                         0,// time_deadline, must finish no later than this after start, 0 => ignore
48                         0	// minimum time expected between start requests, 0 => no restriction
49                         ) != SUCCESSFUL)
50     return 1;
51 
52   if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)
53       != SUCCESSFUL)
54     return 2;
55 
56   /*
57    * Finish initialising OCEOS and setting up the fixed data
58    */
59   status = oceos_init_finish();
60   if (SUCCESSFUL != status) {
61     return 3;
62   }   // if
63 
64   /*
65    * Start OCEOS scheduling
66    *
67    * The OCEOS fixed data provides all the information required.
68    *
69    * If a valid task is specified, it is started and passed the pointer.
70    * Otherwise the system is put in sleep mode
71    */
72   status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task
73   return status;
74 }   // main
75 
76 /*
77  * Application code functions, functions declared in asw.h
78  */
79 void fun0(void *ptr) {
80   printf("Entered high priority task\n");
81   oceos_task_start(t_1, ptr);
82   printf("Leaving high priority task\n");
83   return;
84 }   // fun0()
85 
86 void fun1(void *ptr) {
87   printf("Entered low priority task\n");
88   oceos_task_start(t_0, ptr);
89   printf("Leaving low priority task\n");
90   return;
91 }   // fun1()

Tutorial 2 – Using a mutex

This exercise will familiarise the developer with the use a mutexes.

  1. Two tasks as before.
  2. One mutex. Note the priority ceiling of the mutex.
  3. Both tasks output message when they get the mutex and when they return it
  4. Start OCEOS with the low priority task
  5. This grabs mutex, then starts high priority task
  6. Low priority task returns mutex then exits
  7. High priority task returns mutex, start low priority task and exits

For code example see example below:

tut2.h

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
17  */
18 #ifndef TUT2_H_
19 #define TUT2_H_
20 
21 /* Sample Task names - all here start with t_ to help avoid name confusion */
22 enum TASK_NAME{
23     t_0,                 // High priority task
24     t_1                  // Low priority task
25 };
26 /* Sample Mutex names - all here start with m_ to help avoid name confusion */
27 enum MUTEX_NAME{
28     m_0
29 };
30 char* nullPtr = "";			// Need pointer to pass to oceos_start
31 void (*nullFun)(void *);	// Null function
32 
33 /*
34  * APPLICATION FUNCTION DECLARATIONS
35  */
36 void fun0(void *);
37 void fun1(void *);
38 
39 #endif /* TUT2_H_ */

oceos_config.h

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #ifndef INCLUDE_OCEOS_CONFIG_H_
 19 #define INCLUDE_OCEOS_CONFIG_H_
 20 
 21 // 1: Includes OCEOS main header file
 22 #include "oceos.h"
 23 //----------------------------------------------------------------------------
 24 // 2: Number of Log entries.
 25 #define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64
 26 //----------------------------------------------------------------------------
 27 // 3: Number of tasks
 28 #define NUMBER_OF_TASKS                         2  // 1 to 255
 29 //----------------------------------------------------------------------------
 30 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
 31 //    Defaults to number of tasks, as each task should have aa least one job;
 32 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
 33 #define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2
 34 //----------------------------------------------------------------------------
 35 // 5: Number of Mutexes
 36 #define NUMBER_OF_MUTEXES                       1  // 0 to 63
 37 //----------------------------------------------------------------------------
 38 // 6: Number of Semaphores
 39 #define NUMBER_OF_SEMAPHORES                    0  // 0 to 63
 40 //----------------------------------------------------------------------------
 41 // 7: Number of Data Qs
 42 #define NUMBER_OF_DATAQS                        0  // 0 to 63
 43 //----------------------------------------------------------------------------
 44 // 8: LOG data array size
 45 #define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual
 46 //----------------------------------------------------------------------------
 47 // 9: FIXED data array size
 48 #define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual
 49 //----------------------------------------------------------------------------
 50 // 10: DYNAMIC data array size
 51 #define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual
 52 //----------------------------------------------------------------------------
 53 // 11: Timed Actions
 54 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field
 55 //----------------------------------------------------------------------------
 56 // 12: Log entries base 2
 57 #define CS_LOG_DEF_ENTRIES_BASE2                0
 58 //----------------------------------------------------------------------------
 59 // 13: OCEOS stack start Address
 60 #define OCEOS_STACK_START_ADDRESS               0
 61 //----------------------------------------------------------------------------
 62 // 14: OCEOS stack end address
 63 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0
 64 //----------------------------------------------------------------------------
 65 /**
 66  * Target specific configurations
 67  */
 68 /*
 69  * ARM specific configurations
 70  */
 71 #ifdef __SAM3X8E__
 72 #ifndef BSP_SYSFREQ
 73 #define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz
 74 #endif
 75 #endif
 76 #ifdef __SAMV71Q21__
 77 #ifndef BSP_SYSFREQ
 78 #define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz
 79 #endif
 80 #endif
 81 #ifdef __VA41620__
 82 #ifndef BSP_SYSFREQ
 83 #define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz
 84 #endif
 85 #endif
 86 //--------------------------------------------------------------------
 87 // User defined function to deal with system errors
 88 void oceos_on_error(void);
 89 //---------------------------------------------------------------------
 90 // User defined function to deal with log 2/3 full
 91 void oceos_on_full_log(void);
 92 //---------------------------------------------------------------------
 93 extern U32_t log_data[];
 94 extern U32_t fixed_data[];
 95 extern U32_t dynamic_data[];
 96 extern const unsigned int __oceos_bsp_sysfreq;
 97 /**
 98  * Initialize OCEOS with user configurations
 99  */
100 int application_init(void);
101 #endif /* INCLUDE_OCEOS_CONFIG_H_ */

oceos_config.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include "oceos_config.h"
 20 
 21 /*
 22  * OCEOS INTERNAL DATA STORAGE
 23  *
 24  * This application defines arrays to hold OCEOS internal data.
 25  * The array sizes are provided by DMON by running "oceos info" command:</br>
 26  *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>
 27  *  *Run DMON command "oceos info" to get size for each array.</br>
 28  *  *Update array sizes below
 29  */
 30 U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];
 31 
 32 U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment
 33 
 34 U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];
 35 
 36 const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO
 37 
 38 static BOOLE_t log_full_was_called = FALSE;
 39 
 40 /**
 41  * Must be defined if Application is using :
 42  *      Dataq with timeout
 43  *      Semaphore with timeout
 44  *      Timed Actions
 45  */
 46 /*
 47  * Set up the application configuration structure and pass it to oceos_init
 48  * (done this way the memory used for the structure is returned automatically)
 49  */
 50 
 51 int application_init(){
 52 
 53     /*
 54      * Create the application configuration structure
 55      */
 56     struct application_configuration           app_config = {0};
 57 
 58     /*
 59      * Fill in the application parameters
 60      */
 61     app_config.log_address                   = (adrs_t)log_data;              // required
 62     app_config.fixed_data_address            = (adrs_t)fixed_data;            // required
 63     app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required
 64 
 65     app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check
 66     app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check
 67 
 68     app_config.system_error_function         = &oceos_on_error;               // NULL => ignore
 69     app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore
 70     // used in setting up system log and fixed data array
 71     app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default
 72 
 73     app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1
 74     app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size
 75 
 76     app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;
 77     app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
 78     app_config.number_of_data_queues         = NUMBER_OF_DATAQS;
 79 
 80     app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
 81     app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
 82     app_config.use_oceos_system_time         = TRUE;
 83 
 84     // initialise OCEOS
 85     enum DIRECTIVE_STATUS status;
 86     status = oceos_init(app_config);
 87 
 88     if (SUCCESSFUL == status) {
 89         return 1;
 90     } else {
 91         printf("\n oceos_init failure\n");
 92         return -1;
 93     }   // else
 94 }   // application_init()
 95 /**
 96  * User to implement in case of system error;
 97  * Comment it out if not used and set field system_error_function in app_config to NULL
 98  */
 99 void oceos_on_error() {
100   return;
101 }
102 /**
103  * User to implement in case of system log is 2/3 full;
104  * Comment it out if not used and set field log_full_function in app_config to NULL
105  */
106 void oceos_on_full_log(){
107   log_full_was_called = TRUE;
108   return;
109 }

tut2.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include <stdlib.h>
 20 #include "tut2.h"                        // application header
 21 
 22 /* N.B.  Application header is included first */
 23 #include "oceos_config.h"                // OCEOS header for this application
 24 #include "mutex.h"
 25 
 26 int main(void) {
 27   int status;
 28 
 29   /*
 30    * Initialise the application configuration and OCEOS
 31    *
 32    * This application function creates the application configuration
 33    * and passes it to oceos_init(), which initialises the fixed data
 34    * and enables the system log
 35    */
 36   if (!application_init()) {
 37     //LOG
 38     return -1;
 39   }
 40 
 41   // Create Main task to
 42   if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254
 43                         100,// priority,  must be in range 1 to 254, lower value is higher priority
 44                         100,	// threshold, must be in range 1 to task priority
 45                         2,				// jobs_max, must be in range 1 to 15
 46                         0,// FALSE -> floating point hardware not used by task
 47                         1,				// FALSE -> task initially not enabled
 48                         fun0,			// main body of task
 49                         nullFun,		// task end function
 50                         0,// time_deadline, must finish no later than this after start, 0 => ignore
 51                         0	// minimum time expected between start requests, 0 => no restriction
 52                         ) != SUCCESSFUL)
 53     return 1;
 54 
 55   if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)
 56       != SUCCESSFUL)
 57     return 2;
 58 
 59   if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it
 60     return 3;
 61 
 62   /*
 63    * Finish initialising OCEOS and setting up the fixed data
 64    */
 65   status = oceos_init_finish();
 66   if (SUCCESSFUL != status) {
 67     return 4;
 68   }   // if
 69 
 70   /*
 71    * Start OCEOS scheduling
 72    *
 73    * The OCEOS fixed data provides all the information required.
 74    *
 75    * If a valid task is specified, it is started and passed the pointer.
 76    * Otherwise the system is put in sleep mode
 77    */
 78   status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task
 79   return status;
 80 }   // main
 81 
 82 /*
 83  * Application code functions, functions declared in asw.h
 84  */
 85 void fun0(void *ptr) {
 86   if (oceos_mutex_wait(m_0) != SUCCESSFUL) {
 87     printf("Error from high priority task getting mutex\n");
 88   } else {
 89     printf("high priority task got mutex\n");
 90   }
 91   oceos_task_start(t_1, ptr);	// Start lower priority task
 92 
 93   if (oceos_mutex_signal(m_0) != SUCCESSFUL) {
 94     printf("Error from high priority task releasing mutex\n");
 95   } else {
 96     printf("High priority task released mutex\n");
 97   }
 98   return;
 99 }   // fun0()
100 
101 void fun1(void *ptr) {
102   if (oceos_mutex_wait(m_0) != SUCCESSFUL) {
103     printf("Error from low priority task getting mutex\n");
104   } else {
105     printf("Low priority task got mutex\n");
106   }
107   oceos_task_start(t_0, ptr);	// Start higher priority task
108 
109   if (oceos_mutex_signal(m_0) != SUCCESSFUL) {
110     printf("Error from low priority task releasing mutex\n");
111   } else {
112     printf("Low priority task released mutex\n");
113   }
114   return;
115 }   // fun1()

Tutorial 3 – Using Semaphores

Semaphores can be used to synchronise task actions as in this exercise.

  1. Three tasks this time, one high priority and the other two with the same lower priority
  2. Two counting semaphores, one initially 0, one initially 4, called ‘items’ and ‘spaces’
  3. First task starts second and third tasks
  4. Second task loops
    1. wait_restart spaces
    2. signal items
    3. Output ‘item done’ message
  5. Third task loops
    1. wait_restart items
    2. Output ‘got item’ message
    3. signal spaces

For code example see below:

tut3.h

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
17  */
18 #ifndef TUT3_H_
19 #define TUT3_H_
20 /* Sample Task names - all here start with t_ to help avoid name confusion */
21 enum TASK_NAME{
22     t_0,                 // Task to start other two
23     t_1,                 // consumer task
24     t_2                  // consumer task
25 
26 };
27 /* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */
28 enum SEM_NAME{
29     items,                   // Semaphore called items
30     spaces                   // Semaphore called spaces
31 };
32 char* nullPtr = "";			// Need pointer to pass to oceos_start
33 void (*nullFun)(void *);	// Null function
34 
35 /*
36  * APPLICATION FUNCTION DECLARATIONS
37  */
38 void fun0(void *);
39 void fun1(void *);
40 void fun2(void *);
41 
42 #endif /* TUT3_H_ */

oceos_config.h

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #ifndef INCLUDE_OCEOS_CONFIG_H_
 19 #define INCLUDE_OCEOS_CONFIG_H_
 20 
 21 // 1: Includes OCEOS main header file
 22 #include "oceos.h"
 23 //----------------------------------------------------------------------------
 24 // 2: Number of Log entries.
 25 #define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64
 26 //----------------------------------------------------------------------------
 27 // 3: Number of tasks
 28 #define NUMBER_OF_TASKS                         3  // 1 to 255
 29 //----------------------------------------------------------------------------
 30 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
 31 //    Defaults to number of tasks, as each task should have aa least one job;
 32 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
 33 #define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2
 34 //----------------------------------------------------------------------------
 35 // 5: Number of Mutexes
 36 #define NUMBER_OF_MUTEXES                       0  // 0 to 63
 37 //----------------------------------------------------------------------------
 38 // 6: Number of Semaphores
 39 #define NUMBER_OF_SEMAPHORES                    2  // 0 to 63
 40 //----------------------------------------------------------------------------
 41 // 7: Number of Data Qs
 42 #define NUMBER_OF_DATAQS                        0  // 0 to 63
 43 //----------------------------------------------------------------------------
 44 // 8: LOG data array size
 45 #define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual
 46 //----------------------------------------------------------------------------
 47 // 9: FIXED data array size
 48 #define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual
 49 //----------------------------------------------------------------------------
 50 // 10: DYNAMIC data array size
 51 #define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual
 52 //----------------------------------------------------------------------------
 53 // 11: Timed Actions
 54 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field
 55 //----------------------------------------------------------------------------
 56 // 12: Log entries base 2
 57 #define CS_LOG_DEF_ENTRIES_BASE2                0
 58 //----------------------------------------------------------------------------
 59 // 13: OCEOS stack start Address
 60 #define OCEOS_STACK_START_ADDRESS               0
 61 //----------------------------------------------------------------------------
 62 // 14: OCEOS stack end address
 63 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0
 64 //----------------------------------------------------------------------------
 65 /**
 66  * Target specific configurations
 67  */
 68 /*
 69  * ARM specific configurations
 70  */
 71 #ifdef __SAM3X8E__
 72 #ifndef BSP_SYSFREQ
 73 #define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz
 74 #endif
 75 #endif
 76 #ifdef __SAMV71Q21__
 77 #ifndef BSP_SYSFREQ
 78 #define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz
 79 #endif
 80 #endif
 81 #ifdef __VA41620__
 82 #ifndef BSP_SYSFREQ
 83 #define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz
 84 #endif
 85 #endif
 86 //--------------------------------------------------------------------
 87 // User defined function to deal with system errors
 88 void oceos_on_error(void);
 89 //---------------------------------------------------------------------
 90 // User defined function to deal with log 2/3 full
 91 void oceos_on_full_log(void);
 92 //---------------------------------------------------------------------
 93 extern U32_t log_data[];
 94 extern U32_t fixed_data[];
 95 extern U32_t dynamic_data[];
 96 extern const unsigned int __oceos_bsp_sysfreq;
 97 /**
 98  * Initialize OCEOS with user configurations
 99  */
100 int application_init(void);
101 #endif /* INCLUDE_OCEOS_CONFIG_H_ */

oceos_config.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include "oceos_config.h"
 20 
 21 /*
 22  * OCEOS INTERNAL DATA STORAGE
 23  *
 24  * This application defines arrays to hold OCEOS internal data.
 25  * The array sizes are provided by DMON by running "oceos info" command:</br>
 26  *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>
 27  *  *Run DMON command "oceos info" to get size for each array.</br>
 28  *  *Update array sizes below
 29  */
 30 U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];
 31 
 32 U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment
 33 
 34 U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];
 35 
 36 const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO
 37 
 38 static BOOLE_t log_full_was_called = FALSE;
 39 
 40 /**
 41  * Must be defined if Application is using :
 42  *      Dataq with timeout
 43  *      Semaphore with timeout
 44  *      Timed Actions
 45  */
 46 /*
 47  * Set up the application configuration structure and pass it to oceos_init
 48  * (done this way the memory used for the structure is returned automatically)
 49  */
 50 
 51 int application_init(){
 52 
 53     /*
 54      * Create the application configuration structure
 55      */
 56     struct application_configuration           app_config = {0};
 57 
 58     /*
 59      * Fill in the application parameters
 60      */
 61     app_config.log_address                   = (adrs_t)log_data;              // required
 62     app_config.fixed_data_address            = (adrs_t)fixed_data;            // required
 63     app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required
 64 
 65     app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check
 66     app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check
 67 
 68     app_config.system_error_function         = &oceos_on_error;               // NULL => ignore
 69     app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore
 70     // used in setting up system log and fixed data array
 71     app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default
 72 
 73     app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1
 74     app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size
 75 
 76     app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;
 77     app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
 78     app_config.number_of_data_queues         = NUMBER_OF_DATAQS;
 79 
 80     app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
 81     app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
 82     app_config.use_oceos_system_time         = TRUE;
 83 
 84     // initialise OCEOS
 85     enum DIRECTIVE_STATUS status;
 86     status = oceos_init(app_config);
 87 
 88     if (SUCCESSFUL == status) {
 89         return 1;
 90     } else {
 91         printf("\n oceos_init failure\n");
 92         return -1;
 93     }   // else
 94 }   // application_init()
 95 /**
 96  * User to implement in case of system error;
 97  * Comment it out if not used and set field system_error_function in app_config to NULL
 98  */
 99 void oceos_on_error() {
100   return;
101 }
102 /**
103  * User to implement in case of system log is 2/3 full;
104  * Comment it out if not used and set field log_full_function in app_config to NULL
105  */
106 void oceos_on_full_log(){
107   log_full_was_called = TRUE;
108   return;
109 }

tut3.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 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 "tut3.h"                        // application header
 24 #include "semaphore.h"
 25 
 26 int main(void) {
 27   int status;
 28   /*
 29    * Initialise the application configuration and OCEOS
 30    *
 31    * This application function creates the application configuration
 32    * and passes it to oceos_init(), which initialises the fixed data
 33    * and enables the system log
 34    */
 35   if (!application_init()) {
 36     //LOG
 37     return -1;
 38   }
 39   // Create Main task to
 40   if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254
 41                         10,	// priority,  must be in range 1 to 254, lower value is higher priority
 42                         10,		// threshold, must be in range 1 to task priority
 43                         1,				// jobs_max, must be in range 1 to 15
 44                         0,// FALSE -> floating point hardware not used by task
 45                         1,				// FALSE -> task initially not enabled
 46                         fun0,			// main body of task
 47                         nullFun,		// task end function
 48                         0,// time_deadline, must finish no later than this after start, 0 => ignore
 49                         0	// minimum time expected between start requests, 0 => no restriction
 50                         ) != SUCCESSFUL)
 51     return 1;
 52 
 53   if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)
 54       != SUCCESSFUL)
 55     return 2;
 56 
 57   if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)
 58       != SUCCESSFUL)
 59     return 3;
 60 
 61   if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2
 62     return 4;
 63 
 64   if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2
 65     return 4;
 66   /*
 67    * Finish initialising OCEOS and setting up the fixed data
 68    */
 69   status = oceos_init_finish();
 70   if (SUCCESSFUL != status) {
 71     return 6;
 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 with task to start other tasks
 82   return status;
 83 }   // main
 84 
 85 /*
 86  * Application code functions, functions declared in asw.h
 87  */
 88 void fun0(void *ptr) {
 89   oceos_task_start(t_1, ptr);	// Start consumer task
 90   oceos_task_start(t_2, ptr);	// Start consumer task
 91 }   // fun0()
 92 
 93 void fun1(void *ptr) {
 94   while (1) {	// loop forever
 95     if (oceos_sem_wait_restart(items) != SUCCESSFUL) {
 96       printf("Error from task t_0 task waiting items\n");
 97     }
 98     printf("Got item\n");
 99     if (oceos_sem_signal(spaces) != SUCCESSFUL) {
100       printf("Error from task t_0 signalling spaces\n");
101     }
102   }
103 }   // fun0()
104 
105 void fun2(void *ptr) {
106   while (1) {	// loop forever
107     if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {
108       printf("Error from task t_1 task waiting spaces\n");
109     }
110     if (oceos_sem_signal(items) != SUCCESSFUL) {
111       printf("Error from task t_1 signalling items\n");
112     } else {
113       printf("Item done\n");
114     }
115   }
116   return;
117 }   // fun1()

Tutorial 4 – Timer interrupt starts task

This exercise introduces the use of timer interrupts.

  1. Create one task
  2. Set a timer to interrupt every 2 seconds
  3. Set timer handler to start task
  4. Task outputs message, then exits

For code example see below:

tut4.h

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
17  */
18 #ifndef TUT4_H_
19 #define TUT4_H_
20 /* Sample Task names - all here start with t_ to help avoid name confusion */
21 enum TASK_NAME{
22     t_0,                 // Task to setup interrupt
23     t_1                  // Task to be executed by interrupt routine
24 
25 };
26 /*
27  * APPLICATION FUNCTION DECLARATIONS
28  */
29 void fun0(void *);
30 void fun1(void *);
31 void start_task(void *arg, int source);
32 void timer_setup(void);
33 
34 #endif /* TUT4_H_ */

oceos_config.h

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #ifndef INCLUDE_OCEOS_CONFIG_H_
 19 #define INCLUDE_OCEOS_CONFIG_H_
 20 
 21 // 1: Includes OCEOS main header file
 22 #include "oceos.h"
 23 //----------------------------------------------------------------------------
 24 // 2: Number of Log entries.
 25 #define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64
 26 //----------------------------------------------------------------------------
 27 // 3: Number of tasks
 28 #define NUMBER_OF_TASKS                         2  // 1 to 255
 29 //----------------------------------------------------------------------------
 30 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
 31 //    Defaults to number of tasks, as each task should have aa least one job;
 32 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
 33 #define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1
 34 //----------------------------------------------------------------------------
 35 // 5: Number of Mutexes
 36 #define NUMBER_OF_MUTEXES                       0  // 0 to 63
 37 //----------------------------------------------------------------------------
 38 // 6: Number of Semaphores
 39 #define NUMBER_OF_SEMAPHORES                    0  // 0 to 63
 40 //----------------------------------------------------------------------------
 41 // 7: Number of Data Qs
 42 #define NUMBER_OF_DATAQS                        0  // 0 to 63
 43 //----------------------------------------------------------------------------
 44 // 8: LOG data array size
 45 #define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual
 46 //----------------------------------------------------------------------------
 47 // 9: FIXED data array size
 48 #define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual
 49 //----------------------------------------------------------------------------
 50 // 10: DYNAMIC data array size
 51 #define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual
 52 //----------------------------------------------------------------------------
 53 // 11: Timed Actions
 54 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field
 55 //----------------------------------------------------------------------------
 56 // 12: Log entries base 2
 57 #define CS_LOG_DEF_ENTRIES_BASE2                0
 58 //----------------------------------------------------------------------------
 59 // 13: OCEOS stack start Address
 60 #define OCEOS_STACK_START_ADDRESS               0
 61 //----------------------------------------------------------------------------
 62 // 14: OCEOS stack end address
 63 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0
 64 //----------------------------------------------------------------------------
 65 /**
 66  * Target specific configurations
 67  */
 68 /*
 69  * ARM specific configurations
 70  */
 71 #ifdef __SAM3X8E__
 72 #ifndef BSP_SYSFREQ
 73 #define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz
 74 #endif
 75 #endif
 76 #ifdef __SAMV71Q21__
 77 #ifndef BSP_SYSFREQ
 78 #define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz
 79 #endif
 80 #endif
 81 #ifdef __VA41620__
 82 #ifndef BSP_SYSFREQ
 83 #define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz
 84 #endif
 85 #endif
 86 //--------------------------------------------------------------------
 87 // User defined function to deal with system errors
 88 void oceos_on_error(void);
 89 //---------------------------------------------------------------------
 90 // User defined function to deal with log 2/3 full
 91 void oceos_on_full_log(void);
 92 //---------------------------------------------------------------------
 93 extern U32_t log_data[];
 94 extern U32_t fixed_data[];
 95 extern U32_t dynamic_data[];
 96 extern const unsigned int __oceos_bsp_sysfreq;
 97 /**
 98  * Initialize OCEOS with user configurations
 99  */
100 int application_init(void);
101 #endif /* INCLUDE_OCEOS_CONFIG_H_ */

oceos_config.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include "oceos_config.h"
 20 
 21 /*
 22  * OCEOS INTERNAL DATA STORAGE
 23  *
 24  * This application defines arrays to hold OCEOS internal data.
 25  * The array sizes are provided by DMON by running "oceos info" command:</br>
 26  *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>
 27  *  *Run DMON command "oceos info" to get size for each array.</br>
 28  *  *Update array sizes below
 29  */
 30 U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];
 31 
 32 U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment
 33 
 34 U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];
 35 
 36 const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO
 37 
 38 static BOOLE_t log_full_was_called = FALSE;
 39 
 40 /**
 41  * Must be defined if Application is using :
 42  *      Dataq with timeout
 43  *      Semaphore with timeout
 44  *      Timed Actions
 45  */
 46 /*
 47  * Set up the application configuration structure and pass it to oceos_init
 48  * (done this way the memory used for the structure is returned automatically)
 49  */
 50 
 51 int application_init(){
 52 
 53     /*
 54      * Create the application configuration structure
 55      */
 56     struct application_configuration           app_config = {0};
 57 
 58     /*
 59      * Fill in the application parameters
 60      */
 61     app_config.log_address                   = (adrs_t)log_data;              // required
 62     app_config.fixed_data_address            = (adrs_t)fixed_data;            // required
 63     app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required
 64 
 65     app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check
 66     app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check
 67 
 68     app_config.system_error_function         = &oceos_on_error;               // NULL => ignore
 69     app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore
 70     // used in setting up system log and fixed data array
 71     app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default
 72 
 73     app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1
 74     app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size
 75 
 76     app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;
 77     app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
 78     app_config.number_of_data_queues         = NUMBER_OF_DATAQS;
 79 
 80     app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
 81     app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
 82     app_config.use_oceos_system_time         = TRUE;
 83 
 84     // initialise OCEOS
 85     enum DIRECTIVE_STATUS status;
 86     status = oceos_init(app_config);
 87 
 88     if (SUCCESSFUL == status) {
 89         return 1;
 90     } else {
 91         printf("\n oceos_init failure\n");
 92         return -1;
 93     }   // else
 94 }   // application_init()
 95 /**
 96  * User to implement in case of system error;
 97  * Comment it out if not used and set field system_error_function in app_config to NULL
 98  */
 99 void oceos_on_error() {
100   return;
101 }
102 /**
103  * User to implement in case of system log is 2/3 full;
104  * Comment it out if not used and set field log_full_function in app_config to NULL
105  */
106 void oceos_on_full_log(){
107   log_full_was_called = TRUE;
108   return;
109 }

arm_task_src.c

  1 /*
  2  *********************************************************************************************************
  3  *                                                OCEOS
  4  *                                      Real-Time Operating System
  5  *                                                 for
  6  *                                        ARM Microcontroller
  7  *
  8  *                                   Example implementation of OCEOS
  9  *
 10  *
 11  *                               (c) Copyright 2021, O.C.E. Technology
 12  *                                           All Rights Reserved
 13  *
 14  *
 15  * Author:       jfk
 16  ********************************************************************************************************
 17  */
 18 #include <stdio.h>
 19 #include <stdlib.h>
 20 #include "tut4.h"
 21 #include "oceos_config.h"
 22 
 23 #if defined(__SAM3X8E__) || defined(__SAMV71Q21__)
 24 #include "sam.h"
 25 
 26 #define ENABLE_WAVE_MODE           (0x1 << TC_CMR_WAVE_Pos)
 27 #define TC_CMR_WAVE_SEL_Pos        13
 28 #define SET_WAVE_SELECT            (~(0x3 << TC_CMR_WAVE_SEL_Pos)) //00
 29 #define TC_CMR_CPCSTOP_Pos         6
 30 #define TC_CMR_CPCSTOP             (0x1 << TC_CMR_CPCSTOP_Pos)
 31 
 32 static Tc *timer_regs;
 33 static TcChannel *tc;
 34 
 35 #endif
 36 
 37 /*
 38  * Set up timer and register handler
 39  */
 40 void timer_setup(){
 41 
 42 #ifdef __SAM3X8E__
 43   // Enabling Peripheral Clocks
 44  // REmove write protect
 45  int pmc_was_enabled = 0;
 46  if (0 != (PMC->PMC_WPMR & PMC_WPMR_WPEN)) {
 47      PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
 48      pmc_was_enabled = 1;
 49  }
 50  // Enable Clock
 51  PMC->PMC_PCER0 |= PMC_PCER0_PID28;
 52  // Enable write protect
 53  if (pmc_was_enabled) {
 54    PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;
 55  }
 56 
 57  timer_regs = (Tc *)TC0;
 58  tc = &(timer_regs->TC_CHANNEL[1]);
 59 
 60  // Enable Wave Mode
 61   tc->TC_CMR |= ENABLE_WAVE_MODE;
 62   // Set WAVESEL to 00
 63   tc->TC_CMR &= (U32_t)SET_WAVE_SELECT;
 64   // Set TC_CMR_CPCSTOP and Clock input
 65   tc->TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8
 66 
 67 
 68  // Set Block Clock
 69  timer_regs->TC_BMR &= (U32_t)(~(1 << 1));
 70  // Interrupt Enable
 71    // Enable Timer interrupt (RC Compare)
 72  tc->TC_IER = TC_IER_CPCS;
 73 
 74  NVIC_EnableIRQ(TC1_IRQn);
 75  // Set Highest Priority for interrupt number
 76  NVIC_SetPriority(TC1_IRQn, 1);
 77  float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;
 78 
 79  //tc->TC_RC  = base_scaler * 0x3DC6C0;
 80  tc->TC_RC  = base_scaler * 1349;
 81  // Enable clock
 82  tc->TC_CCR = TC_CCR_CLKEN;
 83 
 84  // Start clock
 85  tc->TC_CCR = TC_CCR_SWTRG;
 86 #endif
 87 #ifdef __SAMV71Q21__
 88   // Enabling Peripheral Clocks
 89  // REmove write protect
 90  int pmc_was_enabled = 0;
 91  if (0 != (PMC->PMC_WPMR & PMC_WPMR_WPEN)) {
 92      PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
 93      pmc_was_enabled = 1;
 94  }
 95  // Enable Clock
 96  PMC->PMC_PCER0 |= PMC_PCER0_PID24;
 97  // Enable write protect
 98  if (pmc_was_enabled) {
 99    PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;
100  }
101  timer_regs = (Tc *)TC0;
102  tc = &(timer_regs->TC_CHANNEL[1]);
103 
104  // Enable Wave Mode
105   tc->TC_CMR |= ENABLE_WAVE_MODE;
106   // Set WAVESEL to 00
107   tc->TC_CMR &= (U32_t)SET_WAVE_SELECT;
108   // Set TC_CMR_CPCSTOP and Clock input
109   tc->TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //
110 
111  // Set Block Clock
112  timer_regs->TC_BMR &= (U32_t)(~(1 << 1));
113  // Interrupt Enable
114  // Enable Timer interrupt (RC Compare)
115  tc->TC_IER = TC_IER_CPCS;
116 
117  NVIC_EnableIRQ(TC1_IRQn);
118  // Set Highest Priority for interrupt number
119  NVIC_SetPriority(TC1_IRQn, 1);
120 
121  tc->TC_RC  = 0x61a8;// 1s
122 
123  // Enable clock
124  tc->TC_CCR = TC_CCR_CLKEN;
125 
126  // Start clock
127  tc->TC_CCR = TC_CCR_SWTRG;
128 #endif
129 }   // setup_timer()
130 
131 void TC1_IRQHandler() {
132 #if defined(__SAM3X8E__) || defined(__SAMV71Q21__)
133   tc->TC_SR;// Read to remove pending bit
134 #endif
135   // Start task
136   oceos_task_start(t_1, NULL);
137 
138 #if defined(__SAM3X8E__) || defined(__SAMV71Q21__)
139   tc->TC_CCR = TC_CCR_SWTRG;
140 #endif
141 }

tut4.c

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        ARM Microcontroller
 7  *
 8  *                                   Example implementation of OCEOS
 9  *
10  *
11  *                               (c) Copyright 2021, O.C.E. Technology
12  *                                           All Rights Reserved
13  *
14  *
15  * Author:       jfk
16  ********************************************************************************************************
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 "tut4.h"                        // application header
24 
25 volatile U32_t count_task_start = 0;
26 
27 int main(void) {
28   int status;
29   /*
30    * Initialise the application configuration and OCEOS
31    *
32    * This application function creates the application configuration
33    * and passes it to oceos_init(), which initialises the fixed data
34    * and enables the system log
35    */
36   if (!application_init()) {
37     //LOG
38     return -1;
39   }
40   // Create Main task to
41   if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254
42                         10,	// priority,  must be in range 1 to 254, lower value is higher priority
43                         10,		// threshold, must be in range 1 to task priority
44                         1,				// jobs_max, must be in range 1 to 15
45                         0,// FALSE -> floating point hardware not used by task
46                         1,				// FALSE -> task initially not enabled
47                         fun0,			// main body of task
48                         NULL,		// task end function
49                         0,// time_deadline, must finish no later than this after start, 0 => ignore
50                         0	// minimum time expected between start requests, 0 => no restriction
51                         ) != SUCCESSFUL)
52     return 1;
53 
54   if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)
55       != SUCCESSFUL)
56     return 2;
57   /*
58    * Finish initialising OCEOS and setting up the fixed data
59    */
60   status = oceos_init_finish();
61   if (SUCCESSFUL != status) {
62     return 3;
63   }   // if
64   /*
65    * Start OCEOS scheduling
66    *
67    * The OCEOS fixed data provides all the information required.
68    *
69    * If a valid task is specified, it is started and passed the pointer.
70    * Otherwise the system is put in sleep mode
71    */
72   status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS
73   return status;
74 }   // main
75 
76 /*
77  * Task 0 starting point
78  */
79 void fun0(void *ptr) {
80   timer_setup();
81 }   // fun0()
82 /**
83  * Task 1 starting point;
84  * Triggered from Timer IRQ handler
85  */
86 void fun1(void *ptr) {
87   printf("Task started : %u times \n", count_task_start);
88   count_task_start++;
89 }   // fun1()

Tutorial 5 – Using dataq with timed action

This exercise introduces the use of dataq with timed action.

  1. Create functions to be used by tasks
  2. Create one struct – pointer to these will be placed on queues
  3. Set timeout period T
  4. Create configuration structure with above configuration values for fields
  5. Initialize OCEOS using oceos_init()
  6. Create two tasks
  7. Create two data queues

For code example see below:

tut5.h

 1 /*
 2 ******************************************************************************
 3 *                                   OCEOS
 4 *                        Real-Time Operating System
 5 *                               for ARM/SPARC
 6 *                              Microcontroller
 7 *
 8 *                   Application Software Example Header File
 9 *
10 *
11 *                    (c) Copyright 2021, O.C.E. Technology
12 *                             All Rights Reserved
13 *
14 * File :        asw.h
15 * Author:       Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>
16 ******************************************************************************
17  */
18 #ifndef ASW_H
19 #define ASW_H
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <assert.h>
23 #include "oceos_config.h"    // OCEOS header
24 #include "oceos_timer.h"     
25 #include "system_log.h"
26 #include "dataq.h"
27 
28 #define N0 1  // dataq_size
29 #define N1 1  // dataq_size
30 #define JOBS0 1 // pending q size
31 #define JOBS1 1 // pending q size
32 #define TIME_OUT 1000000 // timeout
33 
34 /*
35  * APPLICATION FUNCTION DECLARATIONS
36  */
37 enum TASK_NAME{
38     t_consumer ,                     // will have task ID 0
39     t_producer,                     // will have task ID 1
40 };
41 enum DATAQ_NAME{
42   queue_0,                      // will have dataq ID 0
43   queue_1,                      // will have dataq ID 1
44 };
45 void t_consumer_task(void);
46 void t_producer_task(void);
47 
48 #endif /* ASW_H */

oceos_config.h

 1 /*
 2  * app_config.h
 3  *
 4  *  Created on: 17 Feb 2020
 5  *      Author: Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>
 6  */
 7 
 8 #ifndef INCLUDE_OCEOS_CONFIG_H_
 9 #define INCLUDE_OCEOS_CONFIG_H_
10 
11 // 1: Includes OCEOS main header file
12 #include "oceos.h"
13 //----------------------------------------------------------------------------
14 // 2: Number of Log entries.
15 #define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64
16 //----------------------------------------------------------------------------
17 // 3: Number of tasks
18 #define NUMBER_OF_TASKS                         2  // 1 to 255
19 //----------------------------------------------------------------------------
20 // 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);
21 //    Defaults to number of tasks, as each task should have aa least one job;
22 //    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs
23 #define NUMBER_OF_READYQ_ENTRIES                3
24 //----------------------------------------------------------------------------
25 // 5: Number of Mutexes
26 #define NUMBER_OF_MUTEXES                       0  // 0 to 63
27 //----------------------------------------------------------------------------
28 // 6: Number of Semaphores
29 #define NUMBER_OF_SEMAPHORES                    0  // 0 to 63
30 //----------------------------------------------------------------------------
31 // 7: Number of Data Qs
32 #define NUMBER_OF_DATAQS                        2  // 0 to 63
33 //----------------------------------------------------------------------------
34 // 8: LOG data array size
35 #define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual
36 //----------------------------------------------------------------------------
37 // 9: FIXED data array size
38 #define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual
39 //----------------------------------------------------------------------------
40 // 10: DYNAMIC data array size
41 #define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual
42 //----------------------------------------------------------------------------
43 // 11: Timed Actions
44 #define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field
45 //----------------------------------------------------------------------------
46 // 12: Log entries base 2
47 #define CS_LOG_DEF_ENTRIES_BASE2                0
48 //----------------------------------------------------------------------------
49 // 13: OCEOS stack start Address
50 #define OCEOS_STACK_START_ADDRESS               0
51 //----------------------------------------------------------------------------
52 // 14: OCEOS stack end address
53 #define OCEOS_STACK_LOW_BOUND_ADDRESS           0
54 //----------------------------------------------------------------------------
55 /**
56  * Target specific configurations
57  */
58 #ifdef __SAM3X8E__
59 #ifndef BSP_SYSFREQ
60 #define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz
61 #endif
62 #endif
63 #ifdef __SAMV71Q21__
64 #ifndef BSP_SYSFREQ
65 #define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz
66 #endif
67 #endif
68 #ifdef __VA41620__
69 #ifndef BSP_SYSFREQ
70 #define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz
71 #endif
72 #endif
73 
74 // User defined function to deal with system errors
75 void oceos_on_error(void*);
76 //---------------------------------------------------------------------
77 // User defined function to deal with log 2/3 full
78 void oceos_on_full_log(void*);
79 //---------------------------------------------------------------------
80 extern U32_t log_data[];
81 extern U32_t fixed_data[];
82 extern U32_t dynamic_data[];
83 extern const unsigned int __oceos_bsp_sysfreq;
84 /**
85  * Initialize OCEOS with user configurations
86  */
87 int application_init(void);
88 #endif /* INCLUDE_OCEOS_CONFIG_H_ */

oceos_config.c

 1 /*
 2  * app_config.c
 3  *
 4  *  Configuration Tamplate for OCEOS
 5  *
 6  *  Created on: 17 Feb 2020
 7  *      Author: Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>
 8  */
 9 #include <stdio.h>
10 #include <assert.h>
11 #include "oceos_config.h"
12 
13 /*
14  * OCEOS INTERNAL DATA STORAGE
15  *
16  * This application defines arrays to hold OCEOS internal data.
17  * The array sizes are provided by DMON by running "oceos info" command:</br>
18  *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>
19  *  *Run DMON command "oceos info" to get size for each array.</br>
20  *  *Update array sizes below
21  */
22 U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];
23 
24 U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment
25 
26 U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];
27 
28 const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO
29 
30 static BOOLE_t log_full_was_called = FALSE;
31 
32 /*
33  * Set up the application configuration structure and pass it to oceos_init
34  * (done this way the memory used for the structure is returned automatically)
35  */
36 
37 int application_init(){
38 
39     /*
40      * Create the application configuration structure
41      */
42     struct application_configuration           app_config = {0};
43 
44     /*
45      * Fill in the application parameters
46      */
47     app_config.log_address                   = (adrs_t)log_data;              // required
48     app_config.fixed_data_address            = (adrs_t)fixed_data;            // required
49     app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required
50 
51     app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check
52     app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check
53 
54     app_config.system_error_function         = &oceos_on_error;               // NULL => ignore
55     app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore
56 
57     // used in setting up system log and fixed data array
58     app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default
59 
60     app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1
61     app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size
62 
63     app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;
64     app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;
65     app_config.number_of_data_queues         = NUMBER_OF_DATAQS;
66 
67     app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
68     app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
69     app_config.use_oceos_system_time         = TRUE;
70 
71     // initialise OCEOS
72     enum DIRECTIVE_STATUS status;
73     status = oceos_init(app_config);
74     assert(SUCCESSFUL == status);
75 
76     if (SUCCESSFUL == status) {
77         return 1;
78     } else {
79         printf("\n oceos_init failure\n");
80         return -1;
81     }   // else
82 }   // application_init()
83 /**
84  * User to implement in case of system error;
85  * Comment it out if not used and set field system_error_function in app_config to NULL
86  */
87 void oceos_on_error(void* ptr) {
88   return;
89 }
90 /**
91  * User to implement in case of system log is 2/3 full;
92  * Comment it out if not used and set field log_full_function in app_config to NULL
93  */
94 void oceos_on_full_log(void* ptr){
95   log_full_was_called = TRUE;
96   return;
97 }

tut5.c

  1 /*
  2 ******************************************************************************
  3 *                                   OCEOS
  4 *                        Real-Time Operating System
  5 *                              for ARM/SPARC
  6 *                             Microcontroller
  7 *
  8 *                       Application Software Example
  9 *
 10 *
 11 *                    (c) Copyright 2022, O.C.E. Technology
 12 *                             All Rights Reserved
 13 *
 14 * Author:       jfk
 15 *
 16 * Purpose                : The test here involves creating two tasks with different priorities, 
 17 *						   and two data queues with timed action implimentation.
 18 *
 19 ******************************************************************************
 20 */
 21 /* N.B.  Application header is included first */
 22 #include "tut5.h"                        // application header
 23 
 24 struct data {
 25   int status;
 26   char *message;
 27 } test_data = {
 28     1,
 29     "Test Data",
 30 };
 31 int main(void) {
 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         printf("\nProblem\n");
 43         return -1;
 44     }
 45 
 46     enum DIRECTIVE_STATUS status;
 47     // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0
 48     status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);
 49       if(SUCCESSFUL != status){
 50         // LOG
 51         printf("\nAbandoning, problem creating task t_consumer, resulting return code: %u\n", status);
 52         return -1;
 53       }   // if
 54 	
 55     // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0
 56     status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);
 57 	  if(SUCCESSFUL != status){
 58         // LOG
 59         printf("\nAbandoning, problem creating task t_producer, resulting return code: %u\n", status);
 60         return -1;
 61       }   // if
 62 
 63     printf("\n Tasks created\n");
 64     // no counting semaphores, data queues or user defined traps
 65 
 66     // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE
 67      status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);
 68      if(SUCCESSFUL != status){
 69         printf("\nProblem creating dataq queue_0, resulting return code: %u\n", status);
 70      }   // if
 71 	
 72 	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE
 73       status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);
 74       if(SUCCESSFUL != status){
 75        printf("\nProblem creating dataq queue_1, resulting return code: %u\n", status);
 76       }   // if
 77     /*
 78      * Finish initialising OCEOS and setting up the fixed data
 79      */
 80     status = oceos_init_finish();
 81     if(SUCCESSFUL != status){
 82      printf("\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n", status);
 83      return -1;
 84     }   // if
 85     //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer
 86     status = oceos_start(fixed_data, t_producer, NULL);
 87 
 88     return status;                          // returned as an integer
 89 
 90 }   // function waits for specific time interval
 91 void test_wait(U32_t interval) {
 92   volatile U32_t start_time = oceos_time_sys_get32();
 93   volatile U32_t cur_time = 0;
 94   while(1) {
 95       cur_time = oceos_time_sys_get32();
 96       if ((cur_time - start_time) >= interval ) {
 97           break;
 98       }
 99   }
100 }
101 /*
102  * Tasks
103  */
104 void t_consumer_task() {
105   static int case_number = 0;
106   if (case_number == 0) {
107       case_number++;
108       // 2)  Action: Task 1 attempts to start Task 0
109       // Check:  Task 0 has started, pre-empting Task 1
110       // a.  Check: entry message from Task 0
111       // b.  Check: queue_0 entries is 0
112       // c.  Check: queue_1 entries is 0
113       printf("t_consumer was started\n");
114        if(oceos_dataq_get_size(queue_0)!= 0){
115        printf("\nData queue_0 entries is not equal to 0\n");
116        }   // if
117 	   if(oceos_dataq_get_size(queue_1)!= 0){
118        printf("\nData queue_1 entries is not equal to 0\n");
119        }   // if
120   
121 
122       // 3) Action: Task 0 does read_restart on queue_0
123       oceos_dataq_read_restart_timeout(queue_0, 0);
124   } else if (case_number == 1){
125       case_number++;
126       // 5) Action: Task 1 writes pointer to struct to queue_0
127       // Check:  Task 0 has started, pre-empting Task 1
128       // a.  Check: entry message from Task 0
129       // b.  Check: queue_0 entries count is 1
130       // c.  Check: queue_1 entries count is 0
131        printf("t_consumer was started\n");
132 	   if(oceos_dataq_get_size(queue_0)!= 1){
133        printf("\nData queue_0 entries is not equal to 1\n");
134        }   // if
135 	   if(oceos_dataq_get_size(queue_1)!= 0){
136        printf("\nData queue_1 entries is not equal to 0\n");
137        }   // if
138 
139       // 6) Action: Task 0 does read_restart on queue 0
140       // Check:  Task 0 has succeeded
141       // a.  Check: non-null pointer returned
142       // b.  Check: queue_0 entries count is 0
143       // c.  Check: queue_0 entries count is 0
144 	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){
145        printf("\nDataq read restart timeout returned null\n");
146        }   // if
147 	   if(oceos_dataq_get_size(queue_0)!= 0){
148        printf("\nData queue_0 entries is not equal to 0\n");
149        }   // if
150        if(oceos_dataq_get_size(queue_1)!= 0){
151        printf("\nData queue_1 entries is not equal to 0\n");
152        }   // if
153 
154       // 7)    Action: Task 0 writes this pointer to queue_1
155       // Check:  Task 0 has succeeded
156       // a.  Check: queue_0 entries count is 0
157       // b.  Check: queue_1 entries count is 1
158 	   if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
159        printf("\nDataq write was not succesful\n");
160        }   // if
161        if(oceos_dataq_get_size(queue_0)!= 0){
162        printf("\nData queue_0 entries is not equal to 0\n");
163        }   // if
164 	   if(oceos_dataq_get_size(queue_1)!= 1){
165        printf("\nData queue_1 entries is not equal to 1\n");
166        }   // if
167 
168       // 8) Action: Task 0 does read_restart with timeout on queue_0
169       // Check:  Task 0 exits as queues_0 is empty
170 	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){
171        printf("\nDataq read restart timeout returned not null\n");
172        }   // if
173   } else {
174       case_number++;
175       // 10)   Action: Task 1 loops for at least twice timeout period T
176       // Check:  Task 0 restarts on timeout, pre-empting Task 1
177       // a.  Check: entry message from Task 0
178       // b.  Check: queue_0 entries count is 0
179       // c.  Check: queue_1 entries count is 0
180        printf("t_consumer was started\n");
181 	   if(oceos_dataq_get_size(queue_0)!= 0){
182        printf("\nData queue_0 entries is not equal to 0\n");
183        }   // if
184 	   if(oceos_dataq_get_size(queue_1)!= 0){
185        printf("\nData queue_1 entries is not equal to 0\n");
186        }   // if
187 
188       // 11)    Action: Task 0 does read_continue on queue_0
189       // Check:  Task 0 has succeeded
190       // a.  Check: null pointer returned
191       // b.  Check: queue_0 entries count is 0
192       // c.  Check: queue_1 entries count is 0
193 	   if(oceos_dataq_read_continue(queue_0) != NULL){
194        printf("\nDataq read continue returned not null\n");
195        }   // if
196        if(oceos_dataq_get_size(queue_0)!= 0){
197        printf("\nData queue_0 entries is not equal to 0\n");
198        }   // if
199 	   if(oceos_dataq_get_size(queue_1)!= 0){
200        printf("\nData queue_1 entries is not equal to 0\n");
201        }   // if
202 
203       // 12)   Action: Task 0 exits
204       // Check:  Task 0 exit message
205       // a.  Check: queue_0 entries count is 0
206       // b.  Check: queue_1 entries count is 0
207        printf("t_consumer is exiting\n");
208        if(oceos_dataq_get_size(queue_0)!= 0){
209        printf("\nData queue_0 entries is not equal to 0\n");
210        }   // if
211 	   if(oceos_dataq_get_size(queue_1)!= 0){
212        printf("\nData queue_1 entries is not equal to 0\n");
213        }   // if
214       return;
215   }
216 }//END  t_consumer_task
217 
218 void t_producer_task() {
219   // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer
220   // Check: Task 1 has started
221   // a.  Check: Starting message from Task 1
222   // b.  Check: queue_0 entries count is 0
223   // c.  Check: queue_0 capacity is as created
224   // d.  Check: queue_1 entries count is 0
225   // e.  Check: queue_1 capacity is as created
226   printf("t_producer was started\n");
227    if(oceos_dataq_get_size(queue_0)!= 0){
228    printf("\nData queue_0 entries is not equal to 0\n");
229    }   // if
230    if(oceos_dataq_get_size(queue_1)!= 0){
231    printf("\nData queue_1 entries is not equal to 0\n");
232    }   // if
233 
234   // 2)  Action: Task 1 attempts to start Task 0
235    if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){
236    printf("\nFailed starting task t_consumer\n");
237    }   // if
238 
239   // 3) Action: Task 0 does read_restart on queue_0
240   // Check:  Task 0 exits as queue_0 is empty
241   // Check:  Task 1 continues
242   // a.  Check: continue message from Task 1
243   // b.  Check: queue_0 entries count is 0
244   // c.  Check: queue_1 entries count is 0
245    printf("t_producer continues \n");
246    if(oceos_dataq_get_size(queue_0)!= 0){
247    printf("\nData queue_0 entries is not equal to 0\n");
248    }   // if
249    if(oceos_dataq_get_size(queue_1)!= 0){
250    printf("\nData queue_1 entries is not equal to 0\n");
251    }   // if
252 
253   // 4) Action: Task 1 does read_continue on queue_1
254   // Check:   null pointer returned
255    if(oceos_dataq_read_continue(queue_1) != NULL){
256    printf("\nDataq read continue returned not null\n");
257    }   // if
258 
259   // 5) Action: Task 1 writes pointer to struct to queue_0
260    if(oceos_dataq_write(queue_0, &test_data) != SUCCESSFUL){
261    printf("\nDataq write failed\n");
262    }   // if
263 
264   // 8) Action: Task 0 does read_restart with timeout on queue_0
265   // Check:  Task 0 exits as queues_0 is empty
266   // Check:  Task 1 continues
267   // a.  Check: continue message from Task 1
268   // b.  Check: queue_0 entries count is 0
269   // c.  Check: queue_1 entries count is 1
270    printf("t_producer continues \n");
271    if(oceos_dataq_get_size(queue_0)!= 0){
272    printf("\nData queue_0 entries is not equal to 0\n");
273    }   // if
274    if(oceos_dataq_get_size(queue_1)!= 1){
275    printf("\nData queue_1 entries is not equal to 1\n");
276    }   // if
277 
278   // 9) Action: Task 1 does read_continue on queue_1
279   // Check:  Non-null pointer returned
280   // a.  Check: pointer to same struct
281   // b.  Check: queue_0 entries count is 0
282   // c.  Check: queue_1 entries count is 0
283    struct data *temp_data = oceos_dataq_read_continue(queue_1);
284    if(temp_data == NULL){
285    printf("\ntemp_data is null\n");
286    }   // if
287    if(test_data.message != temp_data->message){
288    printf("\npointer not to same struct\n");
289    }   // if
290    if(oceos_dataq_get_size(queue_0)!= 0){
291    printf("\nData queue_0 entries is not equal to 0\n");
292    }   // if
293    if(oceos_dataq_get_size(queue_1)!= 0){
294    printf("\nData queue_1 entries is not equal to 0\n");
295    }   // if
296 
297   // 10)   Action: Task 1 loops for at least three timeout period
298   // Check:  Task 0 restarts on timeout, pre-empting Task 1
299   test_wait(TIME_OUT * 3);
300 
301   //Task 1 writes pointer to struct on queue_1
302    if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
303    printf("\nDataq write failed\n");
304    }   // if
305   // Data q size check
306    if(oceos_dataq_get_size(queue_1)!= 1){
307    printf("\nData queue_1 entries is not equal to 1\n");
308    }   // if
309   // Task 1 does read restart on queue_1
310    if(oceos_dataq_read_restart(queue_1) == NULL){
311    printf("\nDataq read restart failed\n");
312    }   // if
313   // Data q size check
314    if(oceos_dataq_get_size(queue_1)!= 0){
315    printf("\nData queue_1 entries is not equal to 0\n");
316    }   // if
317   //Task 1 writes pointer to struct on queue_1
318    if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
319    printf("\nDataq write failed\n");
320    }   // if
321   // Data q size check
322    if(oceos_dataq_get_size(queue_1)!= 1){
323    printf("\nData queue_1 entries is not equal to 1\n");
324    }   // if
325   // Data q clear
326    if(oceos_dataq_clear(queue_1)!= 0){
327    printf("\nDataq clear failed\n");
328    }   // if
329   
330   // Data q size check
331    if(oceos_dataq_get_size(queue_1)!= 0){
332    printf("\nData queue_1 entries is not equal to 0\n");
333    }   // if
334   // Data pending q size check
335    if(oceos_dataq_penq_get_size(queue_1) != 0){
336    printf("\nDataq pending queue not equal to 0\n");
337    }   // if
338 
339   // 14)   Action: Task 1 terminates
340    // Check:  Task 1 exit message
341    printf("t_producer is exiting\n");
342 
343 
344 
345   // 15) Action: CPU placed in sleep mode
346   // Check:  Sleep mode starting message
347    if(oceos_exit() != SUCCESSFUL){
348    printf("\nOceos exiting failed\n");
349    }   // if
350    
351   return;
352 }