综述
场景
在系统A中,任务A周期发送cmd1,发送前,将RS485设置发送模式,发送完成后,立马切换为接收模式,等待系统B返回字符串信息。此时,在系统A中,另一任务B随机发送cmd2,在发送时,也会将RS485切换成发送模式,但是此时系统B正在返回字符串信息,就有可能,任务B打断了任务A的接收,因为RS485的发送接收模式被切换了。
-
场景A:
-
场景B
尝试解决方法
互斥锁
-
Mutexes are used for managing resources by avoiding conflicts caused by simultaneous use of a resource.
互斥锁是对某资源同时访问的保护。 -
1.Task A begins writing to the terminal
-
2.Task B interrupts Task A and writes to the terminal
-
3.Task A is resumed and its output is written at a wrong position
static OS_STACKPTR int StackHP[128], StackLP[128]; // Task stacks
static OS_TASK TCBHP, TCBLP; // Task-control-blocks
static OS_MUTEX Mutex;
static void _Write(char const* s) {
OS_MUTEX_LockBlocked(&Mutex);
printf(s);
OS_MUTEX_Unlock(&Mutex);
}
static void HPTask(void) {
while (1) {
_Write("HPTask\n");
OS_TASK_Delay(50);
}
}
static void LPTask(void) {
while (1) {
_Write("LPTask\n");
OS_TASK_Delay(200);
}
}
int main(void) {
OS_Init(); // Initialize embOS
OS_InitHW(); // Initialize hardware for embOS
OS_TASK_CREATE(&TCBHP, "HP Task", 100, HPTask, StackHP);
OS_TASK_CREATE(&TCBLP, "LP Task", 50, LPTask, StackLP);
OS_MUTEX_Create(&Mutex); // Creates mutex
OS_Start(); // Start multitasking
return 0;
}
信号量
- A semaphore is a variable or abstract data type used to control access to a common resource by multiple processes in a multitasking operating system.For example, they are commonly used in “credittracking synchronization” where a task needs to wait for something that can be signaled one or more times.
- 信号量可以用来在多任务(线程)间进行控制
- 当多个任务同时等待某个信号量时,再信号量可得时,优先级高的任务先执行
//fake demo
OS_SEMAPHORE _Sema;
create_semaphora(&_Sema);
Set_Semaphora(&_Sema, 1);
//Task A
while(1){
do_something_A()
{
OS_Semaphre_TakeBlock(_&Sema); //发送前
send_cmd1();
}
if(rece_finish) //rece_finish flag is set in RX ReceiveIRQ Handler
{
Set_Semaphora(&_Sema, 1);
}
if(timeout)
{
Set_Semaphora(&_Sema, 1);
}
OS_Delay(100);
}
//Task B, Priority is low than Task A
OS_Semaphre_TakeBlock(_&Sema);
do_something_B()
{
Send_Cmd2();
}
Set_Semaphora(&_Sema, 1);
MailBox
任务之间传递少量固定大小数据。
MainBox can handler small message with fixed data size only.固定字节数
void OS_MAILBOX_Create(OS_MAILBOX* pMB, //point to a Mailbox object of type OS_MAILBOX
OS_U16 sizeofMsg, //sizeof a message in bytes,1<=sizeofmsg<=32767
OS_UINT maxnofMsg, //maximum number of messages.
void* Buffer); //pointer to a memory area used as buffer.
问题
调试的时候,发现在Task B发送Cmd2时,此时要等到超时才能发送cmd2,先Mark。看看能否优化。
Queues
embos提供Queues机制
- Queues enable inter-task communication with larger messages or with messages of differing lengths. 提供可变长度的消息
- Queues像普通的buffer,可以向里面放入数据,取出数据。
- Queues works like FIFO, 先进先出
- Difference between queues and mailboxes:
- 接收可变长度消息,当存消息至Queues时,消息大小作为一个参数。
- 取出消息时不是拷贝消息,而是返回指向消息结构体的指针。
- 取出消息函数必须删除消息,再处理之后。
- 取出新消息只有在之前的消息删除之后才能进行。