kmilo17pet / QuarkTS

An open-source OS for embedded applications that supports prioritized cooperative scheduling, time control, inter-task communications primitives, hierarchical state machines and CoRoutines.
MIT License
253 stars 44 forks source link

Timing tasks in the range of Microseconds, using QuarkTs with Omnetpp #26

Closed HpLightcorner closed 3 years ago

HpLightcorner commented 3 years ago

Hi, Recently I came across a scenario where I may need to time tasks below 1 Millisecond - mainly within a simulation framework like Omnetpp. I somehow like the idea of using QuarkTS with Omnet as it would allow me to reuse a lot of code I will write for the simulation than in the actual firmware.

The plan is to use Omnetpp Self-Messages to simulate the ticks for QuarkTs. As I won't use a custom IDLE function, I thought about executing the QuarkTs Run Function after every Tick call and/or events. This should then execute all timed and event-driven tasks when I remember the kernel code correctly.

Coming to my questions:

Thanks for your effort!

kmilo17pet commented 3 years ago

Hi @HpLightcorner, I don't have much knowledge of Omnetpp, but basically what you need for QuarkTS to meet temporary specifications is that you have to feed its internal tick from a context running in the background by invoking the qOS_SysTick () function. In embedded systems this is accomplished with a timer interrupt. This tick can be less than 1mS, but keep in mind that the maximum times you can define will be less. For example:

you can also use different time bases, for example 50uS

If you do this, all the specifications should be aligned to that base. for example, if you want to create a task that runs every 2sec

/ Im assuming that your are using Q_SETUP_TIME_CANONICAL /

define TICK_TIME (50uL) / uS /

define DESIRED_TASK1_PERIOD ( 2uL ) / Sec /

define TASK1_PERIOD_SPEC ( (DESIRED_TASK1_PERIOD * 1e6) / TICK_TIME )

qOS_Add_Task (& Task1, Task1Callback, qMedium_Priority, TASK1_PERIOD_SPEC , qPeriodic, qEnabled, NULL );

and the qOS_Run() function must be executed in a base context without any type of time control, basically at the maximum of the CPU (at full speed) or at least at a time significantly faster than the Tick that you are using as time-base.

it would be impossible to ask a task for 1uS if the tick is also running at 1uS. Even if we ask 5us to a task and the tick is 1uS it would also be difficult to achieve, we must bear in mind that there are also other tasks that must be verified and it is possible that the required time specification cannot be met. I hope that in this last you have understood my point.

ok, so going to your questions:

What is your opinion on using a non-preemptive OS for timing below a millisecond? totally possible Do you think the simulation would work with the proposed solution? its posible, but you also need to call both, the qOS_SysTick and the qOS_Run. Just keep in mind what I mentioned before. Without deep-diving into the code: is scheduling below a millisecond even possible with the current implementation? I normally use Q_SETUP_TIME_CANONICAL . Yes, but the maximum times that you can define will be less

just to complement, I think this kind of discussions can be moved here :) , https://github.com/kmilo17pet/QuarkTS/discussions

let me know if you need more info.

Best,