Difference between revisions of "OCEOS Tutorials"
Dtimofejevs (talk | contribs)   | 
				|||
| (26 intermediate revisions by 2 users not shown) | |||
| Line 32: | Line 32: | ||
For code example see below.  | For code example see below.  | ||
  <syntaxhighlight lang="C" line>  | '''''tut.h'''''  | ||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef TUT1_H_  | |||
#define TUT1_H_  | |||
/* Sample Task names - all here start with t_ to help avoid name confusion */  | |||
enum TASK_NAME{  | |||
    t_0,                 // High priority task  | |||
    t_1                  // Low priority task  | |||
};  | |||
char* nullPtr = "";			// Need pointer to pass to oceos_start  | |||
void (*nullFun)(void *);	// Null function  | |||
/*  | |||
  * APPLICATION FUNCTION DECLARATIONS  | |||
 */  | |||
void fun0(void *);  | |||
void fun1(void *);  | |||
#endif /* TUT1_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef INCLUDE_OCEOS_CONFIG_H_  | |||
#define INCLUDE_OCEOS_CONFIG_H_  | |||
// 1: Includes OCEOS main header file  | |||
#include "oceos.h"  | |||
//----------------------------------------------------------------------------  | |||
// 2: Number of Log entries.  | |||
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64  | |||
//----------------------------------------------------------------------------  | |||
// 3: Number of tasks  | |||
#define NUMBER_OF_TASKS                         2  // 1 to 255  | |||
//----------------------------------------------------------------------------  | |||
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);  | |||
//    Defaults to number of tasks, as each task should have aa least one job;  | |||
//    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs  | |||
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2  | |||
//----------------------------------------------------------------------------  | |||
// 5: Number of Mutexes  | |||
#define NUMBER_OF_MUTEXES                       0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 6: Number of Semaphores  | |||
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 7: Number of Data Qs  | |||
#define NUMBER_OF_DATAQS                        0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 8: LOG data array size  | |||
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 9: FIXED data array size  | |||
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 10: DYNAMIC data array size  | |||
#define DYN_DATA_ARRAY_SIZE_U32S                0x33// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 11: Timed Actions  | |||
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field  | |||
//----------------------------------------------------------------------------  | |||
// 12: Log entries base 2  | |||
#define CS_LOG_DEF_ENTRIES_BASE2                0  | |||
//----------------------------------------------------------------------------  | |||
// 13: OCEOS stack start Address  | |||
#define OCEOS_STACK_START_ADDRESS               0  | |||
//----------------------------------------------------------------------------  | |||
// 14: OCEOS stack end address  | |||
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  | |||
//----------------------------------------------------------------------------  | |||
/**  | |||
 * Target specific configurations  | |||
 */  | |||
/*  | /*  | ||
**  |  * ARM specific configurations  | ||
 */  | |||
#ifdef __SAM3X8E__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
***  | #ifdef __VA41620__  | ||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
//--------------------------------------------------------------------  | |||
// User defined function to deal with system errors  | |||
void oceos_on_error(void);  | |||
//---------------------------------------------------------------------  | |||
// User defined function to deal with log 2/3 full  | |||
void oceos_on_full_log(void);  | |||
//---------------------------------------------------------------------  | |||
extern U32_t log_data[];  | |||
extern U32_t fixed_data[];  | |||
extern U32_t dynamic_data[];  | |||
extern const unsigned int __oceos_bsp_sysfreq;  | |||
/**  | |||
 * Initialize OCEOS with user configurations  | |||
  */  |   */  | ||
int application_init(void);  | |||
#endif /* INCLUDE_OCEOS_CONFIG_H_ */  | |||
#  | |||
/  | </syntaxhighlight>  | ||
'''''oceos_config.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include "oceos_config.h"  | |||
/*  | /*  | ||
  *   |   * OCEOS INTERNAL DATA STORAGE  | ||
  *  |   *  | ||
 * This application defines arrays to hold OCEOS internal data.  | |||
 * The array sizes are provided by DMON by running "oceos info" command:</br>  | |||
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>  | |||
 *  *Run DMON command "oceos info" to get size for each array.</br>  | |||
 *  *Update array sizes below  | |||
  */  |   */  | ||
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];  | |||
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment  | |||
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];  | |||
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO  | |||
static BOOLE_t log_full_was_called = FALSE;  | |||
/**  | |||
  * Must be defined if Application is using :  | |||
 *      Dataq with timeout  | |||
 *      Semaphore with timeout  | |||
 *      Timed Actions  | |||
 */  | |||
/*  | |||
 * Set up the application configuration structure and pass it to oceos_init  | |||
 * (done this way the memory used for the structure is returned automatically)  | |||
 */  | |||
int application_init(){  | |||
     /*  |      /*  | ||
      *   |       * Create the application configuration structure  | ||
      */  |       */  | ||
     struct application_configuration           app_config = {0};  | |||
     /*  |      /*  | ||
      *   |       * Fill in the application parameters  | ||
      */  |       */  | ||
     status = oceos_start(fixed_data, t_1, (void *)nullPtr);	  |      app_config.log_address                   = (adrs_t)log_data;              // required  | ||
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required  | |||
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required  | |||
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check  | |||
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check  | |||
    app_config.system_error_function         = &oceos_on_error;               // NULL => ignore  | |||
    app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore  | |||
    // used in setting up system log and fixed data array  | |||
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default  | |||
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1  | |||
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size  | |||
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;  | |||
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;  | |||
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;  | |||
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;  | |||
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;  | |||
    app_config.use_oceos_system_time         = TRUE;  | |||
    // initialise OCEOS  | |||
    enum DIRECTIVE_STATUS status;  | |||
    status = oceos_init(app_config);  | |||
    if (SUCCESSFUL == status) {  | |||
        return 1;  | |||
    } else {  | |||
        printf("\n oceos_init failure\n");  | |||
        return -1;  | |||
    }   // else  | |||
}   // application_init()  | |||
/**  | |||
 * User to implement in case of system error;  | |||
 * Comment it out if not used and set field system_error_function in app_config to NULL  | |||
 */  | |||
void oceos_on_error() {  | |||
  return;  | |||
}  | |||
/**  | |||
 * User to implement in case of system log is 2/3 full;  | |||
 * Comment it out if not used and set field log_full_function in app_config to NULL  | |||
 */  | |||
void oceos_on_full_log(){  | |||
  log_full_was_called = TRUE;  | |||
  return;  | |||
}  | |||
</syntaxhighlight>  | |||
'''''tut1.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include <stdlib.h>  | |||
#include "tut1.h"                        // application header  | |||
#include "oceos_config.h"                // OCEOS header  | |||
int main(void) {  | |||
  int status;  | |||
  /*  | |||
   * Initialise the application configuration and OCEOS  | |||
   *  | |||
   * This application function creates the application configuration  | |||
   * and passes it to oceos_init(), which initialises the fixed data  | |||
   * and enables the system log  | |||
   */  | |||
  if (!application_init()) {  | |||
    //LOG  | |||
    return -1;  | |||
  }  | |||
  // Create Main task to  | |||
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254  | |||
                        100,// priority,  must be in range 1 to 254, lower value is higher priority  | |||
                        100,	// threshold, must be in range 1 to task priority  | |||
                        2,				// jobs_max, must be in range 1 to 15  | |||
                        0,// FALSE -> floating point hardware not used by task  | |||
                        1,				// FALSE -> task initially not enabled  | |||
                        fun0,			// main body of task  | |||
                        nullFun,		// task end function  | |||
                        0,// time_deadline, must finish no later than this after start, 0 => ignore  | |||
                        0	// minimum time expected between start requests, 0 => no restriction  | |||
                        ) != SUCCESSFUL)  | |||
    return 1;  | |||
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)  | |||
      != SUCCESSFUL)  | |||
    return 2;  | |||
  /*  | |||
   * Finish initialising OCEOS and setting up the fixed data  | |||
   */  | |||
  status = oceos_init_finish();  | |||
  if (SUCCESSFUL != status) {  | |||
    return 3;  | |||
  }   // if  | |||
  /*  | |||
   * Start OCEOS scheduling  | |||
   *  | |||
   * The OCEOS fixed data provides all the information required.  | |||
   *  | |||
   * If a valid task is specified, it is started and passed the pointer.  | |||
   * Otherwise the system is put in sleep mode  | |||
   */  | |||
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task  | |||
  return status;  | |||
}   // main  | }   // main  | ||
/*  | /*  | ||
  * Application code functions, functions declared in asw.h  |   * Application code functions, functions declared in asw.h  | ||
  */  |   */  | ||
void fun0(void * ptr){  | void fun0(void *ptr) {  | ||
  printf("Entered high priority task\n");  | |||
  oceos_task_start(t_1, ptr);  | |||
  printf("Leaving high priority task\n");  | |||
  return;  | |||
}   // fun0()  | }   // fun0()  | ||
void fun1(void *ptr) {  | |||
void fun1(void * ptr){  |   printf("Entered low priority task\n");  | ||
  oceos_task_start(t_0, ptr);  | |||
  printf("Leaving low priority task\n");  | |||
  return;  | |||
}   // fun1()  | }   // fun1()  | ||
</syntaxhighlight>  | |||
=== Tutorial 2 – Using a mutex ===  | === Tutorial 2 – Using a mutex ===  | ||
| Line 145: | Line 397: | ||
#  Two tasks as before.  | #  Two tasks as before.  | ||
# One mutex. Note the priority ceiling of the mutex  | # One mutex. Note the priority ceiling of the mutex.  | ||
# Both tasks output message when they get the mutex and when they return it  | # Both tasks output message when they get the mutex and when they return it  | ||
# Start OCEOS with the low priority task  | # Start OCEOS with the low priority task  | ||
| Line 154: | Line 406: | ||
For code example see example below:  | For code example see example below:  | ||
'''''tut2.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef TUT2_H_  | |||
#define TUT2_H_  | |||
/* Sample Task names - all here start with t_ to help avoid name confusion */  | |||
enum TASK_NAME{  | |||
    t_0,                 // High priority task  | |||
    t_1                  // Low priority task  | |||
};  | |||
/* Sample Mutex names - all here start with m_ to help avoid name confusion */  | |||
enum MUTEX_NAME{  | |||
    m_0  | |||
};  | |||
char* nullPtr = "";			// Need pointer to pass to oceos_start  | |||
void (*nullFun)(void *);	// Null function  | |||
/*  | |||
 * APPLICATION FUNCTION DECLARATIONS  | |||
 */  | |||
void fun0(void *);  | |||
void fun1(void *);  | |||
#endif /* TUT2_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.h'''''  | |||
<syntaxhighlight lang="C" line>  | <syntaxhighlight lang="C" line>  | ||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef INCLUDE_OCEOS_CONFIG_H_  | |||
#define INCLUDE_OCEOS_CONFIG_H_  | |||
// 1: Includes OCEOS main header file  | |||
#include "oceos.h"  | |||
//----------------------------------------------------------------------------  | |||
// 2: Number of Log entries.  | |||
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64  | |||
//----------------------------------------------------------------------------  | |||
// 3: Number of tasks  | |||
#define NUMBER_OF_TASKS                         2  // 1 to 255  | |||
//----------------------------------------------------------------------------  | |||
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);  | |||
//    Defaults to number of tasks, as each task should have aa least one job;  | |||
//    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs  | |||
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2  | |||
//----------------------------------------------------------------------------  | |||
// 5: Number of Mutexes  | |||
#define NUMBER_OF_MUTEXES                       1  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 6: Number of Semaphores  | |||
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 7: Number of Data Qs  | |||
#define NUMBER_OF_DATAQS                        0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 8: LOG data array size  | |||
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 9: FIXED data array size  | |||
#define FIXED_DATA_ARRAY_SIZE_U32S              0x33// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 10: DYNAMIC data array size  | |||
#define DYN_DATA_ARRAY_SIZE_U32S                0x34// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 11: Timed Actions  | |||
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field  | |||
//----------------------------------------------------------------------------  | |||
// 12: Log entries base 2  | |||
#define CS_LOG_DEF_ENTRIES_BASE2                0  | |||
//----------------------------------------------------------------------------  | |||
// 13: OCEOS stack start Address  | |||
#define OCEOS_STACK_START_ADDRESS               0  | |||
//----------------------------------------------------------------------------  | |||
// 14: OCEOS stack end address  | |||
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  | |||
//----------------------------------------------------------------------------  | |||
/**  | |||
 * Target specific configurations  | |||
 */  | |||
/*  | /*  | ||
**  |  * ARM specific configurations  | ||
 */  | |||
#ifdef __SAM3X8E__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
***  | #ifdef __VA41620__  | ||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
//--------------------------------------------------------------------  | |||
// User defined function to deal with system errors  | |||
void oceos_on_error(void);  | |||
//---------------------------------------------------------------------  | |||
// User defined function to deal with log 2/3 full  | |||
void oceos_on_full_log(void);  | |||
//---------------------------------------------------------------------  | |||
extern U32_t log_data[];  | |||
extern U32_t fixed_data[];  | |||
extern U32_t dynamic_data[];  | |||
extern const unsigned int __oceos_bsp_sysfreq;  | |||
/**  | |||
 * Initialize OCEOS with user configurations  | |||
  */  |   */  | ||
#  | int application_init(void);  | ||
#endif /* INCLUDE_OCEOS_CONFIG_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | #include <stdio.h>  | ||
#include "oceos_config.h"  | |||
#include "oceos_config.h"   | |||
/*  | /*  | ||
  *   |   * OCEOS INTERNAL DATA STORAGE  | ||
  *  |   *  | ||
 * This application defines arrays to hold OCEOS internal data.  | |||
 * The array sizes are provided by DMON by running "oceos info" command:</br>  | |||
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>  | |||
 *  *Run DMON command "oceos info" to get size for each array.</br>  | |||
 *  *Update array sizes below  | |||
  */  |   */  | ||
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];  | |||
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment  | |||
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];  | |||
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO  | |||
static BOOLE_t log_full_was_called = FALSE;  | |||
/**  | |||
 * Must be defined if Application is using :  | |||
 *      Dataq with timeout  | |||
 *      Semaphore with timeout  | |||
 *      Timed Actions  | |||
 */  | |||
/*  | |||
 * Set up the application configuration structure and pass it to oceos_init  | |||
 * (done this way the memory used for the structure is returned automatically)  | |||
 */  | |||
int application_init(){  | |||
     /*  |      /*  | ||
      *   |       * Create the application configuration structure  | ||
      */  |       */  | ||
     struct application_configuration           app_config = {0};  | |||
     /*  |      /*  | ||
      *   |       * Fill in the application parameters  | ||
      */  |       */  | ||
     status = oceos_start(fixed_data, t_1, (void *)nullPtr);	  |      app_config.log_address                   = (adrs_t)log_data;              // required  | ||
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required  | |||
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required  | |||
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check  | |||
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check  | |||
    app_config.system_error_function         = &oceos_on_error;               // NULL => ignore  | |||
    app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore  | |||
    // used in setting up system log and fixed data array  | |||
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default  | |||
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1  | |||
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size  | |||
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;  | |||
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;  | |||
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;  | |||
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;  | |||
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;  | |||
    app_config.use_oceos_system_time         = TRUE;  | |||
    // initialise OCEOS  | |||
    enum DIRECTIVE_STATUS status;  | |||
    status = oceos_init(app_config);  | |||
    if (SUCCESSFUL == status) {  | |||
        return 1;  | |||
    } else {  | |||
        printf("\n oceos_init failure\n");  | |||
        return -1;  | |||
    }   // else  | |||
}   // application_init()  | |||
/**  | |||
 * User to implement in case of system error;  | |||
 * Comment it out if not used and set field system_error_function in app_config to NULL  | |||
 */  | |||
void oceos_on_error() {  | |||
  return;  | |||
}  | |||
/**  | |||
 * User to implement in case of system log is 2/3 full;  | |||
 * Comment it out if not used and set field log_full_function in app_config to NULL  | |||
 */  | |||
void oceos_on_full_log(){  | |||
  log_full_was_called = TRUE;  | |||
  return;  | |||
}  | |||
</syntaxhighlight>  | |||
'''''tut2.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include <stdlib.h>  | |||
#include "tut2.h"                        // application header  | |||
/* N.B.  Application header is included first */  | |||
#include "oceos_config.h"                // OCEOS header for this application  | |||
#include "mutex.h"  | |||
int main(void) {  | |||
  int status;  | |||
  /*  | |||
   * Initialise the application configuration and OCEOS  | |||
   *  | |||
   * This application function creates the application configuration  | |||
   * and passes it to oceos_init(), which initialises the fixed data  | |||
   * and enables the system log  | |||
   */  | |||
  if (!application_init()) {  | |||
    //LOG  | |||
    return -1;  | |||
  }  | |||
  // Create Main task to  | |||
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254  | |||
                        100,// priority,  must be in range 1 to 254, lower value is higher priority  | |||
                        100,	// threshold, must be in range 1 to task priority  | |||
                        2,				// jobs_max, must be in range 1 to 15  | |||
                        0,// FALSE -> floating point hardware not used by task  | |||
                        1,				// FALSE -> task initially not enabled  | |||
                        fun0,			// main body of task  | |||
                        nullFun,		// task end function  | |||
                        0,// time_deadline, must finish no later than this after start, 0 => ignore  | |||
                        0	// minimum time expected between start requests, 0 => no restriction  | |||
                        ) != SUCCESSFUL)  | |||
    return 1;  | |||
  if (oceos_task_create(t_1, 200, 200, 2, 0, 1, fun1, nullFun, 0, 0)  | |||
      != SUCCESSFUL)  | |||
    return 2;  | |||
  if (oceos_mutex_create(m_0, 100) != SUCCESSFUL)	// Create mutex with ceiling of highest priority task using it  | |||
    return 3;  | |||
  /*  | |||
   * Finish initialising OCEOS and setting up the fixed data  | |||
   */  | |||
  status = oceos_init_finish();  | |||
  if (SUCCESSFUL != status) {  | |||
    return 4;  | |||
  }   // if  | |||
  /*  | |||
   * Start OCEOS scheduling  | |||
   *  | |||
   * The OCEOS fixed data provides all the information required.  | |||
   *  | |||
   * If a valid task is specified, it is started and passed the pointer.  | |||
   * Otherwise the system is put in sleep mode  | |||
   */  | |||
  status = oceos_start(fixed_data, t_1, (void*) nullPtr);	// Start OCEOS with lower prioroty task  | |||
  return status;  | |||
}   // main  | }   // main  | ||
/*  | /*  | ||
  * Application code functions, functions declared in asw.h  |   * Application code functions, functions declared in asw.h  | ||
  */  |   */  | ||
void fun0(void * ptr){  | void fun0(void *ptr) {  | ||
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {  | |||
    printf("Error from high priority task getting mutex\n");  | |||
  } else {  | |||
    printf("high priority task got mutex\n");  | |||
  }  | |||
  oceos_task_start(t_1, ptr);	// Start lower priority task  | |||
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {  | |||
    printf("Error from high priority task releasing mutex\n");  | |||
  } else {  | |||
    printf("High priority task released mutex\n");  | |||
  }  | |||
  return;  | |||
}   // fun0()  | }   // fun0()  | ||
void fun1(void *ptr) {  | |||
  if (oceos_mutex_wait(m_0) != SUCCESSFUL) {  | |||
    printf("Error from low priority task getting mutex\n");  | |||
  } else {  | |||
    printf("Low priority task got mutex\n");  | |||
  }  | |||
  oceos_task_start(t_0, ptr);	// Start higher priority task  | |||
  if (oceos_mutex_signal(m_0) != SUCCESSFUL) {  | |||
    printf("Error from low priority task releasing mutex\n");  | |||
  } else {  | |||
    printf("Low priority task released mutex\n");  | |||
  }  | |||
  return;  | |||
}   // fun1()  | |||
  </syntaxhighlight>  |   </syntaxhighlight>  | ||
| Line 308: | Line 817: | ||
For code example see below:  | For code example see below:  | ||
  <  | '''''tut3.h'''''  | ||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
  *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef TUT3_H_  | |||
#define TUT3_H_  | |||
/* Sample Task names - all here start with t_ to help avoid name confusion */  | |||
enum TASK_NAME{  | |||
    t_0,                 // Task to start other two  | |||
    t_1,                 // consumer task  | |||
    t_2                  // consumer task  | |||
};  | |||
/* Sample Counting Semaphore names - all here start with s_ to help avoid name confusion */  | |||
enum SEM_NAME{  | |||
    items,                   // Semaphore called items  | |||
    spaces                   // Semaphore called spaces  | |||
};  | |||
char* nullPtr = "";			// Need pointer to pass to oceos_start  | |||
void (*nullFun)(void *);	// Null function  | |||
/*  | |||
 * APPLICATION FUNCTION DECLARATIONS  | |||
 */  | |||
void fun0(void *);  | |||
void fun1(void *);  | |||
void fun2(void *);  | |||
#endif /* TUT3_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef INCLUDE_OCEOS_CONFIG_H_  | |||
#define INCLUDE_OCEOS_CONFIG_H_  | |||
// 1: Includes OCEOS main header file  | |||
#include "oceos.h"  | |||
//----------------------------------------------------------------------------  | |||
// 2: Number of Log entries.  | |||
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64  | |||
//----------------------------------------------------------------------------  | |||
// 3: Number of tasks  | |||
#define NUMBER_OF_TASKS                         3  // 1 to 255  | |||
//----------------------------------------------------------------------------  | |||
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);  | |||
//    Defaults to number of tasks, as each task should have aa least one job;  | |||
//    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs  | |||
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS * 2  | |||
//----------------------------------------------------------------------------  | |||
// 5: Number of Mutexes  | |||
#define NUMBER_OF_MUTEXES                       0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 6: Number of Semaphores  | |||
#define NUMBER_OF_SEMAPHORES                    2  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 7: Number of Data Qs  | |||
#define NUMBER_OF_DATAQS                        0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 8: LOG data array size  | |||
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 9: FIXED data array size  | |||
#define FIXED_DATA_ARRAY_SIZE_U32S              0x3a// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 10: DYNAMIC data array size  | |||
#define DYN_DATA_ARRAY_SIZE_U32S                0x65// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 11: Timed Actions  | |||
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field  | |||
//----------------------------------------------------------------------------  | |||
// 12: Log entries base 2  | |||
#define CS_LOG_DEF_ENTRIES_BASE2                0  | |||
//----------------------------------------------------------------------------  | |||
// 13: OCEOS stack start Address  | |||
#define OCEOS_STACK_START_ADDRESS               0  | |||
//----------------------------------------------------------------------------  | |||
// 14: OCEOS stack end address  | |||
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  | |||
//----------------------------------------------------------------------------  | |||
/**  | |||
 * Target specific configurations  | |||
 */  | |||
/*  | /*  | ||
**  |  * ARM specific configurations  | ||
 */  | |||
#ifdef __SAM3X8E__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
***  | #ifdef __VA41620__  | ||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
//--------------------------------------------------------------------  | |||
// User defined function to deal with system errors  | |||
void oceos_on_error(void);  | |||
//---------------------------------------------------------------------  | |||
// User defined function to deal with log 2/3 full  | |||
void oceos_on_full_log(void);  | |||
//---------------------------------------------------------------------  | |||
extern U32_t log_data[];  | |||
extern U32_t fixed_data[];  | |||
extern U32_t dynamic_data[];  | |||
extern const unsigned int __oceos_bsp_sysfreq;  | |||
/**  | |||
 * Initialize OCEOS with user configurations  | |||
  */  |   */  | ||
#  | int application_init(void);  | ||
#endif /* INCLUDE_OCEOS_CONFIG_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | #include <stdio.h>  | ||
#include "oceos_config.h"  | |||
#include "oceos_config.h"   | |||
/*  | /*  | ||
  *   |   * OCEOS INTERNAL DATA STORAGE  | ||
  *  |   *  | ||
 * This application defines arrays to hold OCEOS internal data.  | |||
 * The array sizes are provided by DMON by running "oceos info" command:</br>  | |||
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>  | |||
 *  *Run DMON command "oceos info" to get size for each array.</br>  | |||
 *  *Update array sizes below  | |||
  */  |   */  | ||
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];  | |||
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment  | |||
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];  | |||
int   | const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO  | ||
static BOOLE_t log_full_was_called = FALSE;  | |||
/**  | |||
 * Must be defined if Application is using :  | |||
 *      Dataq with timeout  | |||
 *      Semaphore with timeout  | |||
 *      Timed Actions  | |||
 */  | |||
/*  | |||
 * Set up the application configuration structure and pass it to oceos_init  | |||
 * (done this way the memory used for the structure is returned automatically)  | |||
 */  | |||
int application_init(){  | |||
     /*  |      /*  | ||
      *   |       * Create the application configuration structure  | ||
      */  |       */  | ||
     struct application_configuration           app_config = {0};  | |||
     /*  |      /*  | ||
      *   |       * Fill in the application parameters  | ||
      */  |       */  | ||
     status = oceos_start(fixed_data, t_0, (void *)nullPtr);	  |      app_config.log_address                   = (adrs_t)log_data;              // required  | ||
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required  | |||
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required  | |||
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check  | |||
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check  | |||
    app_config.system_error_function         = &oceos_on_error;               // NULL => ignore  | |||
    app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore  | |||
    // used in setting up system log and fixed data array  | |||
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default  | |||
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1  | |||
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size  | |||
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;  | |||
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;  | |||
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;  | |||
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;  | |||
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;  | |||
    app_config.use_oceos_system_time         = TRUE;  | |||
    // initialise OCEOS  | |||
    enum DIRECTIVE_STATUS status;  | |||
    status = oceos_init(app_config);  | |||
    if (SUCCESSFUL == status) {  | |||
        return 1;  | |||
    } else {  | |||
        printf("\n oceos_init failure\n");  | |||
        return -1;  | |||
    }   // else  | |||
}   // application_init()  | |||
/**  | |||
 * User to implement in case of system error;  | |||
 * Comment it out if not used and set field system_error_function in app_config to NULL  | |||
 */  | |||
void oceos_on_error() {  | |||
  return;  | |||
}  | |||
/**  | |||
 * User to implement in case of system log is 2/3 full;  | |||
 * Comment it out if not used and set field log_full_function in app_config to NULL  | |||
 */  | |||
void oceos_on_full_log(){  | |||
  log_full_was_called = TRUE;  | |||
  return;  | |||
}  | |||
</syntaxhighlight>  | |||
'''''tut3.c'''''  | |||
 <syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include <stdlib.h>  | |||
/* N.B.  Application header is included first */  | |||
#include "oceos_config.h"                // OCEOS header for this application  | |||
#include "tut3.h"                        // application header  | |||
#include "semaphore.h"  | |||
int main(void) {  | |||
  int status;  | |||
  /*  | |||
   * Initialise the application configuration and OCEOS  | |||
   *  | |||
   * This application function creates the application configuration  | |||
   * and passes it to oceos_init(), which initialises the fixed data  | |||
   * and enables the system log  | |||
   */  | |||
  if (!application_init()) {  | |||
    //LOG  | |||
    return -1;  | |||
  }  | |||
  // Create Main task to  | |||
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254  | |||
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority  | |||
                        10,		// threshold, must be in range 1 to task priority  | |||
                        1,				// jobs_max, must be in range 1 to 15  | |||
                        0,// FALSE -> floating point hardware not used by task  | |||
                        1,				// FALSE -> task initially not enabled  | |||
                        fun0,			// main body of task  | |||
                        nullFun,		// task end function  | |||
                        0,// time_deadline, must finish no later than this after start, 0 => ignore  | |||
                        0	// minimum time expected between start requests, 0 => no restriction  | |||
                        ) != SUCCESSFUL)  | |||
    return 1;  | |||
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)  | |||
      != SUCCESSFUL)  | |||
    return 2;  | |||
  if (oceos_task_create(t_2, 100, 100, 1, 0, 1, fun2, nullFun, 0, 0)  | |||
      != SUCCESSFUL)  | |||
    return 3;  | |||
  if (oceos_sem_create(items, 10, 0, 2, FALSE) != SUCCESSFUL)// items semaphore with max permits of 10, initial permits of 0, max jobs 2  | |||
    return 4;  | |||
  if (oceos_sem_create(spaces, 10, 4, 2, FALSE) != SUCCESSFUL)	// spaces semaphore with max permits of 10, initial permits of 4, max jobs 2  | |||
    return 4;  | |||
  /*  | |||
   * Finish initialising OCEOS and setting up the fixed data  | |||
   */  | |||
  status = oceos_init_finish();  | |||
  if (SUCCESSFUL != status) {  | |||
    return 6;  | |||
  }   // if  | |||
  /*  | |||
   * Start OCEOS scheduling  | |||
   *  | |||
   * The OCEOS fixed data provides all the information required.  | |||
   *  | |||
   * If a valid task is specified, it is started and passed the pointer.  | |||
   * Otherwise the system is put in sleep mode  | |||
   */  | |||
  status = oceos_start(fixed_data, t_0, (void*) nullPtr);	// Start OCEOS with task to start other tasks  | |||
  return status;  | |||
}   // main  | }   // main  | ||
| Line 400: | Line 1,171: | ||
  * Application code functions, functions declared in asw.h  |   * Application code functions, functions declared in asw.h  | ||
  */  |   */  | ||
void fun0(void * ptr){  | void fun0(void *ptr) {  | ||
  oceos_task_start(t_1, ptr);	// Start consumer task  | |||
  oceos_task_start(t_2, ptr);	// Start consumer task  | |||
}   // fun0()  | }   // fun0()  | ||
void fun1(void * ptr){  | void fun1(void *ptr) {  | ||
  while (1) {	// loop forever  | |||
    if (oceos_sem_wait_restart(items) != SUCCESSFUL) {  | |||
      printf("Error from task t_0 task waiting items\n");  | |||
    }  | |||
    printf("Got item\n");  | |||
    if (oceos_sem_signal(spaces) != SUCCESSFUL) {  | |||
      printf("Error from task t_0 signalling spaces\n");  | |||
     }  |      }  | ||
  }  | |||
}   // fun0()  | }   // fun0()  | ||
void fun2(void * ptr){  | void fun2(void *ptr) {  | ||
  while (1) {	// loop forever  | |||
    if (oceos_sem_wait_restart(spaces) != SUCCESSFUL) {  | |||
      printf("Error from task t_1 task waiting spaces\n");  | |||
     }  |      }  | ||
    if (oceos_sem_signal(items) != SUCCESSFUL) {  | |||
      printf("Error from task t_1 signalling items\n");  | |||
    } else {  | |||
      printf("Item done\n");  | |||
    }  | |||
  }  | |||
  return;  | |||
}   // fun1()  | }   // fun1()  | ||
  </  | |||
  </syntaxhighlight>  | |||
=== Tutorial 4 – Timer interrupt starts task ===  | === Tutorial 4 – Timer interrupt starts task ===  | ||
| Line 443: | Line 1,215: | ||
For code example see below:  | For code example see below:  | ||
'''''tut4.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
  *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef TUT4_H_  | |||
#define TUT4_H_  | |||
/* Sample Task names - all here start with t_ to help avoid name confusion */  | |||
enum TASK_NAME{  | |||
    t_0,                 // Task to setup interrupt  | |||
    t_1                  // Task to be executed by interrupt routine  | |||
};  | |||
/*  | |||
 * APPLICATION FUNCTION DECLARATIONS  | |||
 */  | |||
void fun0(void *);  | |||
void fun1(void *);  | |||
void start_task(void *arg, int source);  | |||
void timer_setup(void);  | |||
#endif /* TUT4_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#ifndef INCLUDE_OCEOS_CONFIG_H_  | |||
#define INCLUDE_OCEOS_CONFIG_H_  | |||
// 1: Includes OCEOS main header file  | |||
#include "oceos.h"  | |||
//----------------------------------------------------------------------------  | |||
// 2: Number of Log entries.  | |||
#define NUMBER_OF_LOG_ENTRIES                   64 // 16 to 1024, default 64  | |||
//----------------------------------------------------------------------------  | |||
// 3: Number of tasks  | |||
#define NUMBER_OF_TASKS                         2  // 1 to 255  | |||
//----------------------------------------------------------------------------  | |||
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);  | |||
//    Defaults to number of tasks, as each task should have aa least one job;  | |||
//    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs  | |||
#define NUMBER_OF_READYQ_ENTRIES                NUMBER_OF_TASKS + 1  | |||
//----------------------------------------------------------------------------  | |||
// 5: Number of Mutexes  | |||
#define NUMBER_OF_MUTEXES                       0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 6: Number of Semaphores  | |||
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 7: Number of Data Qs  | |||
#define NUMBER_OF_DATAQS                        0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 8: LOG data array size  | |||
#define LOG_DATA_ARRAY_SIZE_U32S                0x88// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 9: FIXED data array size  | |||
#define FIXED_DATA_ARRAY_SIZE_U32S              0x32// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 10: DYNAMIC data array size  | |||
#define DYN_DATA_ARRAY_SIZE_U32S                0x29// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 11: Timed Actions  | |||
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field  | |||
//----------------------------------------------------------------------------  | |||
// 12: Log entries base 2  | |||
#define CS_LOG_DEF_ENTRIES_BASE2                0  | |||
//----------------------------------------------------------------------------  | |||
// 13: OCEOS stack start Address  | |||
#define OCEOS_STACK_START_ADDRESS               0  | |||
//----------------------------------------------------------------------------  | |||
// 14: OCEOS stack end address  | |||
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  | |||
//----------------------------------------------------------------------------  | |||
/**  | |||
 * Target specific configurations  | |||
 */  | |||
/*  | |||
 * ARM specific configurations  | |||
 */  | |||
#ifdef __SAM3X8E__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __VA41620__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
//--------------------------------------------------------------------  | |||
// User defined function to deal with system errors  | |||
void oceos_on_error(void);  | |||
//---------------------------------------------------------------------  | |||
// User defined function to deal with log 2/3 full  | |||
void oceos_on_full_log(void);  | |||
//---------------------------------------------------------------------  | |||
extern U32_t log_data[];  | |||
extern U32_t fixed_data[];  | |||
extern U32_t dynamic_data[];  | |||
extern const unsigned int __oceos_bsp_sysfreq;  | |||
/**  | |||
 * Initialize OCEOS with user configurations  | |||
 */  | |||
int application_init(void);  | |||
#endif /* INCLUDE_OCEOS_CONFIG_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include "oceos_config.h"  | |||
/*  | |||
 * OCEOS INTERNAL DATA STORAGE  | |||
 *  | |||
 * This application defines arrays to hold OCEOS internal data.  | |||
 * The array sizes are provided by DMON by running "oceos info" command:</br>  | |||
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>  | |||
 *  *Run DMON command "oceos info" to get size for each array.</br>  | |||
 *  *Update array sizes below  | |||
 */  | |||
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];  | |||
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment  | |||
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];  | |||
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO  | |||
static BOOLE_t log_full_was_called = FALSE;  | |||
/**  | |||
 * Must be defined if Application is using :  | |||
 *      Dataq with timeout  | |||
 *      Semaphore with timeout  | |||
 *      Timed Actions  | |||
 */  | |||
/*  | |||
 * Set up the application configuration structure and pass it to oceos_init  | |||
 * (done this way the memory used for the structure is returned automatically)  | |||
 */  | |||
int application_init(){  | |||
    /*  | |||
     * Create the application configuration structure  | |||
     */  | |||
    struct application_configuration           app_config = {0};  | |||
    /*  | |||
     * Fill in the application parameters  | |||
     */  | |||
    app_config.log_address                   = (adrs_t)log_data;              // required  | |||
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required  | |||
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required  | |||
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check  | |||
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check  | |||
    app_config.system_error_function         = &oceos_on_error;               // NULL => ignore  | |||
    app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore  | |||
    // used in setting up system log and fixed data array  | |||
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default  | |||
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1  | |||
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size  | |||
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;  | |||
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;  | |||
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;  | |||
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;  | |||
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;  | |||
    app_config.use_oceos_system_time         = TRUE;  | |||
    // initialise OCEOS  | |||
    enum DIRECTIVE_STATUS status;  | |||
    status = oceos_init(app_config);  | |||
    if (SUCCESSFUL == status) {  | |||
        return 1;  | |||
    } else {  | |||
        printf("\n oceos_init failure\n");  | |||
        return -1;  | |||
    }   // else  | |||
}   // application_init()  | |||
/**  | |||
 * User to implement in case of system error;  | |||
 * Comment it out if not used and set field system_error_function in app_config to NULL  | |||
 */  | |||
void oceos_on_error() {  | |||
  return;  | |||
}  | |||
/**  | |||
 * User to implement in case of system log is 2/3 full;  | |||
 * Comment it out if not used and set field log_full_function in app_config to NULL  | |||
 */  | |||
void oceos_on_full_log(){  | |||
  log_full_was_called = TRUE;  | |||
  return;  | |||
}  | |||
</syntaxhighlight>  | |||
'''''arm_task_src.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 *********************************************************************************************************  | |||
 *                                                OCEOS  | |||
 *                                      Real-Time Operating System  | |||
 *                                                 for  | |||
 *                                        ARM Microcontroller  | |||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include <stdlib.h>  | |||
#include "tut4.h"  | |||
#include "oceos_config.h"  | |||
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)  | |||
#include "sam.h"  | |||
#define ENABLE_WAVE_MODE           (0x1 << TC_CMR_WAVE_Pos)  | |||
#define TC_CMR_WAVE_SEL_Pos        13  | |||
#define SET_WAVE_SELECT            (~(0x3 << TC_CMR_WAVE_SEL_Pos)) //00  | |||
#define TC_CMR_CPCSTOP_Pos         6  | |||
#define TC_CMR_CPCSTOP             (0x1 << TC_CMR_CPCSTOP_Pos)  | |||
static Tc *timer_regs;  | |||
static TcChannel *tc;  | |||
#endif  | |||
/*  | |||
 * Set up timer and register handler  | |||
 */  | |||
void timer_setup(){  | |||
#ifdef __SAM3X8E__  | |||
  // Enabling Peripheral Clocks  | |||
 // REmove write protect  | |||
 int pmc_was_enabled = 0;  | |||
 if (0 != (PMC->PMC_WPMR & PMC_WPMR_WPEN)) {  | |||
     PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;  | |||
     pmc_was_enabled = 1;  | |||
 }  | |||
 // Enable Clock  | |||
 PMC->PMC_PCER0 |= PMC_PCER0_PID28;  | |||
 // Enable write protect  | |||
 if (pmc_was_enabled) {  | |||
   PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;  | |||
 }  | |||
 timer_regs = (Tc *)TC0;  | |||
 tc = &(timer_regs->TC_CHANNEL[1]);  | |||
 // Enable Wave Mode  | |||
  tc->TC_CMR |= ENABLE_WAVE_MODE;  | |||
  // Set WAVESEL to 00  | |||
  tc->TC_CMR &= (U32_t)SET_WAVE_SELECT;  | |||
  // Set TC_CMR_CPCSTOP and Clock input  | |||
  tc->TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK1); // MCK/8  | |||
 // Set Block Clock  | |||
 timer_regs->TC_BMR &= (U32_t)(~(1 << 1));  | |||
 // Interrupt Enable  | |||
   // Enable Timer interrupt (RC Compare)  | |||
 tc->TC_IER = TC_IER_CPCS;  | |||
 NVIC_EnableIRQ(TC1_IRQn);  | |||
 // Set Highest Priority for interrupt number  | |||
 NVIC_SetPriority(TC1_IRQn, 1);  | |||
 float base_scaler        = (float)(__oceos_bsp_sysfreq / 2) / 1000000.0f;  | |||
 //tc->TC_RC  = base_scaler * 0x3DC6C0;  | |||
 tc->TC_RC  = base_scaler * 1349;  | |||
 // Enable clock  | |||
 tc->TC_CCR = TC_CCR_CLKEN;  | |||
 // Start clock  | |||
 tc->TC_CCR = TC_CCR_SWTRG;  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
  // Enabling Peripheral Clocks  | |||
 // REmove write protect  | |||
 int pmc_was_enabled = 0;  | |||
 if (0 != (PMC->PMC_WPMR & PMC_WPMR_WPEN)) {  | |||
     PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;  | |||
     pmc_was_enabled = 1;  | |||
 }  | |||
 // Enable Clock  | |||
 PMC->PMC_PCER0 |= PMC_PCER0_PID24;  | |||
 // Enable write protect  | |||
 if (pmc_was_enabled) {  | |||
   PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN;  | |||
 }  | |||
 timer_regs = (Tc *)TC0;  | |||
 tc = &(timer_regs->TC_CHANNEL[1]);  | |||
 // Enable Wave Mode  | |||
  tc->TC_CMR |= ENABLE_WAVE_MODE;  | |||
  // Set WAVESEL to 00  | |||
  tc->TC_CMR &= (U32_t)SET_WAVE_SELECT;  | |||
  // Set TC_CMR_CPCSTOP and Clock input  | |||
  tc->TC_CMR |= (TC_CMR_CPCSTOP | TC_CMR_TCCLKS_TIMER_CLOCK5_Val); //  | |||
 // Set Block Clock  | |||
 timer_regs->TC_BMR &= (U32_t)(~(1 << 1));  | |||
 // Interrupt Enable  | |||
 // Enable Timer interrupt (RC Compare)  | |||
 tc->TC_IER = TC_IER_CPCS;  | |||
 NVIC_EnableIRQ(TC1_IRQn);  | |||
 // Set Highest Priority for interrupt number  | |||
 NVIC_SetPriority(TC1_IRQn, 1);  | |||
 tc->TC_RC  = 0x61a8;// 1s  | |||
 // Enable clock  | |||
 tc->TC_CCR = TC_CCR_CLKEN;  | |||
 // Start clock  | |||
 tc->TC_CCR = TC_CCR_SWTRG;  | |||
#endif  | |||
}   // setup_timer()  | |||
void TC1_IRQHandler() {  | |||
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)  | |||
  tc->TC_SR;// Read to remove pending bit  | |||
#endif  | |||
  // Start task  | |||
  oceos_task_start(t_1, NULL);  | |||
#if defined(__SAM3X8E__) || defined(__SAMV71Q21__)  | |||
  tc->TC_CCR = TC_CCR_SWTRG;  | |||
#endif  | |||
}  | |||
</syntaxhighlight>  | |||
'''''tut4.c'''''  | |||
<syntaxhighlight lang="C" line>  | <syntaxhighlight lang="C" line>  | ||
/*  | /*  | ||
*********************************************************************************************************  |  *********************************************************************************************************  | ||
*                                                OCEOS  |  *                                                OCEOS  | ||
*                                      Real-Time Operating System  |  *                                      Real-Time Operating System  | ||
*                                                 for  |  *                                                 for  | ||
*                                          |  *                                        ARM Microcontroller  | ||
 *  | |||
 *                                   Example implementation of OCEOS  | |||
 *  | |||
 *  | |||
 *                               (c) Copyright 2021, O.C.E. Technology  | |||
 *                                           All Rights Reserved  | |||
 *  | |||
 *  | |||
 * Author:       jfk  | |||
 ********************************************************************************************************  | |||
 */  | |||
#include <stdio.h>  | |||
#include <stdlib.h>  | |||
/* N.B.  Application header is included first */  | |||
#include "oceos_config.h"                // OCEOS header for this application  | |||
#include "tut4.h"                        // application header  | |||
volatile U32_t count_task_start = 0;  | |||
int main(void) {  | |||
  int status;  | |||
  /*  | |||
   * Initialise the application configuration and OCEOS  | |||
   *  | |||
   * This application function creates the application configuration  | |||
   * and passes it to oceos_init(), which initialises the fixed data  | |||
   * and enables the system log  | |||
   */  | |||
  if (!application_init()) {  | |||
    //LOG  | |||
    return -1;  | |||
  }  | |||
  // Create Main task to  | |||
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254  | |||
                        10,	// priority,  must be in range 1 to 254, lower value is higher priority  | |||
                        10,		// threshold, must be in range 1 to task priority  | |||
                        1,				// jobs_max, must be in range 1 to 15  | |||
                        0,// FALSE -> floating point hardware not used by task  | |||
                        1,				// FALSE -> task initially not enabled  | |||
                        fun0,			// main body of task  | |||
                        NULL,		// task end function  | |||
                        0,// time_deadline, must finish no later than this after start, 0 => ignore  | |||
                        0	// minimum time expected between start requests, 0 => no restriction  | |||
                        ) != SUCCESSFUL)  | |||
    return 1;  | |||
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)  | |||
      != SUCCESSFUL)  | |||
    return 2;  | |||
  /*  | |||
   * Finish initialising OCEOS and setting up the fixed data  | |||
   */  | |||
  status = oceos_init_finish();  | |||
  if (SUCCESSFUL != status) {  | |||
    return 3;  | |||
  }   // if  | |||
  /*  | |||
   * Start OCEOS scheduling  | |||
   *  | |||
   * The OCEOS fixed data provides all the information required.  | |||
   *  | |||
   * If a valid task is specified, it is started and passed the pointer.  | |||
   * Otherwise the system is put in sleep mode  | |||
   */  | |||
  status = oceos_start(fixed_data, t_0, NULL);		// Start OCEOS  | |||
  return status;  | |||
}   // main  | |||
/*  | |||
 * Task 0 starting point  | |||
 */  | |||
void fun0(void *ptr) {  | |||
  timer_setup();  | |||
}   // fun0()  | |||
/**  | |||
 * Task 1 starting point;  | |||
 * Triggered from Timer IRQ handler  | |||
 */  | |||
void fun1(void *ptr) {  | |||
  printf("Task started : %u times \n", count_task_start);  | |||
  count_task_start++;  | |||
}   // fun1()  | |||
</syntaxhighlight>  | |||
=== Tutorial 5 – Using dataq with timed action ===  | |||
<p>This exercise introduces the use of dataq with timed action.</p>  | |||
# Create functions to be used by tasks  | |||
# Create one struct – pointer to these will be placed on queues  | |||
# Set timeout period T  | |||
# Create configuration structure with above configuration values for fields  | |||
# Initialize OCEOS using oceos_init()  | |||
# Create two tasks  | |||
# Create two data queues  | |||
For code example see below:  | |||
'''''tut5.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
******************************************************************************  | |||
*                                   OCEOS  | |||
*                        Real-Time Operating System  | |||
*                               for ARM/SPARC  | |||
*                              Microcontroller  | |||
*  | *  | ||
*   | *                   Application Software Example Header File  | ||
*  | *  | ||
*  | *  | ||
* File :          | *                    (c) Copyright 2021, O.C.E. Technology  | ||
*  | *                             All Rights Reserved  | ||
*  | |||
* File :        asw.h  | |||
* Author:       Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>  | |||
******************************************************************************  | |||
  */  |   */  | ||
#  | #ifndef ASW_H  | ||
#define ASW_H  | |||
#include <stdio.h>  | #include <stdio.h>  | ||
#include <stdlib.h>  | #include <stdlib.h>  | ||
#include <assert.h>  | |||
#include "oceos_config.h"    // OCEOS header  | |||
#include "oceos_timer.h"       | |||
#include "system_log.h"  | |||
#include "dataq.h"  | |||
#define N0 1  // dataq_size  | |||
#define N1 1  // dataq_size  | |||
#define JOBS0 1 // pending q size  | |||
#define JOBS1 1 // pending q size  | |||
#define TIME_OUT 1000000 // timeout  | |||
/*  | |||
 * APPLICATION FUNCTION DECLARATIONS  | |||
 */  | |||
enum TASK_NAME{  | |||
    t_consumer ,                     // will have task ID 0  | |||
    t_producer,                     // will have task ID 1  | |||
};  | |||
enum DATAQ_NAME{  | |||
  queue_0,                      // will have dataq ID 0  | |||
  queue_1,                      // will have dataq ID 1  | |||
};  | |||
void t_consumer_task(void);  | |||
void t_producer_task(void);  | |||
#endif /* ASW_H */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.h'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 * app_config.h  | |||
 *  | |||
 *  Created on: 17 Feb 2020  | |||
 *      Author: Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>  | |||
 */  | |||
#ifndef INCLUDE_OCEOS_CONFIG_H_  | |||
#define INCLUDE_OCEOS_CONFIG_H_  | |||
// 1: Includes OCEOS main header file  | |||
#include "oceos.h"  | |||
//----------------------------------------------------------------------------  | |||
// 2: Number of Log entries.  | |||
#define NUMBER_OF_LOG_ENTRIES                   16 // 16 to 1024, default 64  | |||
//----------------------------------------------------------------------------  | |||
// 3: Number of tasks  | |||
#define NUMBER_OF_TASKS                         2  // 1 to 255  | |||
//----------------------------------------------------------------------------  | |||
// 4: Number of ready queue entries, 0 to 254, see manual( MUST BE UPDATED BY USER);  | |||
//    Defaults to number of tasks, as each task should have aa least one job;  | |||
//    If Number of ready Q entries larger that number of total jobs => defaults to number of total jobs  | |||
#define NUMBER_OF_READYQ_ENTRIES                3  | |||
//----------------------------------------------------------------------------  | |||
// 5: Number of Mutexes  | |||
#define NUMBER_OF_MUTEXES                       0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 6: Number of Semaphores  | |||
#define NUMBER_OF_SEMAPHORES                    0  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 7: Number of Data Qs  | |||
#define NUMBER_OF_DATAQS                        2  // 0 to 63  | |||
//----------------------------------------------------------------------------  | |||
// 8: LOG data array size  | |||
#define LOG_DATA_ARRAY_SIZE_U32S                0x28// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 9: FIXED data array size  | |||
#define FIXED_DATA_ARRAY_SIZE_U32S              0x34// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 10: DYNAMIC data array size  | |||
#define DYN_DATA_ARRAY_SIZE_U32S                0x46// Calculated value. Read manual  | |||
//----------------------------------------------------------------------------  | |||
// 11: Timed Actions  | |||
#define NUMBER_OF_ACTION_ENTRIES                0  // User-modify field  | |||
//----------------------------------------------------------------------------  | |||
// 12: Log entries base 2  | |||
#define CS_LOG_DEF_ENTRIES_BASE2                0  | |||
//----------------------------------------------------------------------------  | |||
// 13: OCEOS stack start Address  | |||
#define OCEOS_STACK_START_ADDRESS               0  | |||
//----------------------------------------------------------------------------  | |||
// 14: OCEOS stack end address  | |||
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  | |||
//----------------------------------------------------------------------------  | |||
/**  | |||
 * Target specific configurations  | |||
 */  | |||
#ifdef __SAM3X8E__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 84                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __SAMV71Q21__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 300                                     // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
#ifdef __VA41620__  | |||
#ifndef BSP_SYSFREQ  | |||
#define BSP_SYSFREQ 100                                      // ARM target frequency in Mhz  | |||
#endif  | |||
#endif  | |||
/*   | // User defined function to deal with system errors  | ||
#include   | void oceos_on_error(void*);  | ||
#include <  | //---------------------------------------------------------------------  | ||
// User defined function to deal with log 2/3 full  | |||
void oceos_on_full_log(void*);  | |||
//---------------------------------------------------------------------  | |||
extern U32_t log_data[];  | |||
extern U32_t fixed_data[];  | |||
extern U32_t dynamic_data[];  | |||
extern const unsigned int __oceos_bsp_sysfreq;  | |||
/**  | |||
 * Initialize OCEOS with user configurations  | |||
 */  | |||
int application_init(void);  | |||
#endif /* INCLUDE_OCEOS_CONFIG_H_ */  | |||
</syntaxhighlight>  | |||
'''''oceos_config.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
 * app_config.c  | |||
 *  | |||
 *  Configuration Tamplate for OCEOS  | |||
 *  | |||
 *  Created on: 17 Feb 2020  | |||
 *      Author: Deniss Timofejevs <deniss.timofejevs@ocetechnology.com>  | |||
  */  | |||
#include <stdio.h>  | |||
#include <assert.h>  | |||
#include "oceos_config.h"  | |||
/*  | /*  | ||
  *   |   * OCEOS INTERNAL DATA STORAGE  | ||
  *  |   *  | ||
 * This application defines arrays to hold OCEOS internal data.  | |||
 * The array sizes are provided by DMON by running "oceos info" command:</br>  | |||
 *  *Set all three arrays to guessed max zise, run application for the first time and exit.</br>  | |||
 *  *Run DMON command "oceos info" to get size for each array.</br>  | |||
 *  *Update array sizes below  | |||
  */  |   */  | ||
U32_t log_data[LOG_DATA_ARRAY_SIZE_U32S];  | |||
U32_t fixed_data[FIXED_DATA_ARRAY_SIZE_U32S] = {0};     // will be in data segment  | |||
U32_t dynamic_data[DYN_DATA_ARRAY_SIZE_U32S];  | |||
const unsigned int __oceos_bsp_sysfreq = BSP_SYSFREQ * 1000 * 1000;// TODO  | |||
static BOOLE_t log_full_was_called = FALSE;  | |||
/*  | |||
 * Set up the application configuration structure and pass it to oceos_init  | |||
 * (done this way the memory used for the structure is returned automatically)  | |||
 */  | |||
int application_init(){  | |||
    /*  | |||
     * Create the application configuration structure  | |||
     */  | |||
    struct application_configuration           app_config = {0};  | |||
    /*  | |||
     * Fill in the application parameters  | |||
     */  | |||
    app_config.log_address                   = (adrs_t)log_data;              // required  | |||
    app_config.fixed_data_address            = (adrs_t)fixed_data;            // required  | |||
    app_config.dynamic_data_address          = (adrs_t)dynamic_data;          // required  | |||
    app_config.stack_start_address           = OCEOS_STACK_START_ADDRESS;     // 0 => no check  | |||
    app_config.stack_lower_bound_address     = OCEOS_STACK_LOW_BOUND_ADDRESS; // 0 => no check  | |||
    app_config.system_error_function         = &oceos_on_error;               // NULL => ignore  | |||
    app_config.log_full_function             = &oceos_on_full_log;            // NULL => ignore  | |||
    // used in setting up system log and fixed data array  | |||
    app_config.log_number_of_entries         = NUMBER_OF_LOG_ENTRIES;         // 0 => use default  | |||
    app_config.number_of_tasks               = NUMBER_OF_TASKS;               // >= 1  | |||
    app_config.number_of_readyQ_entries      = NUMBER_OF_READYQ_ENTRIES;      // 0 => calculate size  | |||
    app_config.number_of_mutexes             = NUMBER_OF_MUTEXES;  | |||
    app_config.number_of_counting_semaphores = NUMBER_OF_SEMAPHORES;  | |||
    app_config.number_of_data_queues         = NUMBER_OF_DATAQS;  | |||
    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;  | |||
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;  | |||
    app_config.use_oceos_system_time         = TRUE;  | |||
    // initialise OCEOS  | |||
    enum DIRECTIVE_STATUS status;  | |||
    status = oceos_init(app_config);  | |||
    assert(SUCCESSFUL == status);  | |||
    if (SUCCESSFUL == status) {  | |||
        return 1;  | |||
    } else {  | |||
        printf("\n oceos_init failure\n");  | |||
        return -1;  | |||
    }   // else  | |||
}   // application_init()  | |||
/**  | |||
 * User to implement in case of system error;  | |||
 * Comment it out if not used and set field system_error_function in app_config to NULL  | |||
 */  | |||
void oceos_on_error(void* ptr) {  | |||
  return;  | |||
}  | |||
/**  | |||
 * User to implement in case of system log is 2/3 full;  | |||
 * Comment it out if not used and set field log_full_function in app_config to NULL  | |||
 */  | |||
void oceos_on_full_log(void* ptr){  | |||
  log_full_was_called = TRUE;  | |||
  return;  | |||
}  | |||
</syntaxhighlight>  | |||
'''''tut5.c'''''  | |||
<syntaxhighlight lang="C" line>  | |||
/*  | |||
******************************************************************************  | |||
*                                   OCEOS  | |||
*                        Real-Time Operating System  | |||
*                              for ARM/SPARC  | |||
*                             Microcontroller  | |||
*  | |||
*                       Application Software Example  | |||
*  | |||
*  | |||
*                    (c) Copyright 2022, O.C.E. Technology  | |||
*                             All Rights Reserved  | |||
*  | |||
* Author:       jfk  | |||
*  | |||
* Purpose                : The test here involves creating two tasks with different priorities,   | |||
*						   and two data queues with timed action implimentation.  | |||
*  | |||
******************************************************************************  | |||
*/  | |||
/* N.B.  Application header is included first */  | |||
#include "tut5.h"                        // application header  | |||
struct data {  | |||
  int status;  | |||
  char *message;  | |||
} test_data = {  | |||
    1,  | |||
    "Test Data",  | |||
};  | |||
int main(void) {  | int main(void) {  | ||
     /*  |      /*  | ||
      * Initialise the application configuration and OCEOS  |       * Initialise the application configuration and OCEOS  | ||
| Line 492: | Line 2,019: | ||
     if ( !application_init()) {  |      if ( !application_init()) {  | ||
         //LOG  |          //LOG  | ||
        printf("\nProblem\n");  | |||
         return -1;  |          return -1;  | ||
     }  |      }  | ||
     if ( oceos_task_create(  |      enum DIRECTIVE_STATUS status;  | ||
    // 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  | |||
    status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);  | |||
      if(SUCCESSFUL != status){  | |||
        // LOG  | |||
        printf("\nAbandoning, problem creating task t_consumer, resulting return code: %u\n", status);  | |||
        return -1;  | |||
      }   // if  | |||
    // 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  | |||
    status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);  | |||
	  if(SUCCESSFUL != status){  | |||
        // LOG  | |||
        printf("\nAbandoning, problem creating task t_producer, resulting return code: %u\n", status);  | |||
        return -1;  | |||
      }   // if  | |||
    printf("\n Tasks created\n");  | |||
    // no counting semaphores, data queues or user defined traps  | |||
    // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE  | |||
     status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);  | |||
     if(SUCCESSFUL != status){  | |||
        printf("\nProblem creating dataq queue_0, resulting return code: %u\n", status);  | |||
     }   // if  | |||
	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE  | |||
      status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);  | |||
      if(SUCCESSFUL != status){  | |||
       printf("\nProblem creating dataq queue_1, resulting return code: %u\n", status);  | |||
      }   // if  | |||
     /*  |      /*  | ||
      * Finish initialising OCEOS and setting up the fixed data  |       * Finish initialising OCEOS and setting up the fixed data  | ||
| Line 516: | Line 2,059: | ||
     status = oceos_init_finish();  |      status = oceos_init_finish();  | ||
     if(SUCCESSFUL != status){  |      if(SUCCESSFUL != status){  | ||
     printf("\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n", status);  | |||
     return -1;  | |||
     }   // if  |      }   // if  | ||
     /  |      //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer  | ||
     status = oceos_start(fixed_data, t_producer, NULL);  | |||
     return status;                          // returned as an integer  | |||
     status = oceos_start(fixed_data,   | |||
     return status;  | |||
}   // function waits for specific time interval  | |||
void test_wait(U32_t interval) {  | |||
  volatile U32_t start_time = oceos_time_sys_get32();  | |||
  volatile U32_t cur_time = 0;  | |||
  while(1) {  | |||
      cur_time = oceos_time_sys_get32();  | |||
      if ((cur_time - start_time) >= interval ) {  | |||
          break;  | |||
      }  | |||
  }  | |||
}  | |||
/*  | /*  | ||
  *   |   * Tasks  | ||
  */  |   */  | ||
void   | void t_consumer_task() {  | ||
  static int case_number = 0;  | |||
  if (case_number == 0) {  | |||
      case_number++;  | |||
      // 2)  Action: Task 1 attempts to start Task 0  | |||
      // Check:  Task 0 has started, pre-empting Task 1  | |||
      // a.  Check: entry message from Task 0  | |||
      // b.  Check: queue_0 entries is 0  | |||
      // c.  Check: queue_1 entries is 0  | |||
      printf("t_consumer was started\n");  | |||
       if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      // 3) Action: Task 0 does read_restart on queue_0  | |||
      oceos_dataq_read_restart_timeout(queue_0, 0);  | |||
  } else if (case_number == 1){  | |||
      case_number++;  | |||
      // 5) Action: Task 1 writes pointer to struct to queue_0  | |||
      // Check:  Task 0 has started, pre-empting Task 1  | |||
      // a.  Check: entry message from Task 0  | |||
      // b.  Check: queue_0 entries count is 1  | |||
      // c.  Check: queue_1 entries count is 0  | |||
       printf("t_consumer was started\n");  | |||
	   if(oceos_dataq_get_size(queue_0)!= 1){  | |||
       printf("\nData queue_0 entries is not equal to 1\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      // 6) Action: Task 0 does read_restart on queue 0  | |||
      // Check:  Task 0 has succeeded  | |||
      // a.  Check: non-null pointer returned  | |||
      // b.  Check: queue_0 entries count is 0  | |||
      // c.  Check: queue_0 entries count is 0  | |||
	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){  | |||
       printf("\nDataq read restart timeout returned null\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
       if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      // 7)    Action: Task 0 writes this pointer to queue_1  | |||
      // Check:  Task 0 has succeeded  | |||
      // a.  Check: queue_0 entries count is 0  | |||
      // b.  Check: queue_1 entries count is 1  | |||
	   if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){  | |||
       printf("\nDataq write was not succesful\n");  | |||
       }   // if  | |||
       if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 1){  | |||
       printf("\nData queue_1 entries is not equal to 1\n");  | |||
       }   // if  | |||
      // 8) Action: Task 0 does read_restart with timeout on queue_0  | |||
      // Check:  Task 0 exits as queues_0 is empty  | |||
	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){  | |||
       printf("\nDataq read restart timeout returned not null\n");  | |||
       }   // if  | |||
  } else {  | |||
      case_number++;  | |||
      // 10)   Action: Task 1 loops for at least twice timeout period T  | |||
      // Check:  Task 0 restarts on timeout, pre-empting Task 1  | |||
      // a.  Check: entry message from Task 0  | |||
      // b.  Check: queue_0 entries count is 0  | |||
      // c.  Check: queue_1 entries count is 0  | |||
       printf("t_consumer was started\n");  | |||
	   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      // 11)    Action: Task 0 does read_continue on queue_0  | |||
      // Check:  Task 0 has succeeded  | |||
      // a.  Check: null pointer returned  | |||
      // b.  Check: queue_0 entries count is 0  | |||
      // c.  Check: queue_1 entries count is 0  | |||
	   if(oceos_dataq_read_continue(queue_0) != NULL){  | |||
       printf("\nDataq read continue returned not null\n");  | |||
       }   // if  | |||
       if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      // 12)   Action: Task 0 exits  | |||
      // Check:  Task 0 exit message  | |||
      // a.  Check: queue_0 entries count is 0  | |||
      // b.  Check: queue_1 entries count is 0  | |||
       printf("t_consumer is exiting\n");  | |||
       if(oceos_dataq_get_size(queue_0)!= 0){  | |||
       printf("\nData queue_0 entries is not equal to 0\n");  | |||
       }   // if  | |||
	   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
       printf("\nData queue_1 entries is not equal to 0\n");  | |||
       }   // if  | |||
      return;  | |||
  }  | |||
}//END  t_consumer_task  | |||
void t_producer_task() {  | |||
  // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer  | |||
  // Check: Task 1 has started  | |||
  // a.  Check: Starting message from Task 1  | |||
  // b.  Check: queue_0 entries count is 0  | |||
  // c.  Check: queue_0 capacity is as created  | |||
  // d.  Check: queue_1 entries count is 0  | |||
  // e.  Check: queue_1 capacity is as created  | |||
  printf("t_producer was started\n");  | |||
   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
   printf("\nData queue_0 entries is not equal to 0\n");  | |||
   }   // if  | |||
   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
   printf("\nData queue_1 entries is not equal to 0\n");  | |||
   }   // if  | |||
  // 2)  Action: Task 1 attempts to start Task 0  | |||
   if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){  | |||
   printf("\nFailed starting task t_consumer\n");  | |||
   }   // if  | |||
  // 3) Action: Task 0 does read_restart on queue_0  | |||
  // Check:  Task 0 exits as queue_0 is empty  | |||
  // Check:  Task 1 continues  | |||
  // a.  Check: continue message from Task 1  | |||
  // b.  Check: queue_0 entries count is 0  | |||
  // c.  Check: queue_1 entries count is 0  | |||
   printf("t_producer continues \n");  | |||
   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
   printf("\nData queue_0 entries is not equal to 0\n");  | |||
   }   // if  | |||
   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
   printf("\nData queue_1 entries is not equal to 0\n");  | |||
   }   // if  | |||
  // 4) Action: Task 1 does read_continue on queue_1  | |||
  // Check:   null pointer returned  | |||
   if(oceos_dataq_read_continue(queue_1) != NULL){  | |||
   printf("\nDataq read continue returned not null\n");  | |||
   }   // if  | |||
  // 5) Action: Task 1 writes pointer to struct to queue_0  | |||
   if(oceos_dataq_write(queue_0, &test_data) != SUCCESSFUL){  | |||
   printf("\nDataq write failed\n");  | |||
   }   // if  | |||
  // 8) Action: Task 0 does read_restart with timeout on queue_0  | |||
  // Check:  Task 0 exits as queues_0 is empty  | |||
  // Check:  Task 1 continues  | |||
  // a.  Check: continue message from Task 1  | |||
  // b.  Check: queue_0 entries count is 0  | |||
  // c.  Check: queue_1 entries count is 1  | |||
   printf("t_producer continues \n");  | |||
   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
   printf("\nData queue_0 entries is not equal to 0\n");  | |||
   }   // if  | |||
   if(oceos_dataq_get_size(queue_1)!= 1){  | |||
   printf("\nData queue_1 entries is not equal to 1\n");  | |||
   }   // if  | |||
  // 9) Action: Task 1 does read_continue on queue_1  | |||
  // Check:  Non-null pointer returned  | |||
  // a.  Check: pointer to same struct  | |||
  // b.  Check: queue_0 entries count is 0  | |||
  // c.  Check: queue_1 entries count is 0  | |||
   struct data *temp_data = oceos_dataq_read_continue(queue_1);  | |||
   if(temp_data == NULL){  | |||
   printf("\ntemp_data is null\n");  | |||
   }   // if  | |||
   if(test_data.message != temp_data->message){  | |||
   printf("\npointer not to same struct\n");  | |||
   }   // if  | |||
   if(oceos_dataq_get_size(queue_0)!= 0){  | |||
   printf("\nData queue_0 entries is not equal to 0\n");  | |||
   }   // if  | |||
   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
   printf("\nData queue_1 entries is not equal to 0\n");  | |||
   }   // if  | |||
  // 10)   Action: Task 1 loops for at least three timeout period  | |||
  // Check:  Task 0 restarts on timeout, pre-empting Task 1  | |||
  test_wait(TIME_OUT * 3);  | |||
  //Task 1 writes pointer to struct on queue_1  | |||
   if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){  | |||
   printf("\nDataq write failed\n");  | |||
   }   // if  | |||
  // Data q size check  | |||
   if(oceos_dataq_get_size(queue_1)!= 1){  | |||
   printf("\nData queue_1 entries is not equal to 1\n");  | |||
   }   // if  | |||
  // Task 1 does read restart on queue_1  | |||
   if(oceos_dataq_read_restart(queue_1) == NULL){  | |||
   printf("\nDataq read restart failed\n");  | |||
   }   // if  | |||
  // Data q size check  | |||
   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
   printf("\nData queue_1 entries is not equal to 0\n");  | |||
   }   // if  | |||
  //Task 1 writes pointer to struct on queue_1  | |||
   if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){  | |||
   printf("\nDataq write failed\n");  | |||
   }   // if  | |||
  // Data q size check  | |||
   if(oceos_dataq_get_size(queue_1)!= 1){  | |||
   printf("\nData queue_1 entries is not equal to 1\n");  | |||
   }   // if  | |||
  // Data q clear  | |||
   if(oceos_dataq_clear(queue_1)!= 0){  | |||
   printf("\nDataq clear failed\n");  | |||
   }   // if  | |||
  // Data q size check  | |||
   if(oceos_dataq_get_size(queue_1)!= 0){  | |||
   printf("\nData queue_1 entries is not equal to 0\n");  | |||
   }   // if  | |||
  // Data pending q size check  | |||
   if(oceos_dataq_penq_get_size(queue_1) != 0){  | |||
   printf("\nDataq pending queue not equal to 0\n");  | |||
   }   // if  | |||
  // 14)   Action: Task 1 terminates  | |||
   // Check:  Task 1 exit message  | |||
   printf("t_producer is exiting\n");  | |||
  // 15) Action: CPU placed in sleep mode  | |||
   // Check:  Sleep mode starting message  | |||
/  |    if(oceos_exit() != SUCCESSFUL){  | ||
   printf("\nOceos exiting failed\n");  | |||
   }   // if  | |||
   return;  | |||
}  | }  | ||
</syntaxhighlight>  | </syntaxhighlight>  | ||
Latest revision as of 17:38, 7 March 2022
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.
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.
- 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:
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.
- 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:
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.
- 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:
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.
- Create functions to be used by tasks
 - Create one struct – pointer to these will be placed on queues
 - Set timeout period T
 - Create configuration structure with above configuration values for fields
 - Initialize OCEOS using oceos_init()
 - Create two tasks
 - 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       // 3) Action: Task 0 does read_restart on queue_0
122       oceos_dataq_read_restart_timeout(queue_0, 0);
123   } else if (case_number == 1){
124       case_number++;
125       // 5) Action: Task 1 writes pointer to struct to queue_0
126       // Check:  Task 0 has started, pre-empting Task 1
127       // a.  Check: entry message from Task 0
128       // b.  Check: queue_0 entries count is 1
129       // c.  Check: queue_1 entries count is 0
130        printf("t_consumer was started\n");
131 	   if(oceos_dataq_get_size(queue_0)!= 1){
132        printf("\nData queue_0 entries is not equal to 1\n");
133        }   // if
134 	   if(oceos_dataq_get_size(queue_1)!= 0){
135        printf("\nData queue_1 entries is not equal to 0\n");
136        }   // if
137 
138       // 6) Action: Task 0 does read_restart on queue 0
139       // Check:  Task 0 has succeeded
140       // a.  Check: non-null pointer returned
141       // b.  Check: queue_0 entries count is 0
142       // c.  Check: queue_0 entries count is 0
143 	   if(oceos_dataq_read_restart_timeout(queue_0, 0) == NULL){
144        printf("\nDataq read restart timeout returned null\n");
145        }   // if
146 	   if(oceos_dataq_get_size(queue_0)!= 0){
147        printf("\nData queue_0 entries is not equal to 0\n");
148        }   // if
149        if(oceos_dataq_get_size(queue_1)!= 0){
150        printf("\nData queue_1 entries is not equal to 0\n");
151        }   // if
152 
153       // 7)    Action: Task 0 writes this pointer to queue_1
154       // Check:  Task 0 has succeeded
155       // a.  Check: queue_0 entries count is 0
156       // b.  Check: queue_1 entries count is 1
157 	   if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
158        printf("\nDataq write was not succesful\n");
159        }   // if
160        if(oceos_dataq_get_size(queue_0)!= 0){
161        printf("\nData queue_0 entries is not equal to 0\n");
162        }   // if
163 	   if(oceos_dataq_get_size(queue_1)!= 1){
164        printf("\nData queue_1 entries is not equal to 1\n");
165        }   // if
166 
167       // 8) Action: Task 0 does read_restart with timeout on queue_0
168       // Check:  Task 0 exits as queues_0 is empty
169 	   if(oceos_dataq_read_restart_timeout(queue_0, TIME_OUT) != NULL){
170        printf("\nDataq read restart timeout returned not null\n");
171        }   // if
172   } else {
173       case_number++;
174       // 10)   Action: Task 1 loops for at least twice timeout period T
175       // Check:  Task 0 restarts on timeout, pre-empting Task 1
176       // a.  Check: entry message from Task 0
177       // b.  Check: queue_0 entries count is 0
178       // c.  Check: queue_1 entries count is 0
179        printf("t_consumer was started\n");
180 	   if(oceos_dataq_get_size(queue_0)!= 0){
181        printf("\nData queue_0 entries is not equal to 0\n");
182        }   // if
183 	   if(oceos_dataq_get_size(queue_1)!= 0){
184        printf("\nData queue_1 entries is not equal to 0\n");
185        }   // if
186 
187       // 11)    Action: Task 0 does read_continue on queue_0
188       // Check:  Task 0 has succeeded
189       // a.  Check: null pointer returned
190       // b.  Check: queue_0 entries count is 0
191       // c.  Check: queue_1 entries count is 0
192 	   if(oceos_dataq_read_continue(queue_0) != NULL){
193        printf("\nDataq read continue returned not null\n");
194        }   // if
195        if(oceos_dataq_get_size(queue_0)!= 0){
196        printf("\nData queue_0 entries is not equal to 0\n");
197        }   // if
198 	   if(oceos_dataq_get_size(queue_1)!= 0){
199        printf("\nData queue_1 entries is not equal to 0\n");
200        }   // if
201 
202       // 12)   Action: Task 0 exits
203       // Check:  Task 0 exit message
204       // a.  Check: queue_0 entries count is 0
205       // b.  Check: queue_1 entries count is 0
206        printf("t_consumer is exiting\n");
207        if(oceos_dataq_get_size(queue_0)!= 0){
208        printf("\nData queue_0 entries is not equal to 0\n");
209        }   // if
210 	   if(oceos_dataq_get_size(queue_1)!= 0){
211        printf("\nData queue_1 entries is not equal to 0\n");
212        }   // if
213       return;
214   }
215 }//END  t_consumer_task
216 
217 void t_producer_task() {
218   // 1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer
219   // Check: Task 1 has started
220   // a.  Check: Starting message from Task 1
221   // b.  Check: queue_0 entries count is 0
222   // c.  Check: queue_0 capacity is as created
223   // d.  Check: queue_1 entries count is 0
224   // e.  Check: queue_1 capacity is as created
225   printf("t_producer was started\n");
226    if(oceos_dataq_get_size(queue_0)!= 0){
227    printf("\nData queue_0 entries is not equal to 0\n");
228    }   // if
229    if(oceos_dataq_get_size(queue_1)!= 0){
230    printf("\nData queue_1 entries is not equal to 0\n");
231    }   // if
232 
233   // 2)  Action: Task 1 attempts to start Task 0
234    if(oceos_task_start(t_consumer, NULL)!= SUCCESSFUL){
235    printf("\nFailed starting task t_consumer\n");
236    }   // if
237 
238   // 3) Action: Task 0 does read_restart on queue_0
239   // Check:  Task 0 exits as queue_0 is empty
240   // Check:  Task 1 continues
241   // a.  Check: continue message from Task 1
242   // b.  Check: queue_0 entries count is 0
243   // c.  Check: queue_1 entries count is 0
244    printf("t_producer continues \n");
245    if(oceos_dataq_get_size(queue_0)!= 0){
246    printf("\nData queue_0 entries is not equal to 0\n");
247    }   // if
248    if(oceos_dataq_get_size(queue_1)!= 0){
249    printf("\nData queue_1 entries is not equal to 0\n");
250    }   // if
251 
252   // 4) Action: Task 1 does read_continue on queue_1
253   // Check:   null pointer returned
254    if(oceos_dataq_read_continue(queue_1) != NULL){
255    printf("\nDataq read continue returned not null\n");
256    }   // if
257 
258   // 5) Action: Task 1 writes pointer to struct to queue_0
259    if(oceos_dataq_write(queue_0, &test_data) != SUCCESSFUL){
260    printf("\nDataq write failed\n");
261    }   // if
262 
263   // 8) Action: Task 0 does read_restart with timeout on queue_0
264   // Check:  Task 0 exits as queues_0 is empty
265   // Check:  Task 1 continues
266   // a.  Check: continue message from Task 1
267   // b.  Check: queue_0 entries count is 0
268   // c.  Check: queue_1 entries count is 1
269    printf("t_producer continues \n");
270    if(oceos_dataq_get_size(queue_0)!= 0){
271    printf("\nData queue_0 entries is not equal to 0\n");
272    }   // if
273    if(oceos_dataq_get_size(queue_1)!= 1){
274    printf("\nData queue_1 entries is not equal to 1\n");
275    }   // if
276 
277   // 9) Action: Task 1 does read_continue on queue_1
278   // Check:  Non-null pointer returned
279   // a.  Check: pointer to same struct
280   // b.  Check: queue_0 entries count is 0
281   // c.  Check: queue_1 entries count is 0
282    struct data *temp_data = oceos_dataq_read_continue(queue_1);
283    if(temp_data == NULL){
284    printf("\ntemp_data is null\n");
285    }   // if
286    if(test_data.message != temp_data->message){
287    printf("\npointer not to same struct\n");
288    }   // if
289    if(oceos_dataq_get_size(queue_0)!= 0){
290    printf("\nData queue_0 entries is not equal to 0\n");
291    }   // if
292    if(oceos_dataq_get_size(queue_1)!= 0){
293    printf("\nData queue_1 entries is not equal to 0\n");
294    }   // if
295 
296   // 10)   Action: Task 1 loops for at least three timeout period
297   // Check:  Task 0 restarts on timeout, pre-empting Task 1
298   test_wait(TIME_OUT * 3);
299 
300   //Task 1 writes pointer to struct on queue_1
301    if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
302    printf("\nDataq write failed\n");
303    }   // if
304   // Data q size check
305    if(oceos_dataq_get_size(queue_1)!= 1){
306    printf("\nData queue_1 entries is not equal to 1\n");
307    }   // if
308   // Task 1 does read restart on queue_1
309    if(oceos_dataq_read_restart(queue_1) == NULL){
310    printf("\nDataq read restart failed\n");
311    }   // if
312   // Data q size check
313    if(oceos_dataq_get_size(queue_1)!= 0){
314    printf("\nData queue_1 entries is not equal to 0\n");
315    }   // if
316   //Task 1 writes pointer to struct on queue_1
317    if(oceos_dataq_write(queue_1, &test_data) != SUCCESSFUL){
318    printf("\nDataq write failed\n");
319    }   // if
320   // Data q size check
321    if(oceos_dataq_get_size(queue_1)!= 1){
322    printf("\nData queue_1 entries is not equal to 1\n");
323    }   // if
324   // Data q clear
325    if(oceos_dataq_clear(queue_1)!= 0){
326    printf("\nDataq clear failed\n");
327    }   // if
328   
329   // Data q size check
330    if(oceos_dataq_get_size(queue_1)!= 0){
331    printf("\nData queue_1 entries is not equal to 0\n");
332    }   // if
333   // Data pending q size check
334    if(oceos_dataq_penq_get_size(queue_1) != 0){
335    printf("\nDataq pending queue not equal to 0\n");
336    }   // if
337 
338   // 14)   Action: Task 1 terminates
339    // Check:  Task 1 exit message
340    printf("t_producer is exiting\n");
341 
342   // 15) Action: CPU placed in sleep mode
343   // Check:  Sleep mode starting message
344    if(oceos_exit() != SUCCESSFUL){
345    printf("\nOceos exiting failed\n");
346    }   // if
347    
348   return;
349 }