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.
[SOLVED] how to make scheduler task
-
bar -
July 24, 2019 at 2:05 PM -
Closed
-
-
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
Display Morestatic OS_TIMER MyTimer; static void MyTimerCallback(void) { DoSomething(); OS_TIMER_Restart(&MyTimer); } int main(void) { ... // Initialization, etc. OS_TIMER_CREATE(&MyTimer, MyTimerCallback, 50); // Create and start timer (period: 50 system ticks) OS_Start(); // Start embOS return 0; }
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
Display Morestatic OS_STACKPTR int MyTaskStack[128]; // Task stacks static OS_TASK MyTaskCB; // Task control blocks void MyTask(void) { OS_TIME t0; t0 = OS_TIME_GetTicks(); // Retrieve initial timestamp while (1) { DoSomething(); t0 += 50; // Increase timestamp by 50 system ticks OS_TASK_DelayUntil(t0); // Delay this task for given period } } int main(void) { ... // Initialization, etc. OS_TASK_CREATE(&MyTaskCB, "MyTask", 100, MyTask, MyTaskStack); OS_Start(); // Start embOS return 0; }
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
-
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 event3.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 task4.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,
Quote from BarDo 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?Quote from BarIs there a missing stack also for the event structure?
No. OS primitives such as events do not require a stack of their own.Quote from BarNow 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,
MartinPS, after having just seen your additional post:
Quote from BarNow 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.Quote from BarIf 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
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!