I have a wireless device and can send commands from my phone to the device. A command executes a bunch of steps to complete an action. At the moment, this action function is blocking, ie until the call completes the user needs to wait, with no option to quit. If for any reason, the call doesn't complete then the user is stuck with that screen. A simple pseudo looks like this:
do_action()
{
int result = 0;
result |= step_a();
result |= step_b();
result |= step_c();
result |= step_d();
return result;
}
How can I make this process "interruptible", ie use a signal/flag to tell this function call that the user has terminated and that this action needs to be terminated/cleaned up. Is there a way I can "time bound" this function, ie exit the action if not completed within expected time? How can I implement such a feature? One of the issues also is that some of the steps, such as step_a, step_b functions are blackbox functions, ie implemented by the manufacturer and are blocking and I have no way modify their interface.
The easiest option is to see if the API has a way to pass a timeout to individual calls (or ask the manufacturer to implement one). If this is possible, then you could structure your code to take one step, check if you should quit (timeout reached or user interrupted), then take another step.
Should you be stuck with blocking vendor code you cannot modify, you will need to put something in place that can terminate an in-progress "action". Exactly what this interruption can be will depend environment is running on your device.
If your device is running more feature complete operating system then you could either add a second thread to your process that monitors the first (lookup pthreads), or you could execute your action in one process and have a separate monitor process that kills the first if it takes too long or if the user cancels the action (lookup the "fork" and "kill" system calls).
If your code is running on a more bare-bones environment then your options are more limited. One way to do this is to manually set up a hardware timer and an interrupt handler to check state. The specifics of how to do this will depend entirely on what hardware you are using.
Related
Context
I'm making some libraries to manage internet protocol trough GPRS, some part of this communications (made trough UART) are rather slow (some can take more than 30 seconds) because the module has to connect through GPRS.
First I made a driver library to control the module and manage TCP/IP connections, this library worked whit blocking functions, for example a function like Init_GPRS_connection() could take several seconds to end, I have been made to notice that this is bad practice, cause now I have to implement a watchdog timer and this kind of function is not friendly whit short timeout like watchdogs have (I cannot kick the timer before it expire)
What have I though
I need to rewrite part of my libraries to be watchdog friendly, for this purpose I have tough in this scheme, I need functions that have state machine inside, those will be pulling data acquired trough UART interruptions to advance trough the state machines, so then I can write code like:
GPRS_typef Init_GPRS_connection(){
switch(state){ //state would be a global functions that take the current state of the state machine
.... //here would be all the states of the state machine
case end:
state = 0;
return Done;
}
}
while(Init_GPRS_connection() != Done){
Do_stuff(); //Like kick the Watchdog
}
But I see a few problems whit this solution:
This is a less user-friendly implementation, the user should be careful using this library driver because extra lines of code would be always necessary (kind of defeating the purpose of using functions).
If, for some reason, the module wouldn't answer at some point the code would get stuck in the state machine because the watchdog would be kicked outside this function even though the code got stuck in a loop, this kind of defeat the purpose of using watchdog Timer's
My question
What kind of implementation should I use to make a user and watchdog friendly driver library?, how does other drivers library manage this?
Extra information
All this in the context of embedded systems
I would like to implement the watchdog kicking action outside the driver's functions
Given where you are and assuming you do not what too much upheaval to your project to "do it properly", what you might to is add variable watchdog timeout extension, such that you set a counter that is decremented in a timer interrupt and if the counter is not zero, the watch dog is reset.
That way you are not allowing the timer interrupt to reset the watchdog indefinitely while your main thread is stuck, but you can extend the watchdog immediately before executing any blocking code, essentially setting a timeout for that operation.
So you might have (pseudocode):
static volatile uint8_t wdg_repeat_count = 0 ;
void extendWatchdog( uint8_t repeat ) { wdg_repeat_count = repeat ; }
void timerISR( void )
{
if( wdg_repeat_count > 0 )
{
resetWatchdog() ;
wdg_repeat_count-- ;
}
}
Then you can either:
extendWatchdog( CONNECTION_INIT_WDG_TIMEOUT ) ;
while(Init_GPRS_connection() != Done){
Do_stuff(); //Like kick the Watchdog
}
or continue to use your existing non-state-machine based solution:
extendWatchdog( CONNECTION_INIT_WDG_TIMEOUT ) ;
bool connected = Init_GPRS_connection() ;
if( connected ) ...
The idea is compatible with both what you have and what you propose, it simply allows you to extend the watchdog timeout beyond that dictated by the hardware.
I suggest a uint8_t, because it prevents a lazy developer simply setting a large value and effectively disabling the watchdog protection, and it is likely to be atomic and so shareable between the main and interrupt context.
All that said, it would clearly have been better to design in your integrity infrastructure from the outset at the architectural level rather than trying to bolt it on after the event. For example if you were using an RTOS, you might reset the watchdog in a low priority task that if starved, would cause a watchdog expiry, and that "watchdog task" could be use to monitor the other tasks to ensure they are scheduling as expected.
Without an RTOS you might have a "big-loop" architecture with each "task" implemented as a state-machine. In your example you seem to have missed the point of a state-machine. "initialising connection" should be a single state of a high level state-machine, the internals of that state may itself be a state-machine (hierarchical state machines). So your entire system would be a single master state-machine in the main loop, and the watchdog reset once at each loop iteration. Nothing in any sub-state should block to ensure the loop time is low and deterministic. That is how for example Arduino framework's loop() function should work (when done properly - unfortunately seldom the case in examples). To understand how to implement a real-time deterministic state-machine architecture you couls do worse that look at the work of Miro Samek. The framework described therein is available via his company.
You should make your library non-blocking, but other than that, you should not worry about the watchdog at all. The watchdog management should be left to the user.
To allow the user to do other work while your library is waiting, you can use these approaches:
Provide a function to feed the data into your library (e.g. receive()). The user should call this function when the data is available, for example from the interrupt. As this function can be called from the interrupt, make sure it does not do heavy processing. Typically, you would just buffer the data and process it later (Step 2).
Provide a function, that user calls periodically, that updates the state of your library and does any other housekeeping tasks (like timeout detection). Typically, this function is called run(), process(), tick() or something along these lines. The user would call this function in their main loop or from a dedicated RTOS task.
Provide a way to tell the user the state of your library. You can do it either by some sort of getState() function or using a callback or both. Based on this information, the user can implement their own state machine to do things on connect, disconnect etc.
I'm integrating FreeRTOS cmsis_v2 on my STM32F303VCx and come to a certain problem then using Event Flags when blocking the task to wait for operation approval from another task.
If the task executes the following code, all other tasks get minimal runtime (understandably because OS is constantly checking evt_flg):
for(;;)
{
flag = osEventFlagsWait (evt_flg, EventOccured, osFlagsWaitAny, 0);
if (flag == EventOccured)
{
/* Task main route */
osEventFlagsClear (evt_flg,EventOccured);
}
}
But if to set timeout to osWaitForver: osEventFlagsWait (evt_flg, EventOccured, osFlagsWaitAny, osWaitForver ), the whole program goes into HardFault.
What's the best solution for such behavior? I need the task to wait for a flag and don't block other ones, such as terminal input read, from running.
The task code the question provides is constantly busy, polling the RTOS event.
This is a design antipattern, it is virtually always better to have the task block until the event source has fired. The only exception where a call to osEventFlagsWait() with a zero timeout could make more sense is if you have to monitor several different event/data sources for which there is not a common RTOS API to wait for (and even then, this is only an "emergency exit"). Hence, osWaitForver shall be used.
Next, the reason for the HardFault should be sought. Alone in this task code, I don't see a reason for this - the HardFault source is likely somewhere else. When the area the HardFault can come from, that could be worth a new question (or already fixed). Good luck!
We are using embedded C for the VxWorks real time operating system.
Currently, all of our UDP connections are started with TaskSpawn().
This routine creates and activates a new task with a specified
priority and options and returns a system-assigned ID.
We specify the task size, a priority, and pass in an entry point.
These are continuous connections, and thus every entry point contains an infinite loop where we delay before the next iteration.
Then I discovered period().
period spawns a task to call a function periodically.
Period sounds like what we should be using instead, but I can't find any information on when you would prefer this function over TaskSpawn. Period also doesn't allow specifying the task size or the priority, so how is it decided? Is the task size dynamic? What will the priority be?
There are also watchdogs.
Any task may create a watchdog timer and use it to run a specified
routine in the context of the system-clock ISR, after a specified
delay.
Again, this seems to be in line with the goal of processing data at a particular rate. Which do I choose when a task must continuously execute code at the same rate (i.e. in real time)?
What are the differences between these 3 methods?
Here is a little clarification:
taskSpawn(..) creates a task with which you're free to do anything with you like.
Watchdogs shall only be used to monitor time constraints. Remember that the callback of the watchdog is executed within the context of the system clock ISR which has many limitations (e.g. free stack size, never use blocking function calls in an ISR, ...). Additionally executing "a lot of code" in the system clock ISR slows down your entire system.
period(..) is intended to be a helper for the VxWorks shell and not to be used by a program.
With that being said your only option is to use taskSpawn(..) unless you're doing some very simple stuff in which case period(..) might be ok to use.
If you need to do things cyclically in a specific time frame you might look at timers or taskDelay(..) in combination with sysClkRateSet(..).
Another option is to create two tasks. One that is setting a semaphore after a specific time intervall and the other "worker" tasks waits for this semaphore to do something. With that approach you separate "timing" from "action" which proved to be benefitial according to my experience. You also might want to monitor excution time of the "worker" task by using a watchdog.
I've written many C programs for microcontrollers but never one that runs on an OS like linux. How does linux decide how much processing time to give my application? Is there something I need to do when I have idle time to tell the OS to go do something else and come back to me later so that other processes can get time to run as well? Or does the OS just do that automatically?
Edit: Adding More Detail
My c program has a task scheduler. Some tasks run every 100ms, some run every 50 ms and so on. In my main program loop i call ProcessTasks which checks if any tasks are ready to run, if none are ready it calls an idle function. The idle function does nothing but it's there so that I could toggle a GPIO pin and monitor idle time with an O'scope... or something if I so desired. So maybe I should call sched_yield() in this idle function???
How does linux decide how much processing time to give my application
Each scheduler makes up its own mind. Some reward you for not using up your share, some roll dices trying to predict what you'll do etc. In my opinion you can just consider it magic. After we enter the loop, the scheduler magically decides our time is up etc.
Is there something I need to do when I have idle time to tell the OS
to go do something else
You might call sched_yield. I've never called it, nor do I know of any reasons why one would want to. The manual does say it could improve performance though.
Or does the OS just do that automatically
It most certainly does. That's why they call it "preemptive" multitasking.
It depends why and how you have "idle time". Any call to a blocking I/O function, waiting on a mutex or sleeping will automatically deschedule your thread and let the OS get on with something else. Only something like a busy loop would be a problem, but that shouldn't appear in your design in any case.
Your program should really only have one central "infinite loop". If there's any chance that the loop body "runs out of work", then it would be best if you could make the loop perform one of the above system functions which would make all the niceness appear automatically. For example, if your central loop is an epoll_wait and all your I/O, timers and signals are handled by epoll, call the function with a timeout of -1 to make it sleep if there's nothing to do. (By contrast, calling it with a timeout of 0 would make it busy-loop – bad!).
The other answers IMO are going into too much detail. The simple thing to do is:
while (1){
if (iHaveWorkToDo()){
doWork();
} else {
sleep(amountOfTimeToWaitBeforeNextCheck);
}
}
Note: this is the simple solution which is useful in a single-threaded application or like your case where you dont have anything to do for a specified amount of time; just to get something decent working. The other thing about this is that sleep will call whatever yield function the os prefers, so in that sense it is better than an os specific yield call.
If you want to go for high performance, you should be waiting on events.
If you have your own events it will be something like follows:
Lock *l;
ConditionVariable *cv;
while (1){
l->acquire();
if (iHaveWorkToDo()){
doWork();
} else {
cv->wait(lock);
}
l->release();
}
In a networking type situation it will be more like:
while (1){
int result = select(fd_max+1, ¤tSocketSet, NULL, NULL, NULL);
process_result();
}
In an embedded project, we're supposed to implement a task scheduler with different priorities, the project implementation is in C and is run on an Arduino device.
Now that we're in the researching phase, one question popped but nobody had experience enough to have a certain answer:
How is it possible to control the execution time of a function? How do we keep track of time before the function returns so we can interrupt it for example when a time-out occurs?
One suggestion was to use fork(), but since Arduino does not include an operation system, there's no kernel to handle a thread. Or am I wrong?
Any input will be helpful, thanks a bunch,
You need a timer. All non-cooperative multi tasking systems (i.e. those which don't depend on the function to say "you can interrupt me now" all the time) use a timer to stop the execution after some time (say 100ms).
In the interrupt handler, check if there is another "thread" which can run and switch context.
A pretty simple implementation is a "ready list": Whenever a task or thread could do some work, add it to the ready list.
When the timer fires, add the current task at the end of the list and make the head of the list the current task.
In an embedded system a task scheduler is the core of an operating system (usually an RTOS), so you are being asked to implement one not to use one.
A simple example of how such a scheduler works is described in Jean Labrosse's boot Micro C/OS-II. It describes a complete RTOS kernel with scheduling and IPC. For your project you can take the description of this core and implement your own (or you could use the included source code).
Such a kernel works by scheduling at certain OS calls and on a timer interrupt. A context switch involves storing the processor registers for one task and replacing then with teh registers for another. Because this register save/restore includes the stack-pointer and program counter, control is switched between threads.
It may be that simpler forms of scheduling (rather than preemptive) scheduling are called for. One method is to implement task functions that run to completion and where necessary store their own state and are implemented as state-machines, and then have a simple loop that polls a timer and call's each 'task' function according to a schedule table (that includes the periodicity of the task and a pointer to its function, so that say one function will be called every second, while another will be called every millisecond.