As you can see:
The longest time a task used in one piece is 13 microseconds - the output of the tasklist.
The first task with priority 99 builds the squarewave of the next picture. Of course there are better ways to build a square wave. Its a demonstration to show, that CoopOS can do sometihing ever 19 µs - without any jitter! Two more squarewave are built. The rotary dial is checked and counts as fast as you can turn it.
RTOS running on one core only
Re: RTOS running on one core only
- Attachments
-
- Compare1.png (139.23 KiB) Viewed 13786 times
Fast is not fast enough
Re: RTOS running on one core only
The first row are the CoopOS Scheduler calls. No ticks no - breaks.
Line 2 - 4: CoopOS squarewaves produced with different priorities from highest to lowest.
Last Line: RTOS pure taskswitches. More deterministic and fast: 2 microseconds.
But you have to live with breaks due to taskswitches, because this task must have the lowest priority.
Line 2 - 4: CoopOS squarewaves produced with different priorities from highest to lowest.
Last Line: RTOS pure taskswitches. More deterministic and fast: 2 microseconds.
But you have to live with breaks due to taskswitches, because this task must have the lowest priority.
- Attachments
-
- Compare2.png (88.9 KiB) Viewed 13771 times
Fast is not fast enough
Re: RTOS running on one core only
To make a long story short:
CoopOS is a normal RTOS task and it has to accept and handle all the rules for registers, pointers etc.
and uses the RTOS-API to manage all these things.
On the other side: it has own timers and must not do RTOS-taskswitches and is never preempted, because it is pinned to core 1 and interrupts are disabled ONLY for this core.
Where, Deouss, is your problem ?
CoopOS is a normal RTOS task and it has to accept and handle all the rules for registers, pointers etc.
and uses the RTOS-API to manage all these things.
On the other side: it has own timers and must not do RTOS-taskswitches and is never preempted, because it is pinned to core 1 and interrupts are disabled ONLY for this core.
Where, Deouss, is your problem ?
Fast is not fast enough
Re: RTOS running on one core only
I can replace the
xTaskCreateStaticPinnedToCore(
to a normal xTaskCreate without make any other changes.
The effect: I dont know, which core is used and I get breaks from preemption. Thats all.
IT IS AN RTOS TASK - but this task behaves like an OS - because it is able to run without any other OS.
It can have own semphores, signals etc. inside its own system - and it can use (when a task of RTOS) - all RTOS API calls.
And you can mix both.
Example: RTOS and CoopOS use the same Ringbuffer for output and have to respect all the rules which you have to deal with using the same resource. And then I can build a task for the transfer to the UART.
It can be created as an CoopOS task or an RTOS task.
Think of it as an RTOS task built as a state machine - with the "trick" that it is never preempted.
With this point of view you can do it with ANY RTOS task:
Pin it to the core 1 and disable interrupts. Than you can do inside this task whatever you want - respecting the rules, and be sure to be never preempted. Count microseconds and you can be sure you never will miss one.
xTaskCreateStaticPinnedToCore(
to a normal xTaskCreate without make any other changes.
The effect: I dont know, which core is used and I get breaks from preemption. Thats all.
IT IS AN RTOS TASK - but this task behaves like an OS - because it is able to run without any other OS.
It can have own semphores, signals etc. inside its own system - and it can use (when a task of RTOS) - all RTOS API calls.
And you can mix both.
Example: RTOS and CoopOS use the same Ringbuffer for output and have to respect all the rules which you have to deal with using the same resource. And then I can build a task for the transfer to the UART.
It can be created as an CoopOS task or an RTOS task.
Think of it as an RTOS task built as a state machine - with the "trick" that it is never preempted.
With this point of view you can do it with ANY RTOS task:
Pin it to the core 1 and disable interrupts. Than you can do inside this task whatever you want - respecting the rules, and be sure to be never preempted. Count microseconds and you can be sure you never will miss one.
Fast is not fast enough
Re: RTOS running on one core only
In fact I can take the programs written for an original Arduino Uno and CoopOS. Then I write some #defines to replace DigitalWrite etc. And I have to replace the routine micros() to get the time. Thats all!
Then I can use the same old libraries and let 10 LEDs blink with 100 Hz. No other changes are done.
The code and the timings are the same.
Because CoopOS is made with pure Ansi-C this porting can be done for every processor. And if there is an OS, that allows to reserve a core. It does never use the PC or the CPU registers in an other way, than a normal C program does. It works with an old Apple II or DOS Machine as well as the newest supercomputer. You may think of it like µGUI. This tools needs the implementation of a mouse and SetPixel(). Than you can build (a tiny) Window-System, that can run everywhere - even under Windows. Handling different Windows with its own eventmanager - using an embedded system without any OS or a Linux-machine. Is this an OS ?
If you can do anything you need an RTOS for - is it an OS?
I say it again: I am happy with the RTOS of ESP32 and CoopOS is not a replacement. Some things can be done with the RTOS the best way possible. But sometimes CoopOS is much faster and there are very good reasons to combine the two OSs.
CoopOS does not deal with different stacks. It takes what it got, when it was started.
I have used it- as I wrote - with Raspberry Pi 3+ bare metal (up to 10.000.000 taskswitches per second) and raspberry Pi with Linux preempt (then you have to take into account to have some breaks up to 50 µs).
It is not allways that easy to port a program from one OS to another.
I hope my explanation was understandable
PS. Do not forget the challenge
Then I can use the same old libraries and let 10 LEDs blink with 100 Hz. No other changes are done.
The code and the timings are the same.
Because CoopOS is made with pure Ansi-C this porting can be done for every processor. And if there is an OS, that allows to reserve a core. It does never use the PC or the CPU registers in an other way, than a normal C program does. It works with an old Apple II or DOS Machine as well as the newest supercomputer. You may think of it like µGUI. This tools needs the implementation of a mouse and SetPixel(). Than you can build (a tiny) Window-System, that can run everywhere - even under Windows. Handling different Windows with its own eventmanager - using an embedded system without any OS or a Linux-machine. Is this an OS ?
If you can do anything you need an RTOS for - is it an OS?
I say it again: I am happy with the RTOS of ESP32 and CoopOS is not a replacement. Some things can be done with the RTOS the best way possible. But sometimes CoopOS is much faster and there are very good reasons to combine the two OSs.
CoopOS does not deal with different stacks. It takes what it got, when it was started.
I have used it- as I wrote - with Raspberry Pi 3+ bare metal (up to 10.000.000 taskswitches per second) and raspberry Pi with Linux preempt (then you have to take into account to have some breaks up to 50 µs).
It is not allways that easy to port a program from one OS to another.
I hope my explanation was understandable
PS. Do not forget the challenge
Fast is not fast enough
Re: RTOS running on one core only
Well you are playing with performance levels and want to achieve fast as you call 'task switching'.
Why don't you reverse engineer xTaskCreate...() functions into ASM because those are thread context switching subroutines and they are not optimized the custom way you want here. Or maybe just write your own task creation and management routines that can be used for your custom 'CoopOS' maneuvers)
I don't quite see an idea of two operating systems running in the same small microcontroller. That would make more sense for fpgas like RPi. RTOS is written to handle tasks optimized within its own environment. Your CoopOS is just a function handling compatibility issues from ported code as you mentioned. Still don't see logical relation to being a second OS.
No matter how you manipulate your Arduino and other ported code - if you want to achieve best performance unfortunately you have to completely rewrite it.
Why don't you reverse engineer xTaskCreate...() functions into ASM because those are thread context switching subroutines and they are not optimized the custom way you want here. Or maybe just write your own task creation and management routines that can be used for your custom 'CoopOS' maneuvers)
I don't quite see an idea of two operating systems running in the same small microcontroller. That would make more sense for fpgas like RPi. RTOS is written to handle tasks optimized within its own environment. Your CoopOS is just a function handling compatibility issues from ported code as you mentioned. Still don't see logical relation to being a second OS.
No matter how you manipulate your Arduino and other ported code - if you want to achieve best performance unfortunately you have to completely rewrite it.
Re: RTOS running on one core only
Some links to cooperative multitasking:
---------------------------------------
Good entry points with references to most Languages/Compilers:
https://en.wikipedia.org/wiki/Coroutine
https://en.wikipedia.org/wiki/Green_threads
One wellknown name in the community:
https://kennykerr.ca/2012/08/03/lightwe ... ng-with-c/
https://msdn.microsoft.com/en-us/magazine/mt573711
Node.js is well known as to be very fast (using cooperative multitasking in the background)
https://stackoverflow.com/questions/652 ... sking-work
Lua:
http://www.lua.org/pil/9.html
python 3.5:
https://luminousmen.com/post/asynchrono ... n-blocking
common lisp:
https://github.com/thezerobit/green-threads
Here are the newst trends how C++17 and C++20 will support coroutines
https://modernescpp.com/index.php/compo ... 20#h1-c-17
---------------------------------------
Good entry points with references to most Languages/Compilers:
https://en.wikipedia.org/wiki/Coroutine
https://en.wikipedia.org/wiki/Green_threads
One wellknown name in the community:
https://kennykerr.ca/2012/08/03/lightwe ... ng-with-c/
https://msdn.microsoft.com/en-us/magazine/mt573711
Node.js is well known as to be very fast (using cooperative multitasking in the background)
https://stackoverflow.com/questions/652 ... sking-work
Lua:
http://www.lua.org/pil/9.html
python 3.5:
https://luminousmen.com/post/asynchrono ... n-blocking
common lisp:
https://github.com/thezerobit/green-threads
Here are the newst trends how C++17 and C++20 will support coroutines
https://modernescpp.com/index.php/compo ... 20#h1-c-17
Fast is not fast enough
Re: RTOS running on one core only
Yes) All that you mentioned here are nice computer science definitions that are hard to achieve perfectly working in real world
I can tell you from experience - any tricks as those cooperative manipulations with ported or structurally incompatible code - they lead to serious conflicts and future problems. I know it is fast and lazy way of making code work but this is not always true and most likely leaves the next generation of programmers in big troubles and headaches to deal with ugly old code
Well that's my opinion because I worked with those ugly projects. Doing that stuff on poor MCU seems a bit overkill.
I can tell you from experience - any tricks as those cooperative manipulations with ported or structurally incompatible code - they lead to serious conflicts and future problems. I know it is fast and lazy way of making code work but this is not always true and most likely leaves the next generation of programmers in big troubles and headaches to deal with ugly old code
Well that's my opinion because I worked with those ugly projects. Doing that stuff on poor MCU seems a bit overkill.
Re: RTOS running on one core only
Let me answer with
Kenny Kerr
Author • Systems programmer • Creator of C++/WinRT • Engineer on the Windows team at Microsoft • Romans 1:16
"If you work for a company that has one of those coding standards documents that would annihilate an entire rainforest were it ever to be printed, you’d better stop reading now. Chances are, what I’m about to show you will violate many of the sacred cows in the aforementioned epic. I’m going to tell you about a particular technique I originally developed to allow me to write completely asynchronous code efficiently and without the need for complex state machines."
In Germany we say "What the farmer does'nt know he wont eat"
Try your job to do at your best. You must not read what you do not understand.
But if you are afraid, that a regulary created RTOS-task respecting all rules you may find in the docs may be dangerous for your work and your experience is not to try new ways - just do it your way.
It is obvious that the makers of the Esp32, who ported freeRTOS to a 2 core machine (PRO CPU and APP CPU) did have more in mind than to get a balanced distribution of tasks between these 2 cores.
They spend some work into disabling interrupts for one CPU while the other is running with all ticks and timers and interrupts working.
But let us see how you manage to find a solution for the challange: I have done it and showed how you can test it yourself.
Now its your turn. And THAN we can discuss: What is the better way
Sorry, but I would prefer talking about practical work. Believings and philosophy are themes for a bbq..
The challenge is (maybe you have forgotten)
ESP32, RTOS, allowed is,what you can find in the docs.
An asynchronous pulse (rising edge) arrives at an input pin.
Answer within 200 ns (Nanoseconds) with a pulse of 250 ns width at another pin.
This showed method is fast enough to measure the speed of a bullet comming out of the gun with 1 (one) laserpointer.
I have done as you can read. Now its your turn to program instead of doing small talk.
In the meantime i did some measurements with this method:
Kenny Kerr
Author • Systems programmer • Creator of C++/WinRT • Engineer on the Windows team at Microsoft • Romans 1:16
"If you work for a company that has one of those coding standards documents that would annihilate an entire rainforest were it ever to be printed, you’d better stop reading now. Chances are, what I’m about to show you will violate many of the sacred cows in the aforementioned epic. I’m going to tell you about a particular technique I originally developed to allow me to write completely asynchronous code efficiently and without the need for complex state machines."
In Germany we say "What the farmer does'nt know he wont eat"
Try your job to do at your best. You must not read what you do not understand.
But if you are afraid, that a regulary created RTOS-task respecting all rules you may find in the docs may be dangerous for your work and your experience is not to try new ways - just do it your way.
It is obvious that the makers of the Esp32, who ported freeRTOS to a 2 core machine (PRO CPU and APP CPU) did have more in mind than to get a balanced distribution of tasks between these 2 cores.
They spend some work into disabling interrupts for one CPU while the other is running with all ticks and timers and interrupts working.
But let us see how you manage to find a solution for the challange: I have done it and showed how you can test it yourself.
Now its your turn. And THAN we can discuss: What is the better way
Sorry, but I would prefer talking about practical work. Believings and philosophy are themes for a bbq..
The challenge is (maybe you have forgotten)
ESP32, RTOS, allowed is,what you can find in the docs.
An asynchronous pulse (rising edge) arrives at an input pin.
Answer within 200 ns (Nanoseconds) with a pulse of 250 ns width at another pin.
This showed method is fast enough to measure the speed of a bullet comming out of the gun with 1 (one) laserpointer.
I have done as you can read. Now its your turn to program instead of doing small talk.
In the meantime i did some measurements with this method:
Fast is not fast enough
Re: RTOS running on one core only
[Codebox]
//REG_WRITE(GPIO_OUT_W1TC_REG,(1<<PinY)); // 50 ns
// gpio_set_level(PinY, 0 ); // 147.5 ns
//if( xSemaphoreTake( xSemaphore, 0 ) == pdTRUE ) { // 710 ns (rare), 1080 ns (rare) - 3000 ns (sometimes) - 3380 ns (mostly) - 6600 ns (rare)
//xSemaphoreGive( xSemaphore );
//}
//gpio_set_direction(Pin6, GPIO_MODE_INPUT ); // both: 1550, one: 868, 686 ns
//gpio_set_direction(Pin6, GPIO_MODE_OUTPUT ); //
//counter++; // uint64_t without VOLATILE: 0, with V.: 88 ns
// uint32_t with V: 37 ns
//y=x*1.234; // 225 ns
//y=sinf(x); // x,y float: , 250,262 ns, double: 545,550
//y=sin(x); // x,y float: 640, 650 ns, double: 413, 422.5 ns
//esp_task_wdt_reset(); // 1190 ns
Pause(36); // 0:50, 10:325, 100:2990 200:5855, 1000:29475 2000:58675
// y=29.2 * x + 33, f(20)=(calc)617, =(meas)615
[/Codebox]
//REG_WRITE(GPIO_OUT_W1TC_REG,(1<<PinY)); // 50 ns
// gpio_set_level(PinY, 0 ); // 147.5 ns
//if( xSemaphoreTake( xSemaphore, 0 ) == pdTRUE ) { // 710 ns (rare), 1080 ns (rare) - 3000 ns (sometimes) - 3380 ns (mostly) - 6600 ns (rare)
//xSemaphoreGive( xSemaphore );
//}
//gpio_set_direction(Pin6, GPIO_MODE_INPUT ); // both: 1550, one: 868, 686 ns
//gpio_set_direction(Pin6, GPIO_MODE_OUTPUT ); //
//counter++; // uint64_t without VOLATILE: 0, with V.: 88 ns
// uint32_t with V: 37 ns
//y=x*1.234; // 225 ns
//y=sinf(x); // x,y float: , 250,262 ns, double: 545,550
//y=sin(x); // x,y float: 640, 650 ns, double: 413, 422.5 ns
//esp_task_wdt_reset(); // 1190 ns
Pause(36); // 0:50, 10:325, 100:2990 200:5855, 1000:29475 2000:58675
// y=29.2 * x + 33, f(20)=(calc)617, =(meas)615
[/Codebox]
Fast is not fast enough
Who is online
Users browsing this forum: Google [Bot] and 115 guests