[SOLVED] how to make scheduler task

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] how to make scheduler task

    Hello.
    I want to launch a task on aperiodic bases. I don't find a function, or a parameter I can give to make it done.
    I also can't find any clue in the UM01001 Real-Time Operating System User Guide & Reference Manual document.
    Thanks
    Bar.
  • Hello bar,

    Thanks for your inquiry.

    With embOS, there's several options to perform periodic jobs within your application.
    The most appropriate typically are the embOS software timers:

    C Source Code

    1. static OS_TIMER MyTimer;
    2. static void MyTimerCallback(void) {
    3. DoSomething();
    4. OS_TIMER_Restart(&MyTimer);
    5. }
    6. int main(void) {
    7. ... // Initialization, etc.
    8. OS_TIMER_CREATE(&MyTimer, MyTimerCallback, 50); // Create and start timer (period: 50 system ticks)
    9. OS_Start(); // Start embOS
    10. return 0;
    11. }
    Display All

    If for some reason timers can't be used for the intended purpose (e.g. when specific API functions can't be used with software timers), another option is to make tasks periodic by calling OS_TASK_DelayUntil():

    C Source Code

    1. static OS_STACKPTR int MyTaskStack[128]; // Task stacks
    2. static OS_TASK MyTaskCB; // Task control blocks
    3. void MyTask(void) {
    4. OS_TIME t0;
    5. t0 = OS_TIME_GetTicks(); // Retrieve initial timestamp
    6. while (1) {
    7. DoSomething();
    8. t0 += 50; // Increase timestamp by 50 system ticks
    9. OS_TASK_DelayUntil(t0); // Delay this task for given period
    10. }
    11. }
    12. int main(void) {
    13. ... // Initialization, etc.
    14. OS_TASK_CREATE(&MyTaskCB, "MyTask", 100, MyTask, MyTaskStack);
    15. OS_Start(); // Start embOS
    16. return 0;
    17. }
    Display All
    Alternatively, you may of course use a hardware timer as well - it really depends on the intended purpose which of these otions fits best. If you can explain your intended purpose to us in a little more detail, we may gladly give some more detailed advice.

    Best regards,

    Martin
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Martin.
    Thanks for your replay. I was work on other task, so I didn't get to it.
    Now I have time for this and I check your first suggestion with the event, base on your example and add data from UM01001.
    I build it this way:
    1. define event flag in the h file
    #define CRGTaskDelayEvent (1u << 1)
    2. Announce on the struct and function on the top of the file
    /* local varibles */
    static OS_TIMER CRGTaskTimer;
    /* local function */
    static void CRGTaskTimerCallback(void);// callback for trigger timing event

    3.Then create the timer, with its callback
    OS_TIMER_CREATE(&CRGTaskTimer, CRGTaskTimerCallback, 50); // Create and start timer (period: 1000 system tick) for the charger fuelGauge task

    4.In the callback of the timer I made the event
    void CRGTaskTimerCallback(void) {
    /** set the event **/
    OS_TASKEVENT_Set(&CRGTask, CRGTaskDelayEvent); // Notify task that a delay pass
    OS_TIMER_Restart(&CRGTaskTimer);// start the timer again
    }

    5.And back in the while loop I place this event check with block
    CRGTaskEvents = OS_TASKEVENT_GetBlocked(CRGTaskDelayEvent); // Wait for delay event
    if(!(CRGTaskEvents & CRGTaskDelayEvent))
    {
    uart_printf_LOG("wrong delay pass");
    }
    So it suppose to wait every loop for 50ms.
    I run it and it get to the
    OS_TASKEVENT_Set(&CRGTask, CRGTaskDelayEvent); in the callback, but then when it try to do it it fail to
    here:
    void OS_Error(OS_STATUS ErrCode) {
    OS_TASK_EnterRegion(); // Avoid further task switches
    OS_Global.Counters.Cnt.DI = 0u; // Allow interrupts so we can communicate with embOSView
    OS_INT_Enable();
    OS_Status = ErrCode;
    while (OS_Status) {
    // Endless loop may be left by setting OS_Status to 0
    }
    }
    when OS_Status = OS_ERR_INV_TASK
    I place the TCBCRG on watch ,first for the stack overflow as you find befor, but also I look on 2 variables. the first is events= 0 and the second is EventMask = 2 (which is exactly the event flag I made). The strange thing is that the EventMask =2 made on the beginning of the task , and not during the OS_TASKEVENT_Set phase.
    When I move the flag place the EventMask change according.
    I didn't see overflow on the TCBCRG stack.
    Do you see why this could happen?
    Is there a missing stack also for the event structure?
    Regards
    Bar.
  • Hi Martin.
    My mistake. I place the task name instead of the TCB at
    OS_TASKEVENT_Set(&CRGTask, CRGTaskDelayEvent);
    OS_TASKEVENT_Set(&TCBCRG, CRGTaskDelayEvent);
    Now it work :)
    If we talk, what about the error on the plug in? Are you on it?
    Regards
    Bar.
  • Hi Bar,


    Bar wrote:

    Do you see why this could happen?

    OS_ERR_INV_TASK indicates that the task was not created before, or else that the task's control block was overwritten by the application after it was created.
    Hence, could you please double-check that the task was actually created before the event gets signaled? Also, if it was created before, could you check wether the member "Id" of the respective task's control block holds the value "0x0Fu" at all times after creating that task?


    Bar wrote:

    Is there a missing stack also for the event structure?

    No. OS primitives such as events do not require a stack of their own.


    Bar wrote:

    Now I have time for this and I check your first suggestion with the event,

    Is this really necessary?
    While signalling a task event from a software timer can make sense in specific situations, we'd typcially advise to execute the desired functionality directly inside the software timer's callback function if that's possible. Otherwise, a task can be made periodic by calling OS_TASK_DelayUntil() - then, no software timer is required at all.
    As mentioned previously, if you were to give some more details on the job you're trying to perform periodically, we should be able to suggest the most appropriate approach to doing that with embOS.

    Best regards,
    Martin

    PS, after having just seen your additional post:

    Bar wrote:

    Now it work

    I'm glad to hear that! Still, you might want to re-consider whether signlling a task from the software timer really is necessary, or if OS_TASK_DelayUntil() would do the trick already.

    Bar wrote:

    If we talk, what about the error on the plug in?

    We'll notify you once an updated version of the plug-in becomes available.

    Please let me know if I can be of any further help.

    Best regards,
    Martin
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.