I am looking for wait_event_timeout[1] equivalent function in u-boot but could not find the same.
is there such fuction do exist in u-boot ?
[1] https://github.com/torvalds/linux/blob/master/include/linux/wait.h#L371
U-Boot runs with a single process and a single thread. Interrupts are not enabled for many platforms. So a function like wait_event_timeout() cannot be implemented.
Instead you will have to create a loop that constantly checks if the event has occurred and in the loop execute whatever it takes to let the event occur.
For example look at the efi_wait_for_event() function which in a loop calls efi_timer_check(). efi_timer_check() runs all registered timer based functions like checking the network interface for received packages.
Related
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.
Actually I've a function to monitor a GPIO on my beaglebone. I set that function to send an user signal (SIGUSR1) when an event occurs on a digital input port (external interrupt so) but that function has to be in a loop. I could insert that function in a thread or fork() it but I don't think it's elegant solution.
I'd like to know if exist any way/function/feature ready-to-use in C language to set the monitoring to run in a foreground (higher priority) without put in a loop, something like a setitimer which is declared only once and runs (keeps monitoring) without need to be in a loop.
I don't know if it's possible with beaglebone/linux but with PIC this feature is called by "Streaming Parallel Port" (SPP).
I don't know how you monitor gpio, but to work with gpio from user space
(see https://www.kernel.org/doc/Documentation/gpio/sysfs.txt)
you can use select and poll, call it with minimum timeout time to time you
can work without loop, or if you use Qt/gtk you can insert check of gpio inside
event loops of this frameworks.
The second variant is to use setjmp/longjmp if you want to use only C,
without C++/boost,
also if you speak about timers you can use man 2 alarm to implement periodical timers,
the most simple way as for me is using pthreads, and setup thread that monitor gpio highest priority to not loose information.
I want a particular function to be called every 15seconds (i.e I need to setup a timer) in a core nginx module that i have written.
Here is the code that I have written by referring some examples online. The ngx_monitoring_init_process() is the 'init process' function in my 'ngx_monitoring_module'
The module compiles OK, but the timer doesn't work, any idea why ?
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.
I found tsc2007 driver and modified according to our needs. Our firm is producing its own TI DM365 board. In this board we used TSC2007 and connected PENIRQ pin to GPIO0 of DM365. It is being seen OK on driver. when i touch to touchscreen cursor is moving but at the same time i am getting
BUG: scheduling while atomic: swapper /0x00000103/0, CPU#0
warning and embedded Linux is being crashed. there are 2 files that i modified and uploaded to http://www.muhendislikhizmeti.com/touchscreen.zip one is with timer the other is not. it is giving this error in any case.
I found a solution on web that i need to use work queue and call with using schedule_work() API. but they are blur for me now. Is anybody have any idea how to solve this problem and can give me some advice where to start to use work queue.
"Scheduling while atomic" indicates that you've tried to sleep somewhere that you shouldn't - like within a spinlock-protected critical section or an interrupt handler.
Common examples of things that can sleep are mutex_lock(), kmalloc(..., GFP_KERNEL), get_user() and put_user().
Exactly as said in 1st answer, scheduling while atomic happens when the scheduler gets confused and therefore unable to work properly and this because the scheduler tried to perform a "schedule()" in a section that contains a schedulable code inside of a non schedulable one.
For example using sleeps inside of a section protected by a spinlock. Trying to use another lock(semaphores,mutexes..) inside of a spinlock-proteced code may also disturb the scheduler. In addition using spinlocks in user space can drive the scheduler to behave as such. Hope this helps
For anyone else with a similar error - I had this problem because I had a function, called from an atomic context, that used kzalloc(..., GFP_KERN) when it should have used GFP_NOWAIT or GFP_ATOMIC.
This is just one example of a function sleeping when you don't want to, which is something you have to be careful of in kernel programming.
Hope this is useful to somebody else!
Thanks for the former two answers, in my case it was enough to disable the preemption:
preempt_disable();
// Your code with locks and schedule()
preempt_enable();