 
					
				 
					
				实验三事件标志
事件标志实验相对比较简单,其实就是创建初始化一个事件标志为01,同时创建2个优先级相同的任务A和B。
A的触发事件标志为1(01),B的触发事件标志为2(10)。
A触发执行时把事件标志set为10;A结束后,B被触发执行并将事件标志set为01;B结束后,A触发执行……;如此反复进行。这里要注意事件标志位SVC函数的含义,tk_clr_flg函数仅仅是清除,并不引起任务的调用,而tk_set_flg函数执行后,一旦此事件标志符合某任务的触发条件,这个任务就会进入运行态或就绪态。
编译,下载,得到串口打印信息。
	
简要分析打印信息,A和B在各自的循环中将事件标志位设置为对方的触发条件,这样A和B就一直在轮询。基本上ok。实验之余,我将A的事件标志设置为5(101),B的事件标志设置为4(100),初始化事件标志为4(100),B任务最后将事件标志位设置为5(101)。
	 
 
通过串口信息发现B进入任务循环后再也无法触发任务A。
难道每个任务等待事件标志位仅等待第一位?求科普。
	
实验三思考题
1) 本实验中演示了两个同优先级任务使用事件标志进行交替的方式,如果把一个任务更换为中断,结果如何?
本来想提前学习一下μTenux的中断管理,但发现v1.5和v1.6版本源码的例程中木有中断的例子。
自己尝试设置了不可屏蔽中断和服务程序,但是发现有些变量找不到定义。
先mark,待日后学习了中断再来解答。
	2) 本实验中演示了两个同优先级任务使用事件标志进行交替的方式,如果把一个任务的优先级提高,结果如何?什么情况下,会使用到这种方式?
我分别设置了优先级A>B和A <B
优先级A>B:
	
不解释,很常规。
	
	优先级A<B
	
通过串口信息,不难分析,B运行后,由于无法等到事件标志位而进入等待状态,这个时候A就进入运行态,在A完成任务后,B才能进入运行态。
看来事件标志位的作用还是很大的,如果一个优先级高的任务中含有从优先级低的任务里面才能获取的变量,那么这个时候用事件标志位去使得高优先级任务等待低优先级任务的参数传递时再好不过的了。
举个例子,如果一个传感器数据处理的系统,数据处理任务优先级高,传感器驱动获取数据的任务优先级较低,那么就可以利用事件标志位,让数据处理任务在需要传感器数据的时候进入等待态,而传感器驱动获取数据的任务进入运行态,在传感器驱动获取数据的任务完成后,再set事件标志位并返回获取的数据,传递给数据处理任务进行处理。
不知这种应用是否得当,求大拿指点哇。
	
TBC......
	
	
	
 
					
				实验四 消息邮箱
邮箱特像古代的烽火台,只要人(任务)在看到(等待邮箱消息)烽火台点燃,人(任务)就立刻进入下一个操作。实验的源码写得很易懂,创建-A发送-A等待-B收取-B发送-A接收,流程十分清楚。
源码编译、下载,得到期望的打印信息。
	
 
不解释。
想尝试一下多个消息的发送,看看内核规范,源码中邮箱可以设置为FIFO和优先级两种发送模式,设置一下。
FIFO模式:
	
 
经典的FIFO,先发送的消息先收到。
优先级模式:
这个模式花了点时间研究T_MSG、U_SMG和T_SMG_PRI之间的关系,但是还存在有问题。
	
 
呃,A发送优先级为9的“尼玛速度运行”和优先级为10的“1-2-3,Please starting up....”,B先接收到的是“尼玛速度运行”,再接收“1-2-3,Please starting up....”,是不是和系统的功能一样呢?我觉得是。
为毛B在发送第二条消息的时候(和A的发送模式一样),会返回E_PAR(错误的参数传递),源代码在下面:
	
#include "MailboxSample.h"
typedef struct u_msg {
    	T_MSG               msgque;	                 /* Area for message queue */
PRI                 msgpri;	                 /* Message priority */
    UB  *usrmsg;    /* Area for message pointer */
} U_MSG;
void MbxSampleTaskA(W stacd,VP exinf);
void MbxSampleTaskB(W stacd,VP exinf);
static ID TaskID_A;
static ID TaskID_B;
static ID MbxID_S;
static ID MbxID_R;
ER MbxSample( void)
{
    ER ercd=E_OK;
    T_CTSK ctsk;
    T_CMBX cmbx;
    tm_putstring((UB*)"Mailbox sample create step 1-Create Task A;\n");
    ctsk.exinf = (VP)NULL;
    ctsk.tskatr = TA_HLNG|TA_RNG0;
    ctsk.task = MbxSampleTaskA;
    ctsk.itskpri = 20;
    ctsk.stksz = 512;
    TaskID_A = tk_cre_tsk(&ctsk);
    if(TaskID_A < E_OK) {
        ercd=TaskID_A;
        tm_putstring((UB*)"Task A can't creat;\n");
        PutErcd(ercd);
        return ercd;
    }
    
    tm_putstring((UB*)"Mailbox sample create step 2-Create Task B;\n");
    ctsk.exinf = (VP)NULL;
    ctsk.tskatr = TA_HLNG|TA_RNG0;
    ctsk.task = MbxSampleTaskB;
    ctsk.itskpri = 24;
    ctsk.stksz = 512;
    TaskID_B = tk_cre_tsk(&ctsk);
    if(TaskID_B < E_OK) {
        ercd=TaskID_B;
        tm_putstring((UB*)"Task B can't creat;\n");
        PutErcd(ercd);
        return ercd;
    }
    
    tm_putstring((UB*)"Mailbox sample create step 3-Create a send mailbox;\n");
    cmbx.exinf = (VP)NULL;
    cmbx.mbxatr = TA_TPRI|TA_MPRI;
    MbxID_S = tk_cre_mbx(&cmbx);
    if(MbxID_S < E_OK){
        ercd=MbxID_S;
        tm_putstring((UB*)"MailBox_Send can't creat;\n");
        PutErcd(ercd);
        return ercd;
    }
    tm_putstring((UB*)"Mailbox sample create step 4-Create a return mailbox;\n");
    cmbx.exinf = (VP)NULL;
    cmbx.mbxatr = TA_TPRI|TA_MPRI;
    MbxID_R = tk_cre_mbx(&cmbx);
    if(MbxID_R < E_OK){
      ercd=MbxID_R;
      tm_putstring((UB*)"MailBox_Recieve can't creat;\n");
      PutErcd(ercd);
      return ercd;
    }
    tm_putstring((UB*)"Mailbox sample create step 5-Start Task A;\n");
    ercd = tk_sta_tsk(TaskID_A,0);
    if (E_OK != ercd){
        tm_putstring((UB*)"start Task A failed;\n");
        PutErcd(ercd);
    }
    return TRUE;
} 
void MbxSampleTaskA(W stacd,VP exinf)
{
    B c;
    ER ercd;
    U_MSG *pk_rcvmsg,*pk_rcvmsg1;
    U_MSG sndmsg,sndmsg1;
    tm_putstring((UB*)"Mailbox sample create step 6-Start Task B;\n\n");
    ercd = tk_sta_tsk(TaskID_B,0);
    if (E_OK != ercd){
        tm_putstring((UB*)"Task B is starting failed;\n");
        PutErcd(ercd);
    }
    for(;;){
        tm_putstring((UB*)"Task A is running,Input Command(e=exit):\n");
        c = tm_getchar(0);
        if('e' == c) {
            break;
        }
sndmsg.msgpri = 10;
        sndmsg.usrmsg = "1-2-3,Please Starting up....\n";
        tm_putstring((UB*)"Task A send the first message to Task B:");
        tm_putstring((UB*)sndmsg.usrmsg);
        ercd = tk_snd_mbx(MbxID_S,(T_MSG*)&sndmsg);
        if(E_OK == ercd){
            tm_putstring((UB*)"Task A sent a message successfully;\n");
        }else{
            tm_putstring((UB*)"Task A can't send a message;\n");
            PutErcd(ercd);
        }
sndmsg1.msgpri = 9;
sndmsg1.usrmsg = "ÄáÂêËÙ¶È ÔËÐÐ....\n";
        tm_putstring((UB*)"Task A send the second message to Task B:");
        tm_putstring((UB*)sndmsg1.usrmsg);
        ercd = tk_snd_mbx(MbxID_S,(T_MSG*)&sndmsg1);
        if(E_OK == ercd){
            tm_putstring((UB*)"Task A sent a message successfully;\n");
        }else{
            tm_putstring((UB*)"Task A can't send a message;\n");
            PutErcd(ercd);
        }
        tm_putstring((UB*)"Task A is waiting Task B return message;\n\n");
	tk_slp_tsk ( -1 ) ;
        ercd = tk_rcv_mbx(MbxID_R,(T_MSG**)&pk_rcvmsg,-1);
ercd = tk_rcv_mbx(MbxID_R,(T_MSG**)&pk_rcvmsg1,-1);
        if(E_OK == ercd){
            tm_putstring((UB*)"Task A have received return message: ");
            tm_putstring((UB*)pk_rcvmsg->usrmsg);
tm_putstring((UB*)"Task A have received return message: ");
            tm_putstring((UB*)pk_rcvmsg1->usrmsg);
        }else{
            tm_putstring((UB*)"Task A can't receive return message: \n");
            PutErcd(ercd);
        }
    }
    tm_putstring((UB*)"Task A will delete mailbox;\n");
    tk_del_mbx(MbxID_S);
    tk_del_mbx(MbxID_R);
    tm_putstring((UB*)"Task A will terminate&delete task B;\n");
    tk_ter_tsk(TaskID_B);
    tk_del_tsk(TaskID_B);
    tm_putstring((UB*)"Task A will terminate&delete self;\n");
    tk_exd_tsk();
}
void MbxSampleTaskB(W stacd,VP exinf)
{
    ER ercd;
    U_MSG *pk_rcvmsg,*pk_rcvmsg1;
    U_MSG sndmsg,sndmsg1;
    for(;;){
        tm_putstring((UB*)"Task B is waiting a message;\n");
        ercd = tk_rcv_mbx(MbxID_S,(T_MSG**)&pk_rcvmsg,-1);
        if(E_OK == ercd){
            tm_putstring((UB*)"Task B have received the first message: ");
            tm_putstring((UB*)pk_rcvmsg->usrmsg);
        }else{
            tm_putstring((UB*)"Task B can't receive a message: ");
            PutErcd(ercd);
        }
ercd = tk_rcv_mbx(MbxID_S,(T_MSG**)&pk_rcvmsg1,-1);
        if(E_OK == ercd){
            tm_putstring((UB*)"Task B have received the second message: ");
            tm_putstring((UB*)pk_rcvmsg1->usrmsg);
        }else{
            tm_putstring((UB*)"Task B can't receive a message: ");
            PutErcd(ercd);
        }
sndmsg.msgpri = 10;
        sndmsg.usrmsg = "I have got up...\n";
        tm_putstring((UB*)"Task B return a message to Task A:");
        tm_putstring((UB*)sndmsg.usrmsg);
        tm_putstring((UB*)"\n");
        ercd = tk_snd_mbx(MbxID_R,(T_MSG*)&sndmsg);
        if(E_OK != ercd){
            tm_putstring((UB*)"Task B can't return a message;\n");
            PutErcd(ercd);
        }
sndmsg.msgpri = 9;
sndmsg1.usrmsg = "ÒѾÔÚÔËÐÐÁË...\n";
        tm_putstring((UB*)"Task B return a message to Task A:");
        tm_putstring((UB*)sndmsg1.usrmsg);
        tm_putstring((UB*)"\n");
        ercd = tk_snd_mbx(MbxID_R,(T_MSG*)&sndmsg1);
        if(E_OK != ercd){
            tm_putstring((UB*)"Task B can't return a message;\n");
            PutErcd(ercd);
        }
	tk_wup_tsk (TaskID_A) ;
    }
} 
如果接收邮箱参数改为cmbx.mbxatr = TA_TPRI|TA_MFIFO;就能正常了,不过A无法接收优先级类型的消息了。
	 
  
难道是优先级高的任务不能够从低优先级任务获取优先级类型的信息?百思不得其解,求大拿指点。
-----------------------------------------------------我是华丽的解答线---------------------------------------------------------------------
就在我决定关机的一瞬间,我发现问题所在鸟。
任务B第二条消息的优先级sndmsg.msgpri = 9;和第一条消息的参数一样,手欠啊,果断修改之。
世界清静了:
	
要小心啊,就少输入个1,一直折腾到现在。
实验四思考题
	
	1) 如果把发送消息和反馈消息放在同一个邮箱中,如何实现?如果不能实现会出现什么样的状况?
不想做理论分析,直接修改代码做实验。
直接注释掉接收信箱的创建代码,发送和接受都使用MbxID_S。
	 
 
	
	
 
原来问题里面的状况是指,只有一个A任务在不断的循环,根本无法进入到任务B的循环中。
题目要求用一个邮箱完成收发,果断想到事件标志位,果断修改代码。
	
 
	 
 
创建事件标志,分别设置A和B的标志操作,注释掉接收邮箱,仅用send邮箱完成massage的接受和发送任务,run......
	 
 
原来一个邮箱就ok啦。
	
困,先码到这,TBC......
回复
| 有奖活动 | |
|---|---|
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
| 送您一块开发板,2025年“我要开发板活动”又开始了! | |

 
					
				 
			
			
			
						
			 
					
				 
 
					
				 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

