signpainter
signpainter

Reputation: 750

Time slice function without a OS scheduler

I have a part of a library that processes data and takes quite a long time. In some cases it's not possible to wait for the results of the function but there are other tasks that should be done. On a system with an OS that's not a problem, as the scheduler can help with that. But there are also systems that have no OS available. On these systems I want to achieve something similiar, i.e. the function is called does some calculations and returns after a given period (say 10ms). Then the other things are done and the data processing function gets called again and takes off at the position it left.

while(1) {
    process_data(); // resumes from where it returned before, runs for 10ms and returns
    do_other_stuff();
    and_some_more_stuff();
}

How can this be achieved?

I already found the concept of protothreads, but this would mean that I have to add stuff like PT_WAIT after every x statements that might take 10ms to compute. Is there any other way?

Upvotes: 1

Views: 768

Answers (2)

kkrambo
kkrambo

Reputation: 7057

Implement the process_data function as a state machine. Divide the too-long processing algorithm into multiple shorter steps/states. Declare a static state variable within process_data so that it remembers its previous state each invocation. Each time process_data is called it performs only one state. Then when it's called again it picks up where it left off and performs the next step. With this method the amount of time each invocation takes will be determined by how you divide the steps at design time. You won't be able to limit the execution time at run time.

If the processing is something that is performed in a repetitive loop then perhaps you can read a hardware timer in the loop and break out of the loop when the time limit is reached. But use static variables to remember on the next invocation where the processing left off.

Upvotes: 3

tofro
tofro

Reputation: 6073

As long as other_stuff is reasonably short, you can do it in a timer ISR.

In case you don't want to use the task context savings of an (RT)OS, you have to implement them on your own - break your long-running processing function down into pieces, save the processing context and return to your main dispatching point. After the next step is done, come back to the saved context and re-start processing where you left off. (This is more or less what protothreads do)

The end consequence is that once you're done, you might have implemented most of the parts of a multitasking time-slicing OS.

Upvotes: 2

Related Questions