These projects are designed to start with the most simple configs. I know that two multitasking tasks (sub-processors) in one cog would be the most simple, and I could expand on it. Showing blinking rates of LEDs can confirm the threads are working. In the end, the LEDs are not actually needed, unless they're being used for some output.
I like the first program, - it's one program with all the threads/tasks easily grouped for mods and programming. You can easily see what you have in each "sub-processor."
I like the second "program" with two files. It can take the second file and treat it like one sub-processor and then reproduce it many times and change each one by parameter passing. It saves a lot of programming code and undoubtedly more sub-processors will fit into a single cog. This is like one sub-processor duplicated with many instances running as multitasking.
For me, this project has improved, because several experts have posted variations upon a theme. This is the right thing to do. It has led to more compacted code, better timing, and different methods.
Many great things in this world were developed by trying new things. I think all these posts are vital, significant, worthy, accurate, and profound. I am honored that the world's top thinking minds are contributing to this Forum thread.
To "update" the original specs, add more threads (not just two), more accurate timing (as heater said, rtc may be needed), more explanation how to change things as the number of sub-processors grow (to maintain timing). So it seems the thread is moving in the right direction.
I would use the first program (one file only) and strive to improve it by running more than 20 threads on it. Stoke it with the most working threads. (It's working with 20)
I would also use the 2nd program (with 2 files) that would allow the first file to parameter pass to the second file. The second file is (multi threaded, time shared) with many instances of sub-processors in a single cog.
The big picture - get the greatest number of threads working within the limits of speed and accuracy. Maybe some threads report to LEDs to show they are working, while other threads simply do some computations or self looping to represent processing.
I like the idea where LED code is there in each task, but commented out until it is needed for verification..
I like the idea of each sub-processor inside a cog sharing resources from both outside and inside the cog (counters, pins, LEDs, memory, eeprom, ram, rom, etc.)
I would leave it up to the programmer of sub-processors not to produce any clashes of resources and to understand the consequences of multiple outputs to a single pin for example.
Keeping it simple, easy to use, well commented, and understandable is always a top priority.
One point for having the two file solution is that the logic of flashing the LED, in this case, is separated from the logic of the scheduler. These two things are conceptually independent so let's put each in it's own box. What if we add in some other tasks? Say something monitoring some buttons and doing whatever as a result. Or perhaps keeping an eye on some measurement. These tasks can be, again, conceptually independent so put them in their own boxes. Come the time to make changes you know where everything is. They are more isolated so changes to one are less likely to damage another one.
In this simple LED flasher scenario it hardly seems worth it but as things get bigger and more complicated this kind of division and classification helps keep everything straight in your mind.
One point for having the two file solution is that the logic of flashing the LED, in this case, is separated from the logic of the scheduler. These two things are conceptually independent so let's put each in it's own box. What if we add in some other tasks? Say something monitoring some buttons and doing whatever as a result. Or perhaps keeping an eye on some measurement. These tasks can be, again, conceptually independent so put them in their own boxes. Come the time to make changes you know where everything is. They are more isolated so changes to one are less likely to damage another one.
In this simple LED flasher scenario it hardly seems worth it but as things get bigger and more complicated this kind of division and classification helps keep everything straight in your mind.
Thank you for this suggestion - if I understand correctly, we have our 1st file program - the operating system of the cog, taking care of running many sub-processors (scheduling, multitasking, timing), and all the other files are sub-processors. Some are pure sub-processors waiting to be programmed, others have pre-programmed functions to offer, some with tasks of clock, or LCD, LED, or key press, or watchful eyes, or purely tiny computational machines, or even other special functions like tasks of tiny sub-processor groups that do special things and act upon data in special "software swarming" ways to attack certain problems.
Each in their own "box." In a way, by creating many of these second files, we are creating our own standard of tiny OBEX sub-processors in a single cog. I'm thinking about some really tiny obex subprocessor task programs so many can run in a single cog. This will need some simple examples.
Once the program is firmly established, it would be useful to have a file with the maximum number of sub-processors, to learn what our duplicity limits are with the system and in regards to a timing envelope.
So we'll create a second file with the maximum number of itsy bitsy tiny minuscule little minimal subprocessors that can do things (add numbers, find whole cube roots, calculate pi, calculate subprocessor info, blink LEDs, say "Hello World," a tiny clock) and some vacant subprocessors that are open to programming. (maybe some are on, some are off if not used) These can be clever little programs, so it will be exciting, fun and challenging to create. Emphasis is again on tiny apps to enable the maximum capability and top notch performance of ALL subprocessors working at the same time.
One point for having the two file solution is that the logic of flashing the LED, in this case, is separated from the logic of the scheduler. These two things are conceptually independent so let's put each in it's own box...
I used to discuss with my programming staff the benefits of object-oriented programming versus so-called "spaghetti code" (where programs branch all over the place rather utilizing sub-routines).
Obviously, the design of the propeller chip and the spin language is geared toward the object-oriented approach.
Each taskname : "task_led_flasher" statementin the OBJ section instaniates a new instance of the task_led_flasher with it's set of variables. Thus Heater's two-file approach is the way to isolate the LED variables and related methods into a object (or box as you will).
I used to discuss with my programming staff the benefits of object-oriented programming versus so-called "spaghetti code" (where programs branch all over the place rather utilizing sub-routines). Obviously, the design of the propeller chip and the spin language is geared toward the object-oriented approach. Each taskname : "task_led_flasher" statementin the OBJ section instantiates a new instance of the task_led_flasher with it's set of variables. Thus Heater's two-file approach is the way to isolate the LED variables and related methods into a object (or box as you will).
Ron, I know what you're talking about. I once saw a company running on machine that had a program which was 80% GOTO statements. They wanted it modified, but the code did not have one comment or any info. Five programmers had worked on it, each adding their own GOTOs. I actually could not believe my eyes when I saw the program!
As I see it so far, the first file is the task handler/OS. It's needed to define the passing parameters and create instances of which tasks to perform on the same object. The second file is the object. It can be configured with parameters from the first file and made into 10 instances or a hundred. Generally the second file is the subprocessor and the first file configs it and runs it. So overall, a hundred subprocessors will simply become 100 tasks in the task handler/OS.
Now back to the program. (I'm creating a new machine to run it on, with 32 LEDs that can be selectively banked with 32 tasks per bank. This presumes that a prop chip will work with LEDs on each pin. It will be spartan, mainly a prop chip only.)
Comments
I like the first program, - it's one program with all the threads/tasks easily grouped for mods and programming. You can easily see what you have in each "sub-processor."
I like the second "program" with two files. It can take the second file and treat it like one sub-processor and then reproduce it many times and change each one by parameter passing. It saves a lot of programming code and undoubtedly more sub-processors will fit into a single cog. This is like one sub-processor duplicated with many instances running as multitasking.
Humanoido
Many great things in this world were developed by trying new things. I think all these posts are vital, significant, worthy, accurate, and profound. I am honored that the world's top thinking minds are contributing to this Forum thread.
To "update" the original specs, add more threads (not just two), more accurate timing (as heater said, rtc may be needed), more explanation how to change things as the number of sub-processors grow (to maintain timing). So it seems the thread is moving in the right direction.
Humanoido
I would also use the 2nd program (with 2 files) that would allow the first file to parameter pass to the second file. The second file is (multi threaded, time shared) with many instances of sub-processors in a single cog.
The big picture - get the greatest number of threads working within the limits of speed and accuracy. Maybe some threads report to LEDs to show they are working, while other threads simply do some computations or self looping to represent processing.
I like the idea where LED code is there in each task, but commented out until it is needed for verification..
Humanoido
I would leave it up to the programmer of sub-processors not to produce any clashes of resources and to understand the consequences of multiple outputs to a single pin for example.
Keeping it simple, easy to use, well commented, and understandable is always a top priority.
Humanoido
One point for having the two file solution is that the logic of flashing the LED, in this case, is separated from the logic of the scheduler. These two things are conceptually independent so let's put each in it's own box. What if we add in some other tasks? Say something monitoring some buttons and doing whatever as a result. Or perhaps keeping an eye on some measurement. These tasks can be, again, conceptually independent so put them in their own boxes. Come the time to make changes you know where everything is. They are more isolated so changes to one are less likely to damage another one.
In this simple LED flasher scenario it hardly seems worth it but as things get bigger and more complicated this kind of division and classification helps keep everything straight in your mind.
Each in their own "box." In a way, by creating many of these second files, we are creating our own standard of tiny OBEX sub-processors in a single cog. I'm thinking about some really tiny obex subprocessor task programs so many can run in a single cog. This will need some simple examples.
Once the program is firmly established, it would be useful to have a file with the maximum number of sub-processors, to learn what our duplicity limits are with the system and in regards to a timing envelope.
Humanoido
Humanoido
I used to discuss with my programming staff the benefits of object-oriented programming versus so-called "spaghetti code" (where programs branch all over the place rather utilizing sub-routines).
Obviously, the design of the propeller chip and the spin language is geared toward the object-oriented approach.
Each taskname : "task_led_flasher" statement in the OBJ section instaniates a new instance of the task_led_flasher with it's set of variables.
Thus Heater's two-file approach is the way to isolate the LED variables and related methods into a object (or box as you will).
As I see it so far, the first file is the task handler/OS. It's needed to define the passing parameters and create instances of which tasks to perform on the same object. The second file is the object. It can be configured with parameters from the first file and made into 10 instances or a hundred. Generally the second file is the subprocessor and the first file configs it and runs it. So overall, a hundred subprocessors will simply become 100 tasks in the task handler/OS.
Now back to the program. (I'm creating a new machine to run it on, with 32 LEDs that can be selectively banked with 32 tasks per bank. This presumes that a prop chip will work with LEDs on each pin. It will be spartan, mainly a prop chip only.)
Humanoido