I am new to using the Contiki OS and I have a fundamental question.
Can I safely use a low level ISR from within a Contiki Process?
I am doing this as a quick test and it is functioning well.
However, I am concerned that I may be undermining something in the OS that will
fail at a later time under different conditions.
In the context of a process which is fired periodically based upon an event timer,
I am calling a function which sets up an LED to blink.
The LED blinking function itself is a callback from an ISR fired by a hardware timer on an Atmel SAMD21 MCU.
Can some one please clarify for me what constraints I should be concerned about in this particular case?
Thank You.
Basically you can, but you have to understand the context in which each part of the code run in.
A Process has the context of a function, the Contiki's scheduler runs in the main body, timers will enqueue process wakes in this scheduler, in fact, think of Contiki Processes as functions called after each other, notice that those PROCESS_* macros does in fact call return on the function.
When you are at an interrupt handler or callback, you are in a different context, here you can have race conditions if you share data with processes, the same it would be in a bare-metal firmware where interrupt and main() are different contexts.
I strongly recommend you to read about the "protothreads", besides they sound like threads, they are not, they are functions running in the main body. (I believe this link will enlighten you http://dunkels.com/adam/pt/)
On the problem you described, I see nothing wrong.
Contiki itself has some hardware abstractions modules, so you won't have to deal with the platform directly from you application code. I have written big firmwares using Contiki and found these abstractions not very much usable, since it has limited applications. What I did, on this case, was to write my own low level layer to touch the platform, so in the application everything is still platform independent, but, from the OS perspective, I had application code calling platform registers.
Related
These days I have solved the issue of ocasional false register write. The problem was, that I was writing a lot in the GPIO output register (LPC_GPIO_PORT->SET[1]) in the main loop. In the interrupt routine I was writing in these same registers, and when interrupt happened just in time when these registers were being writen in the main loop, upon return from interrupt, the changes to those registers were discarded and replaced with those writen into register before entering interrupt.
I am using LPC1549 microcontroller. The register writes in interrupts are used for BLDC motor controll, so you could hear loud bang from the motor every 10-30 seconds. By reducing writing registers in the main loop, i have completly eliminated the problem. The question is, is it the same with all registers in microcontroller? I cant find anything describing this problem, which can be a serious issue, and also, hard to find, once it starts causing trouble.
Sounds to be "The Critical Section Problem". This topic pops up a lot more in literature about Operating Systems but exists in any interrupt-driven platform that has shared resources. It might help your searching to look at this problem.
In your case, you have 2 data accessors: the interrupt handler and the main loop. both accessing the same shared resource (memory mapped I/O). This can lead to updates being overwritten immediately based on the timing of the two events like you describe above.
As for your second question, this can affect any shared resources in a concurrent system.
I have seen a lot of argument about epoll accepted new fd and spawn new thread for read and write on it's own thread doesn't scale well? But how it doesn't scale well? What if every connection has heavy processing like:-
doing database transaction
doing heavy algorithm work
waiting for other things to completed.
If my purpose definitely just want to do the thing inside the program(no more fancy routing to other connection to do stuff), and do not spawn new thread for read/write io. It might be hanging forever just because of one function waiting for something right? If this is the case how epoll scale well if do not spawn new thread?
epoll_wait(...);
// available to read now
recv(....);
// From here if i don't spawn thread, the program will be hanging. What should I do?
processing algorithm work.....// At least 3 secs to do the job.
continue;
AFAIU, epoll(7) does not spawn new threads by itself (see also pthreads(7)...). You need some other call (using pthread_create(3) or the underlying clone(2) system call used by pthread_create...) to create threads.
Read more about the C10K problem (which today should be called C100K) and some pthread tutorial. But it looks like your program could be compute-intensive, not IO-bound. So the bottleneck might be computer power (then you cannot get scalability with just multi-threading on a single computer node; you need distributed computing)
Threads are quite heavy resources. So you want to have some thread pool and have only a few dozens of active (i.e. runnable) threads. See this.
Be also aware of other multiplexing system calls (such as poll(2)), of non-blocking IO (fcntl(2) with O_NONBLOCK), of asynchronous IO (see aio(7)).
I recommend using some existing event-loop based library (look into libev, libevent, Glib, Poco, Qt, ... or for HTTP mostly: libonion on the server side, libcurl on the client side). Look also into 0mq.
The concepts related to callbacks, continuations, CPS could be useful and improve your thinking.
Languages like Go and its Goroutines could be helpful.
It might be hanging forever ....
That should not happen if you design your program carefully (of course having event loops using something like poll or epoll_wait - with a limited delay of less than a second and probably prefering non-blocking IO).
Probably, spending a few weeks learning more about Operating Systems concepts should be worthwhile. Also understanding most system calls (listed in syscalls(2)) after having read more about Linux programming (e.g. the old ALP book, or something newer) should be preferable. Perhaps you don't need something as sophisticated as epoll (because using just poll might be enough).
I have been reading about RunLoops for a few days in Apple documentation and stuff from Google search. I have understood the concept of RunLoops to great extent but still I got no answer to some basic questions regarding RunLoops.
How Runloop exactly works ? Is it something like while loop running at some system level ?
If it is indeed some sort of while loop at some system level, then how does it differ from polling ?
Please provide me with some pointers for this..
The whole point about a RunLoop (variously named as Window Handler, main-loop, event-loop on other platforms) is that it facilitates an Event Driven Architecture in which an application only runs when there is something to do - for example, responding to user-interaction. This is the opposite of polling.
Fundamental to the architecture is a some kind of message queue that a thread can block on until a message available for processing. On MacOSX and iOS systems the queue is a Mach kernel RPC port. On Windows it's a kernel IPC queue, and X-windows systems, a unix-domain or network socket.
Events are inserted into the queue by other system components - for instance a Window Manager and other applications. It is also common for applications to message themselves from other threads in order to perform all UI processing in the same thread.
The run-loop itself resides in application space and looks something like this:
while (!stop)
{
message = WaitForNextMessage();
DispatchMessage(message);
}
Usually, whatever UI framework you use provides a mechanism for registering an event handler for particular types of events.
I am trying to understand how I shall port my Java chess engine to dart.
So I have understood that I should use Isolates and/or Futures to run my engine in parallell with the GUI but how can I force the engine to terminate the search.
In java I just set some boolean that where shared between the engine thread and the gui thread.
You should send a message to the isolate, telling it to stop. You can simply do something like:
port.send('STOP');
To be clear, isolates and futures are two different things, and you use them differently.
Use an isolate when you want some code to truly run concurrently, in a separate "isolated memory heap". An isolate is like a mini program, running separately from your main program. You send isolates messages, and you can receive messages from isolates.
Use a future when you want to be notified when a value is available later. "Later" is defined as "a future tick in the event loop". Each isolate has its own event loop. It's important to understand that just asking a Future to run a function doesn't make the function run in parallel. It just puts the function onto the event loop to be run "later".
Answering the implied question 'how can I get a long running task in an isolate to cease running?' rather than more explicitly asked 'how can I cause an isolate to terminate, release it's resources and generally cease to be?'
Break the long running task up into smaller, shorter running units.
Execute each unit with a Future. Chain futures as appropriate.
Provide a flag that each unit should check before executing its logic. If the flag is set, bail.
Listen for a 'stop' message and set the flag if/when received.
Splitting the main processing task up into Futures allows processing of the stop message to get onto the event queue ahead of units of processing of the main task.
There is now iso.Isolate.kill()
WARNING: This method is experimental and not handled on every platform yet.
I was going over the RunLoop iOS documentation and it discusses the idea illustrated here:
(source: apple.com)
in the RunLoopSource it provides the following interface for client threads (ie the Main thread in the above illustration) to fill the audio buffer with commands and data, and to subsequently fire all commands available in the said buffer:
// Client interface for registering commands to process
- (void)addCommand:(NSInteger)command withData:(id)data
- (void)fireAllCommandsOnRunLoop:(CFRunLoopRef)runloop
In the add command method we're simply adding commands to an NSMutableArray data structure.
My question is how can we encapsulate those commands in variables such that they are methods.. the data variable in the addCommand method is of type id.. can we put a block in there for example? Are there any best practices here/sample code etc? thanks.
This technique pre-dates blocks. The beauty about using blocks with concurrency is that you can throw as much work as you want at the system, and given its total device scope can schedule that work on multiple cores and threads as it sees fit. You can also use a concurrent NSOperation and have it implement a fifo to accept work and process it, but in this case there will only be the secondary thread, and it will again be scheduled run time as the system sees fit to giving it, so no advantage over blocks.