OCEOS/oceos use

From wiki
Jump to navigation Jump to search

Introduction

OCEOS is provided as an object library, documentation and example source code.
Setup for the use of OCEOS requires the user to prepare the development environment. At a minimum this requires the installation for compilers, debug tool, editors, …etc.

The OCEOS build and test environment requires the following:

  1. SPARC Build environment (compiler, linker, libraries, etc.) Download here.
  2. ARM Build environment Download here and Download here
  3. Debug software tool e.g. OCE’s DMON. Evaluation download.

Content of Customer Release

Documentation/
             OCEOS_User_Manual.pdf   // OCEOS User Manual
Examples/
         AreaDisplay/                // OCEOS project to display sizes of data areas described HERE
         arm_startup/                // Some start up files for Microchip Cortex-M3 and M7 developments boards, used in DEMO projects below
         asw/                        // DEMO project of main OCEOS features
         SampleProject/              // Skeleton project that can be used to start development  
         tut1/                       // This project demonstrates starting tasks with different priorities.
         tut2/                       // This project familiarize the developer with the use a mutexes.
         tut3/                       // This project demonstrates the use of semaphores for task synchronization.
         tut4/                       // This project introduces the use of timer interrupts to start the task.
         tut5/                       // This project introduces the use of data queue with timeouts.
include/                             // OCEOS header files
OCEOS_GCC_LIB/
              liboceos.lib           // OCEOS library that can be linked with application
              README.txt             // Notes

OCEOS Normal operations

The scheduling is started after calling oceos_start(). The main structure of application flow is described below:

  1. oceos_init() - Initialize fixed data and start system time and log
  2. Create:
  3. oceos_init_finish() - Initialize dynamic data area
  4. oceos_start() - Start the scheduler and pass control to first task

Note

It is mandatory to create the number of tasks, mutexes, semaphores, and data queues declared in oceos_config.h otherwise oceos_init_finish() will return an error.

OCEOS configuration parameters are shown below. In provided demo projects these are oceos_config.h and oceos_config.c. More information can be found by clicking on the link for parameter that is of interest.

// 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                         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                10
//----------------------------------------------------------------------------
// 5: Number of Mutexes
#define NUMBER_OF_MUTEXES                       2  // 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                0x100 // Calculated value. Read manual
//----------------------------------------------------------------------------
// 9: FIXED data array size
#define FIXED_DATA_ARRAY_SIZE_U32S              0x100 // Calculated value. Read manual
//----------------------------------------------------------------------------
// 10: DYNAMIC data array size
#define DYN_DATA_ARRAY_SIZE_U32S                0x100 // 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  // Used by DMON OCEOS profile to display stack usage
//----------------------------------------------------------------------------
// 14: OCEOS stack end address
#define OCEOS_STACK_LOW_BOUND_ADDRESS           0  // Used by DMON OCEOS profile to display stack usage

application_init() function shown below creates OCEOS configuration struct and sets configuration parameter that passed to oceos_init().

/*
 * 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
#ifdef __sparc__
    /**
     * FOR SPARC TARGET ONLY.
     * Not Used for ARM. Always Nested
     */
    app_config.interrupt_nesting_enabled     = TRUE;                          // Nesting Enabled
#endif
    // 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;

#ifdef __sparc__
    /**
     * FOR SPARC TARGET ONLY.
     * ARM SysTick is used for System Time
     */
    app_config.sys_time_timer_index          = SYS_TIME_TIMER_INDEX;          // 0 => invalid index
#endif

    app_config.timed_actions_queue_size      = NUMBER_OF_ACTION_ENTRIES;
    app_config.CS_log_entries_base2          = CS_LOG_DEF_ENTRIES_BASE2;
    // System time is used by timed actions, semaphores with timeout, dataqs with timeout, logging and profiling.
    // If all of above are not required then system time can be disabled. The system will not be interrupted by SysTick while CPU in sleep mode,
    //but it is not the case for SPARC targets,
    // as system time implemented by chaining two timers without interrupting.
    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()

Building the example application

OCE Technology provides sample make files that can be used by application developer. Those files are located in demo projects of Examples folder. If make is called from one of the demo projects, than user requires only to modify variable TOOLCHAIN_PATH in tools_config_arm.mk to point to toolchain folder. User can use make files to build project for one of the supported development board.

Note

User requires to modify make files to add own development board.

Make file available parameters for ARM:

  • Build target: all
  • ARM_BUILD=1
  • TOOLCHAIN=armclangv6|gcc|segger|iar
  • RELEASE=0|1
  • MCPU=cortex-m3|cortex-m7
  • BOARD=ATSAM3X8E|ATSAMV71Q21
  • FPU=0|1
  • SAMV71_CONSOLE=0|1
Example:
make all ARM_BUILD=1 FPU=1 TOOLCHAIN=gcc RELEASE=1 MCPU=cortex-m7 BOARD=ATSAMV71Q21

Make file available parameters for SPARC:

  • Build target: all
  • TOOLCHAIN=gcc|clang
  • RELEASE=0|1
  • MREX=1
  • BSP=gr716|pm698|gr712rc|gr740|agga4|at697
Example:
make all TOOLCHAIN=clang BSP=gr716
or 
make all TOOLCHAIN=clang BSP=gr716 MREX=1

Troubleshooting

oceos_init_interrrupt_manager() is failing with data store error

Solution

OCEOS is initializing interrupt trap table with OCEOS handler, replacing default handlers. If application is run from flash, than replacing interrupt trap table entries give data store error, as it cannot write to flash.

We would suggest you to move interrupt vector table __bcc_trap_table_svt_1 to SRAM. __bcc_trap_table_svt_1 is a weak symbol, so could be recreated and replaced by linker. If you are planning to add other trap handlers, you need to modify trap tables at compile time or move all trap tables to SRAM to use bcc_set_trap() at run time.

OCEOS Demo Tutorials

Tutorial 1 – Starting tasks

This exercise demonstrates starting tasks with different priorities.

  1. Two tasks, one higher priority (i.e. lower priority value), one lower priority (i.e. higher priority value. Each task allowed to have up to two concurrent jobs.
  2. Each task outputs a message when it starts, another message when it exits.
  3. Start OCEOS with the low priority task.
  4. This starts the high priority task and then exits.
  5. The high priority task starts the low priority tasks and exits.

For code example see below.

tut.h

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

Tutorial 2 – Using a mutex

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

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

For code example see example below:

tut2.h

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

Tutorial 3 – Using Semaphores

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

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

For code example see below:

tut3.h

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

Tutorial 4 – Timer interrupt starts task

This exercise introduces the use of timer interrupts.

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

For code example see below:

tut4.h

 1 /*
 2  *********************************************************************************************************
 3  *                                                OCEOS
 4  *                                      Real-Time Operating System
 5  *                                                 for
 6  *                                        SPARC and ARM Microcontrollers
 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  *                                        SPARC and ARM Microcontrollers
  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  *                                        SPARC and ARM Microcontrollers
  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  *                                        SPARC and ARM Microcontrollers
  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  *                                        SPARC and ARM Microcontrollers
 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 data queue with timeouts.

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

For code example see below:

tut5.h

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

oceos_config.h

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

oceos_config.c

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

tut5.c

  1 /*
  2 ******************************************************************************
  3 *                                   OCEOS
  4 *                        Real-Time Operating System
  5 *                              for ARM/SPARC
  6 *                             Microcontroller
  7 *
  8 *                       Application Software Example
  9 *
 10 *
 11 *                    (c) Copyright 2022, O.C.E. Technology
 12 *                             All Rights Reserved
 13 *
 14 * Author:       jfk
 15 *
 16 * Purpose                : The test here involves creating two tasks with different priorities, 
 17 *						   and two data queues with timed action implimentation.
 18 *
 19 ******************************************************************************
 20 */
 21 /* N.B.  Application header is included first */
 22 #include "tut5.h"                        // application header
 23 
 24 struct data {
 25   int status;
 26   char *message;
 27 } test_data = {
 28     1,
 29     "Test Data",
 30 };
 31 int main(void) {
 32 
 33     /*
 34      * Initialise the application configuration and OCEOS
 35      *
 36      * This application function creates the application configuration
 37      * and passes it to oceos_init(), which initialises the fixed data
 38      * and enables the system log
 39      */
 40     if ( !application_init()) {
 41         //LOG
 42         printf("\nProblem\n");
 43         return -1;
 44     }
 45 
 46     enum DIRECTIVE_STATUS status;
 47     // Task 0: priority 10, threshold 10, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0
 48     status  = oceos_task_create(t_consumer, 10, 10, 1, 0, TASK_ENABLED,t_consumer_task, NULL, 0, 0);
 49       if(SUCCESSFUL != status){
 50         // LOG
 51         printf("\nAbandoning, problem creating task t_consumer, resulting return code: %u\n", status);
 52         return -1;
 53       }   // if
 54 	
 55     // Task 1: priority 254, threshold 254, max jobs 1, FP_used disabled,  initially_enabled TRUE, task start address t_consumer_task, start of task end function NULL, time_deadline 0, time_mininterstart 0
 56     status  = oceos_task_create(t_producer, 254, 254, 1, 0, TASK_ENABLED,t_producer_task, NULL, 0, 0);
 57 	  if(SUCCESSFUL != status){
 58         // LOG
 59         printf("\nAbandoning, problem creating task t_producer, resulting return code: %u\n", status);
 60         return -1;
 61       }   // if
 62 
 63     printf("\n Tasks created\n");
 64     // no counting semaphores, data queues or user defined traps
 65 
 66     // Creating Data 0, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE
 67      status = oceos_dataq_create(queue_0, N0, JOBS0, FALSE, TRUE);
 68      if(SUCCESSFUL != status){
 69         printf("\nProblem creating dataq queue_0, resulting return code: %u\n", status);
 70      }   // if
 71 	
 72 	// Creating Data 1, dataq_size 1, pen_q size 1, roll_over FALSE, use_timeout TRUE
 73       status = oceos_dataq_create(queue_1, N1, JOBS1, FALSE, TRUE);
 74       if(SUCCESSFUL != status){
 75        printf("\nProblem creating dataq queue_1, resulting return code: %u\n", status);
 76       }   // if
 77     /*
 78      * Finish initialising OCEOS and setting up the fixed data
 79      */
 80     status = oceos_init_finish();
 81     if(SUCCESSFUL != status){
 82      printf("\nAbandoning, problem ending OCEOS initialisation, resulting return code: %u\n", status);
 83      return -1;
 84     }   // if
 85     //1)  Action: Start OCEOS  with Task 1 as initial task, null input pointer
 86     status = oceos_start(fixed_data, t_producer, NULL);
 87 
 88     return status;                          // returned as an integer
 89 
 90 }   // function waits for specific time interval
 91 void test_wait(U32_t interval) {
 92   volatile U32_t start_time = oceos_time_sys_get32();
 93   volatile U32_t cur_time = 0;
 94   while(1) {
 95       cur_time = oceos_time_sys_get32();
 96       if ((cur_time - start_time) >= interval ) {
 97           break;
 98       }
 99   }
100 }
101 /*
102  * Tasks
103  */
104 void t_consumer_task() {
105   static int case_number = 0;
106   if (case_number == 0) {
107       case_number++;
108       // 2)  Action: Task 1 attempts to start Task 0
109       // Check:  Task 0 has started, pre-empting Task 1
110       // a.  Check: entry message from Task 0
111       // b.  Check: queue_0 entries is 0
112       // c.  Check: queue_1 entries is 0
113       printf("t_consumer was started\n");
114        if(oceos_dataq_get_size(queue_0)!= 0){
115        printf("\nData queue_0 entries is not equal to 0\n");
116        }   // if
117 	   if(oceos_dataq_get_size(queue_1)!= 0){
118        printf("\nData queue_1 entries is not equal to 0\n");
119        }   // if
120   
121       // 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 }