Blog2 RTOS Tao Wang

 First,to know about RTOS,we use the PCW compiler and the microcontroller base on this compiler.

You first need to know the concept of the RTOS,it is like the tasks run  in differnt condition in real time and also need to set the prority of the different tasks.

and we use the state diagram which help us to figure out the change between different tasks.

just a example the state change in different condition,we can assume it as different task in RTOS,and the condition we can use statement :if,while.



#use rtos(timer=1,minor_cycle=100ms)

This line is crucial. It means:

Use Timer1 as the "time base" (timing source) of the RTOS.

The smallest scheduling granularity (minor cycle) of the RTOS is 100ms.

You can think of it as the RTOS "tickling" every 100ms to check which tasks should run.


Your task rate should ideally be an integer multiple of minor_cycle; otherwise, there may be errors or it may not be supported.

Here, minor_cycle=100ms, so common task cycles can be:

100ms, 200ms, 500ms, 1000ms, 2000ms, etc.


Task 3: Print 3 every 100ms


Task 4: Print 4 every 100ms


Task 2: Print 2! every 500ms


Task 1: Print 1 every 1000ms





in the task2,we add the restar in while(1)


`rtos_terminate();`

A task can actively stop the entire system scheduling.


The process is as follows:

Start the RTOS scheduler: `rtos_run()`

Multiple tasks run periodically.

The first task executes 5 times and then calls `rtos_terminate()`.

RTOS stops and returns to main.

Main prints "restart".

Another round of RTOS execution begins.









Then we move to the task3,Building upon the first two demos, this demonstration shows how to dynamically enable/disable a task while it is running (rtos_enable / rtos_disable).


Prints 1 per second.

When counter equals exactly 3, disable task4.

After disabling, task4 will no longer be scheduled for execution (and will no longer print 'd').

In the task 1,just keep print till the counter=3,but you can see the different tasks have differnt time,task3 rate=100ms ,this one seems like most frequently.



then we move to the demo4,we could see the task recevie message between each other
Tasks use a message queue to pass data between them.

We now present 3 important functions of the demo:

`rtos_msg_poll()`

Returns: The number of messages in the current task queue.
Your comment is crucial: If the queue is empty and you try to read it, it might "hang" (block and wait for a message).

`rtos_msg_read()`
Reads the earliest message in the current task queue (FIFO).
Removes the message from the queue after reading it.

`rtos_msg_send(target_task, value)`
Sends `value` to the message queue of `target_task`.







Then we move to the demo5,
task1 do the counter++,and task2 just print what the counter is now,

`count` starts at 0 (a local variable, but the RTOS preserves the task context, so it continues to accumulate).

Entering an infinite loop:
`count++`
Send `count` as a message to the queue of task2.

If I press the reset button on the board, the counting will restart.






in the demo6,
The system has two periodic tasks (both scheduled every 1 second).

Whoever acquires the lock first (rtos_wait(sem)) has exclusive access to the resources and can run its own LCD display loop until it finishes; the other task must wait for it to release the lock (rtos_signal(sem)) before it can use the resource.

Therefore, the effect is that the LCD will display the content of task1 in blocks for a period of time, then jump to display the content of task2 for a period of time, but very quickly.




this jump between the task 1 and task2,and print the current state on the lcd .


in the demo7,
Task2 increments the count each time it runs. When the count reaches 10, Task1 is allowed to execute once. Then, the count is reset to zero, and the next round begins.

Task2 (every 1000ms)

Each run displays "task2 red on/off" on the LCD (approximately 400ms each time).

Then, count is incremented.

Equivalent to: incrementing count by 1 per second.

Task1 (every 1000ms)

From the beginning, it uses:

rtos_await(count==10);

Meaning:

Task1 only continues execution when count==10.

It displays "task1 red on/off" on the LCD (approximately 1 second each time).

Then, count is reset to 0 (reset count).







Task 2 intentionally slows itself down until it exceeds the RTOS's allowed "maximum runtime max=100ms", thus triggering an overrun (task timeout).

Task 1 periodically reads Task 2's statistics (total time, minimum/maximum time) and prints them to the serial port:

`task_total_ticks`: The total number of ticks used by Task 2

`task_min_ticks`: The minimum tick used in a single run of Task 2

`task_max_ticks`: The maximum tick used in a single run of Task 2

`hns_per_tick`: The number of hundred-nanoseconds (100ns) corresponding to each tick

`count` increments with each loop (until an overrun occurs)

Then `count` times `delay_ms(50)` is executed, meaning the current loop time is approximately = `count` × 50ms.







In the demo 9,we can do communication between the microcontroller and the pc and react as i enter the command in pc.
Two RTOS Cyclic Tasks

#task(rate=1000ms,max=100ms) The_first_rtos_task

#task(rate=1000ms,max=100ms) The_second_rtos_task

task1: Scheduled once per second, displaying "task1 red on/off" on the second line of the LCD.

task2: Scheduled once per second, displaying "task2 red on/off" on the first line of the LCD.

Command Processing Task The_kernal (500ms)

#task(rate=500ms,max=100ms)

void The_kernal();

This is the core "console":

Prints the prompt INPUT:>

Waiting for input_ready==TRUE (indicating that the interrupt has received a complete command line)

Using rtos_yield() during the wait

Comparing the input with four command strings:

enable1 → Enable task1

enable2 → Enable task2

disable1 → Disable task1

disable2 → Disable task2

Execute the corresponding rtos_enable/rtos_disable command

enable1: task1 starts running (LCD starts displaying task1 from line 2)

disable1: task1 stops running

enable2: task2 starts running (LCD starts displaying task2 from line 1)

disable2: task2 stops running



As we can see in the initial version, after disabling task1 and task2, I had to enable task2 first; otherwise, enabling task1 would result in an invalid command. However, in the second version, we fixed this bug, and these four commands will no longer conflict.





Finally, I'd like to discuss this compilation environment. Its convenience lies in the fact that you don't need to manually add and initialize hardware header files. Also, since board resources are relatively limited, this compiler essentially integrates these functions, eliminating the need for manual configuration or adjustments. This contrasts with the Keil environment, where creating a project requires manually adding the necessary hardware header files and initializing them in main.c, and defining an RTOS core to determine task priorities and scheduling.









































Comments

Popular posts from this blog

Blog 1 - Igor Kapusniak