Recent versions of zeptoforth (release 0.25.0 or newer) now support straightforward symmetric multiprocessing in that they support interaction between tasks executing on different cores of the RP2040 interacting with one another with task communication and synchronization constructs, which was not supported by older versions of zeptoforth which only supported multicore execution where different cores did not interact with each other aside from through shared RAM, hardware spinlocks, and hardware FIFO's. Additionally any task on any core can now start a task on any given core, where previously one had to explicitly boot the second core of the RP2040 from the first core and aside from that tasks could only spawn tasks on their own core.
For an example of multicore operation combined with multitasking with shared task communication and synchronization constructs, take the following example:
continue-module forth task import systick import chan import \ The data size 1 constant element-size \ The intermediate stream byte count 256 constant inter-count \ The endpoint stream byte count 256 constant end-count \ The endpoint counter interval 1000 constant end-interval \ The tasks variable producer-task variable inter-task variable consumer-task \ The streams element-size inter-count chan-size buffer: inter-chan element-size end-count chan-size buffer: end-chan \ The data buffers element-size buffer: source-send-buf element-size buffer: inter-recv-buf element-size buffer: end-recv-buf \ The receive count variable recv-count \ The starting systick variable start-systick \ Our producer : producer ( -- ) source-send-buf element-size 0 fill begin source-send-buf element-size inter-chan send-chan again ; \ Our intermediate : inter ( -- ) begin inter-recv-buf element-size inter-chan recv-chan inter-recv-buf swap end-chan send-chan again ; \ Our consumer : consumer ( -- ) begin 1 recv-count +! end-recv-buf element-size end-chan recv-chan drop recv-count @ end-interval > if 0 recv-count ! systick-counter dup start-systick @ - cr ." Receives per second: " 0 swap 0 end-interval f/ 10000,0 f/ 1,0 2swap f/ f. start-systick ! then again ; \ Initialize our test : init-test ( -- ) 0 recv-count ! systick-counter start-systick ! element-size inter-count inter-chan init-chan element-size end-count end-chan init-chan 0 ['] consumer 320 128 512 0 spawn-on-core consumer-task ! 0 ['] inter 320 128 512 1 spawn-on-core inter-task ! 0 ['] producer 320 128 512 0 spawn-on-core producer-task ! consumer-task @ run inter-task @ run producer-task @ run ; end-module
In this example, three tasks are spawned, a consumer task on core 0, an intermediate task on core 1, and a producer task on core 0. Two queue channels (a task synchronization and communication construct that consists of a queue which one or more tasks send messages to and which one or more task receive messages from) are created, one for communication from the producer task to the intermediate task, and one for communication from the intermediate task to the consumer task.
The producer task continually sends messages to the intermediate task with the only delays being when the channel for communication from the producer task to the intermediate task is full. The intermediate task continually receives single messages from the producer task and sends the same messages to the consumer task. The consumer task continually receives messages from the intermediate task, and times how long it takes for a given number of messages to be received, with which it calculates how many messages it has received per second and displays it to the user..
By this inter-task communication is demonstrated to function across multiple cores using task communication and synchronization constructs. Likewise, one task can use RUN to initiate a task on another core, as also shown here. (Unlike previously, spawning a task on another core no longer starts it immediately; rather the user must use RUN to start its execution.)
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.