P8X32 events driven programming
events
Posts: 27
Hello to all. This is my first contact with the p8x32. And from what I've seen, there are many programming languages. In my opinion, it is an excellent mcu for working with events. My question, is there anyone who has ever thought of, or even have some code? Sorry my bad (google translator) English. Thanks to those who read this message.
Comments
In PF6, numerous tasks are defined in software, and set in a queue. The 7 or so available cogs are set as a pool. The first task in the queue is taken by the first cog in the pool. When the task finishes one pass, the task is returned to the end of the queue, and the task returns to the pool.
If a given task takes a long time, it only reduces capability by 1/7, as the remaining cogs can service the queue until the occupied cog is returned.
128 tasks are possible, but that doesn't leave much memory for applications. 30 tasks is more reasonable, this number has worked very well.
When the prop 2 is available, with 32 execution opportunities, this scheme might work nicely.
All programming has sequential elements. With 8 processors a lot of parallel processing is possible, including SIMD, MIMD, and multiple threads.
If you mean these protothreads, Catalina (a free open source ANSI C compiler for the Propeller) compiles and runs them (Note that there are a couple of modifications required to make the examples ANSI compliant - for some reason the protothreads code itself is ANSI, but the examples provided are not. I have attached the examples modified to compile under Catalina).
However, on the Propeller, you don't need to use protothreads - Catalina provides much simpler but more sophisticated multi-cog and multi-thread capabilities built right into the kernel - you can execute C code on each of the 8 cogs, and run hundreds of threads on each cog. You can even move threads from cog to cog.
To compare protothreads with Catalina threads, I used the following commands to compile and run all the protothreads examples - the resulting binary (example.binary) should work on any Propeller with a 5Mhz clock:
Then compile the file catalina-small.c - this is just the protothreads example-small.c modified to use Catalina threads instead of protothreads. To use the Catalina threads, you also need to add -lthreads (i.e. the threading library) to the command line - e.g:
The resulting binary is about half the size of the protothreads example.
Ross.
Hi events,
I assumed you wanted to use C since you mentioned protothreads, which are implemented in C.
If you plan to use assembler exclusively, you'd probably be best advised to just use PASM (the Propeller Assembly Language) - all the Spin compilers also support using PASM, since it is just a part of the Spin language.
If instead you plan to use assembler for some things (e.g. time critical code sections) and a higher level language for other things, you should consider Catalina. Catalina supports assembler several ways - you can have inline PASM, or call functions written in PASM (much of the C library is - especially the threads library), or have plugins (e.g. device drivers) written in PASM running in conjunction with C programs, or load and execute entire stand-alone PASM or Spin programs from within your C program.
However, if you have not programmed the Propeller before, be aware that if you program in PASM, you are limited to 496 instructions per cog. The big advantage of using Catalina (or one of the other compilers available for the Propeller) is that they get around that limit for you.
Ross.
Hi events,
Hmmm. The short answer is "Yes" - both the Catalina kernel and the protothreads-like threads libraries are all written 100% in either PASM (the kernel) or LMM PASM (the threads library).
If you are not familiar with LMM PASM, you can consider it as a subset of PASM that can be executed directly from Hub RAM rather than Cog RAM - some specific PASM instructions (such as absolute jumps) are not allowed, and are instead replaced by LMM "primitives" that the kernel knows how to execute to achieve the same thing.
So while Catalina is really a C compiler, it would be perfectly feasible to just have a very thin main C function that did nothing else other than call another function, and then write the rest of the program entirely within that function in LMM PASM. You can call the threads functions from LMM PASM.
Here is an example, which you will find in the Catalina demos\spinc folder. First, the C "main" program:
Next, the LMM PASM function:
Note that the LMM PASM above looks almost exactly like ordinary PASM, apart from the use of the "primitives" I mentioned earlier, such as JMPA and RETN. This particular example doesn't call any thread functions, but that is a simple matter - for example, to call the _thread_yield function, you would just add LMM PASM similar to the following:
Ross.
What kind of events I we talking about?
JavaScript is an event driven programming system. As are Windows GUI apps. The events are things like mouse clicks, keyboard input, timers expiring and many others. These systems generally operate in a big "event loop" that is fetching events off an event queue. The events get put into the queue by the OS and ultimately come from interrupts.
Then we have chips like the XMOS multi-core micro-controllers were each processor can run many thread loops and each of those loops can halt at any point waiting for input/output from I/O pins, communication channels, timers etc. Here the events are very much hardware assisted. There is no OS or scheduler software. They do not use interrupts.
Then we have the Propeller chip. Here "events" can be I/O pin changes or video output becoming empty. A processor, COG, can be waiting on those events. This is handled in hardware and no OS or run time support code is needed. The emphasis here is on the "can reach". Whilst it may always be possible to hand optimize assembler code a little better than a compiler I would say "50 to 100 times faster" is a gross over estimate. For example I have a Fast Fourier Transform written in Propeller Assembler and the equivalent algorithm written in C. Search for heater_fft here. Turns out the C version runs nearly as fast on the Prop as the assembler version.
What you are actually doing is wasting time writing the same functionality over and over again for different architectures in assembler rather than writing it once in a high level language and compiling it for different machines. Life is too short for that unless it is really necessary.
If the rest of the shop is negative to forth, don't even bother, C would be the best bet.
1) understand event driven programming
2) understand the target application
3) use forth
I can only help with #3, and that isnt always helpful.
2) Check
3) The question still stands.
A simple example will do. Lets say my simple app has to respond to 3 events:
1) A pin change.
2) A character arriving over UART
3) A timer timing out.
All of these are simply reported to the user by event handlers via serial out.
Probably the same way you would write event handlers in any other language that doesn't natively support event driven programming.
Write an event loop to process events as they are put on the queue and a mechanism to place things (events) on the event Q.
I guess the interpreter itself is basically an event handler - the only even it happens to know about is "key press"
The inner interpreter is also an event handler - take something off the stack, interpret it, process it, repeat until dead.
-OR- create a Forth text editor to rewrite the project spec to use another language! :thumb:
If I understand event handlers correctly (and I probably don't) this might be one suggestion.
One cog each monitors pin, UART, and time. Each cog saves its data to a hub location. This is the set of events, and the hub location is the interface.
Another cog handles the serial out. It examins each hub interface location in turn, and when it notices one of these has changed, it send an appropriate output on the serial line it controls.
The events are monitored continuously, event when the output handler is occupied. This is how the data logger for SR04 with realtime clock does it.
http://code.google.com/p/propforth/wiki/Logger1SR04
This is the best I can do at the monent. Do I understand the definition "event driven" correctly?
No idea, depends on ones definition of "event driven".
There is the event driven as used by JavaScript.
There is event driven as used by Windows or Qt GUI apps.
There is event driven as done by XMOS chips.
There is the OCCAM language model.
Perhaps more.
Your answer will do fine.
My only reservation is that "event driven" is traditionally a single processor thing and what you have there uses multiple processors, effectively a separate program for each possible event.
We could do the same thing on a PC forth using software multitasking instead of multiple cogs. Pygmy Forth, F-PC, all support this and the same software round robin can be added to any forth with enough resources for the multiple stacks.
Anyway, doesn't it always boil down to a separate program for each event? The other general choice being a single loop that addresses one at a time and ignores the others?