Difference between revisions of "OCEOS Tutorials"

From wiki
Jump to navigation Jump to search
Line 430: Line 430:


/*
/*
*********************************************************************************************************
*********************************************************************************************************
*                                                OCEOS
*                                                OCEOS
*                                      Real-Time Operating System
*                                      Real-Time Operating System
*                                                for
*                                                for
*                                        GR716 Microcontroller
*                                        ARM Microcontroller
*
*
*                                 User Manual Section 11 Example 4
*                                   Example implementation of OCEOS
*
*
*                              (c) Copyright 2020, O.C.E. Technology
*
*                                          All Rights Reserved
*                              (c) Copyright 2021, O.C.E. Technology
*
*                                          All Rights Reserved
* File :       tut4.c
*
********************************************************************************************************
*
* Author:       jfk
********************************************************************************************************
  */
  */
#include "tut4.h"                        // application header
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Line 451: Line 451:
/* N.B.  Application header is included first */
/* N.B.  Application header is included first */
#include "oceos_config.h"                // OCEOS header for this application
#include "oceos_config.h"                // OCEOS header for this application
#include <bcc/regs/gptimer.h>
#include "tut4.h"                       // application header
 
#include "oceos_interrupt.h"
/*
* Application specific
*
*/
extern U32_t  fixed_data[];    // will be in data segment. Should this be in oceos.h


struct gptimer_regs *timer_regs = (void *)OCEOS_TA_TIMER_ADDRESS;
volatile U32_t count_task_start = 0;
struct gptimer_timer_regs *task_timer;
struct bcc_isr_node node;


int main(void) {
int main(void) {
int status;
  int status;
    /*
  /*
    * Initialise the application configuration and OCEOS
  * Initialise the application configuration and OCEOS
    *
  *
    * This application function creates the application configuration
  * This application function creates the application configuration
    * and passes it to oceos_init(), which initialises the fixed data
  * and passes it to oceos_init(), which initialises the fixed data
    * and enables the system log
  * and enables the system log
    */
  */
    if ( !application_init()) {
  if (!application_init()) {
        //LOG
    //LOG
        return -1;
    return -1;
    }
  }
    // Create Main task to
  // Create Main task to
    if ( oceos_task_create(
  if (oceos_task_create(t_0,// taskID, used as index, must be in range 0 to 254
    t_0, // taskID, used as index, must be in range 0 to 254
                        10, // priority,  must be in range 1 to 254, lower value is higher priority
    10, // priority,  must be in range 1 to 254, lower value is higher priority
                        10, // threshold, must be in range 1 to task priority
10, // threshold, must be in range 1 to task priority
                        1, // jobs_max, must be in range 1 to 15
1, // jobs_max, must be in range 1 to 15
                        0,// FALSE -> floating point hardware not used by task
0, // FALSE -> floating point hardware not used by task
                        1, // FALSE -> task initially not enabled
1, // FALSE -> task initially not enabled
                        fun0, // main body of task
fun0, // main body of task
                        NULL, // task end function
nullFun, // task end function
                        0,// time_deadline, must finish no later than this after start, 0 => ignore
0, // time_deadline, must finish no later than this after start, 0 => ignore
                        0 // minimum time expected between start requests, 0 => no restriction
0 // minimum time expected between start requests, 0 => no restriction
                        ) != SUCCESSFUL)
) != SUCCESSFUL )
    return 1;
    return 1;


    if ( oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, nullFun, 0, 0)!= SUCCESSFUL )
  if (oceos_task_create(t_1, 100, 100, 1, 0, 1, fun1, NULL, 0, 0)
    return 2;
      != SUCCESSFUL)
    /*
    return 2;
    * Finish initialising OCEOS and setting up the fixed data
  /*
    */
  * Finish initialising OCEOS and setting up the fixed data
    status = oceos_init_finish();
  */
    if(SUCCESSFUL != status){
  status = oceos_init_finish();
        return 3;
  if (SUCCESSFUL != status) {
    }  // if
    return 3;
    /*
  }  // if
    * Start OCEOS scheduling
  /*
    *
  * Start OCEOS scheduling
    * The OCEOS fixed data provides all the information required.
  *
    *
  * The OCEOS fixed data provides all the information required.
    * If a valid task is specified, it is started and passed the pointer.
  *
    * Otherwise the system is put in sleep mode
  * If a valid task is specified, it is started and passed the pointer.
    */
  * Otherwise the system is put in sleep mode
    status = oceos_start(fixed_data, t_0, (void *)nullPtr); // Start OCEOS
  */
    return status;
  status = oceos_start(fixed_data, t_0, NULL); // Start OCEOS
  return status;
}  // main
}  // main


/*
/*
  * Application code functions, functions declared in asw.h
  * Task 0 starting point
  */
  */
void fun0(void * ptr){
void fun0(void *ptr) {
//set up timer and add handle
  timer_setup();
    task_timer = &timer_regs->timer[3];
    task_timer->ctrl = 0x0;
    enum DIRECTIVE_STATUS ret = 0;
#ifdef TARGET_PM
    node.source = 9;
#endif
#ifdef TARGET_GR716
    node.source = 12;
#endif
    node.handler = start_task;
    node.arg = ptr;
    ret = oceos_interrupt_handle_register(&node);
    if (SUCCESSFUL != ret) {
        printf("ERROR :: Failed to add ISR handler\n");
    }
#ifdef TARGET_PM
    bcc_int_unmask(9);
#endif
#ifdef TARGET_GR716
    bcc_int_unmask(12);
#endif
    task_timer->reload = 0x2DC6C0; // 3 seconds
    task_timer->counter = 0x2DC6C0; // 3 seconds
    task_timer->ctrl = GPTIMER_CTRL_EN | GPTIMER_CTRL_RS | GPTIMER_CTRL_IE;    // 0x1 | (1 << 1) | (1 << 3);
 
    // The interrupt shoud keep starting t_1 so this task can exit
}  // fun0()
}  // fun0()
/*
/**
  * Handler for timer interrupt
* Task 1 starting point;
  * Triggered from Timer IRQ handler
  */
  */
void start_task(void *arg, int source){
void fun1(void *ptr) {
   oceos_task_start(t_1,arg);
   printf("Task started : %u times \n", count_task_start);
}
  count_task_start++;
}   // fun1()


void fun1(void * ptr){
printf ("Task started\n");
}  // fun1()


</syntaxhighlight>
</syntaxhighlight>

Revision as of 11:58, 25 February 2022

Tutorials

Introduction

This section presents some typical real-time tasks and how they can be addressed using OCEOS.

Getting started

Section 9.5 provides guidance on how to structure an OCEOS application. The file asw.c provided with OCEOS is a simple example.

The directives to initialise and start OCEOS are:

  1. application_init – Initialise fixed data and start system timer(s)
  2. oceos_task_create - Create task setting priority, no of jobs, ..etc.
  3. oceos_init_finish – Initilise dynamic data area
  4. oceos_start – Start the scheduler and pass control to first task

After steps 1 to 4 above tasks implement application functionality. If mutexes, semaphores, or dataqs are required they are also created at step 2.

Note: it is mandatory to create the number of mutexes, semaphores, and dataqs declared otherwise oceos_init_finish() will return an error.

Tutorials

Tutorial 1 – Starting tasks

This exercise demonstrates starting tasks with different priorities.

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

For code example see below.

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

Tutorial 2 – Using a mutex

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

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

For code example see example below:

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

Tutorial 3 – Using Semaphores

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

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

For code example see below:

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

Tutorial 4 – Timer interrupt starts task

This exercise introduces the use of timer interrupts.

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

For code example see below:


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