Today, we have done a message loop experiment of uC/OS-II system, write some gains.
Let's talk about the principles of the message mechanism first. The message loop can be used to implement a time-driven application, that is, each event generates a specific message, and then the message is sent to a/some task message queues, the task reads the message and processes it accordingly. Task message queues generally adopt a FIFO structure, that is, the first message task to be sent will read first.
The system message loop implemented by uC/OS is similar to the message mechanism programmed by windows. The system keeps polling to retrieve the most recent messages from the message queue for processing. Of course, the messaging mechanism implemented by uC/OS is much simpler than that implemented by windows. In uC/OS, there is a message queue in the communication mechanism, through which we can implement our message mechanism in UC/OS.
In uC/OS, message queues can work in one-to-one mode, that is, one task sends a message to the message queue, and the other task reads the message from the message queue. This method is also common. There is also a multi-to-one way of working, that is, multiple tasks send message queues to the same message queue, and only one task reads information from this message queue, this is the way we use to implement the messaging mechanism. Of course, there are other ways to work in message queues, but they are not commonly used.
We use the message queue as the task message queue, and then the task can obtain the message by reading the message in the message queue. Of course, generally, a task message queue is created only when the message loop is processed. Storage of messages requires space. Therefore, you need to define an array to store messages. Because the message types are different, the array type is void. The key to connecting the task queue to the task message queue storage zone is the OS _event * osqcreate (void ** start, int16u size) Message Queue creation function. Task message queues must be created before uC/OS is started.
The message functions used in the experiment are ready-made. In the task message header file, we can customize the message.
For example:
# Define tm_key
5762
# Define tm_keydown 5763
......
Define the structure of good news
Typedef struct tagmsg
{
Uint32 message; // Message Value
Uint32 wparam; // additional Message 1
Uint32 lparam; // additional message 2
} MSG;
Then there are two most important message functions: sendmessage () and getmessage ().
/*************************************** *************************************
* Name: sendmessage ()
* Function: send a message, that is, the message sending manager.
* Based on the actual situation, messages are distributed to different task message queues.
* Entry parameter: refers to the message (pointer) to be sent by MSG)
* Exit parameter: if the operation is successful, true is returned. Otherwise, false is returned.
**************************************** ************************************/
Uint8 sendmessage (MSG * MSG)
{
Uint32 message;
Tmq * target;
Uint8 err;
Message = MSG-> message;
Switch (Message)
{
Case tm_key:
Case tm_keydown:
Case tm_keyup:
Target = task_tmq; // if it is a keyboard message, it is sent to the Message Queue of the taskmediatmq task.
Break;
Case tm_uart0rcv:
Target = task_tmq; // If a message is received by a serial port, it is sent to the Message Queue of the taskmediatmq task.
Break;
// (Add User task message dispatch processing here)
Default: Target = NULL;
Break;
}
Err = osqpost (target, MSG );
If (ERR = OS _no_err)
Return (true );
Else
Return (false );
}
/*************************************** *************************************
* Name: getmessage ()
* Function: Wait for a message. It is returned only when a message is received.
* Entry parameter: The Message Queue (pointer) of the task waiting for tmq)
* Exit parameter: return the received message.
**************************************** ************************************/
MSG * getmessage (tmq * tmq)
{
Uint8 err;
Return (osqpend (tmq, 0, & ERR ));
}
The specific implementation code does not need to be written. The important thing is this idea and implementation method.