zoukankan      html  css  js  c++  java
  • ucos(七)事件标志组

    一、概述

    前面讲述了UCOSIII的信号量、互斥信号量,它们都可以完成任务的同步。但是有时候一个任务可能需要和多个事件同步,这个时候就需要使用事件标志组。事件标志组与任务之间有两种同步机制:
    • “或”同步:等待多个事件时,任何一个事件发生 ,任务都被同步,这个就称为“或”同步;
    • “与”同步:当所有的事件都发生时任务才被同步,这种同步机制被称为“与”同步。
     
    事件标志组是专门管理标志位,一个事件标志组可以管理32个标志位
    在前后台系统,经常会用到标志位,查询标志位是否置位,有明显的缺点,CPU得不到休息,会一直工作查询,增加CPU的功耗。
    void main(void)
    {
         while(1)
         {
              if(g_iwdg_reset)
              {
    
              }
    
              if(g_wwdg_reset)
              {
                     g_wwdg_reset=0;
              }
    
              if(g_usart1_event)
              {
    
              }
              
              if(g_usart3_event)
              {
    
              } 
              
              if(g_rtc_wakeup_event)
              {
    
              } 
              
              if(g_rtc_alarm_event)
              {
    
              }         
                                                                
         }
    
    }
    

    1.创建事件标志组

    void OSFlagCreate (OS_FLAG_GRP *p_grp, CPU_CHAR *p_name, OS_FLAGS flags, OS_ERR *p_err)
    参数:
    p_grp:事件标志组对象
    p_name:事件标志组的名字
    flags:事件标志组里所有标志位的初值,默认写0
    p_err:返回错误码,没有错误的就返回OS_ERR_NONE

    2.等待事件标志组

    OS_FLAGS OSFlagPend (OS_FLAG_GRP *p_grp, OS_FLAGS flags, OS_TICK timeout, OS_OPT opt, CPU_TS *p_ts, OS_ERR *p_err)

    参数:

    p_grp:事件标志组对象
    flags:要等待哪些标志位;0x01(0001'b),则等待bit0;0x05(0101'b),则等待bit0和bit2;0x83,则等待bit0、bit1、bit7。
    timeout:超时时间,默认写0,一直等待
    opt:默认写以下格式
    OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME+OS_OPT_PEND_BLOCKING
    OS_OPT_PEND_FLAG_SET_ANY: 等待任意一个标志位置位
    OS_OPT_PEND_FLAG_CONSUME: 等待任意一个标志位成功后,就自动将其清零
    OS_OPT_PEND_BLOCKING: 阻塞等待
    OS_OPT_PEND_FLAG_SET_ALL: 等待所有标志位置位,才能跳出阻塞等待
    p_ts: 用于记录等待事件花了多长时间,默认写NULL,不记录。
    p_err: 返回错误码,没有错误的就返回OS_ERR_NONE.
    返回值:
      返回等待成功的标志位。

    3.设置事件标志组

    OS_FLAGS OSFlagPost (OS_FLAG_GRP *p_grp, OS_FLAGS flags, OS_OPT opt, OS_ERR *p_err)
    参数:
    p_grp:事件标志组对象
    flags: 结合opt参数一起使用。设置/清零哪些标志位,0x01,则对应bit0;0x05,则对应bit0和bit2;0x83,则对应bit0、bit1、bit7。
    opt: OS_OPT_POST_FLAG_SET,对应的bit置位   ,OS_OPT_POST_FLAG_CLR,对应的bit清零.
    p_err: 返回错误码,没有错误的就返回OS_ERR_NONE。
     

    二、实例

    按键触发中断,在中断中设置中断标志位
    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "includes.h"
    #include "exti.h"
    
    //任务1控制块
    OS_TCB Task1_TCB;
    
    void task1(void *parg);
    
    CPU_STK task1_stk[128];			//任务1的任务堆栈,大小为128字,也就是512字节
    
    
    OS_FLAG_GRP g_flag_grp;   //事件标志组的对象
    
    //主函数
    int main(void)
    {
    	OS_ERR err;
    
    	systick_init();  													//时钟初始化
    	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);						//中断分组配置
    	
    	usart_init(9600);  				 									//串口初始化
    	
    	LED_Init();         												//LED初始化	
           Exti_Init();
    
    	//OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器
    	OSInit(&err);
    
    
    	//创建任务1
    	OSTaskCreate(	(OS_TCB *)&Task1_TCB,									//任务控制块,等同于线程id
    					(CPU_CHAR *)"Task1",									//任务的名字,名字可以自定义的
    					(OS_TASK_PTR)task1,										//任务函数,等同于线程函数
    					(void *)0,												//传递参数,等同于线程的传递参数
    					(OS_PRIO)6,											 	//任务的优先级6		
    					(CPU_STK *)task1_stk,									//任务堆栈基地址
    					(CPU_STK_SIZE)128/10,									//任务堆栈深度限位,用到这个位置,任务不能再继续使用
    					(CPU_STK_SIZE)128,										//任务堆栈大小			
    					(OS_MSG_QTY)0,											//禁止任务消息队列
    					(OS_TICK)0,												//默认时间片长度																
    					(void  *)0,												//不需要补充用户存储区
    					(OS_OPT)OS_OPT_TASK_NONE,								//没有任何选项
    					&err													//返回的错误码
    				);				
    	if(err!=OS_ERR_NONE)
    	{
    		printf("task 1 create fail
    ");
    		
    		while(1);
    	
    	}
    	
    	
    	//创建事件标志组
    	OSFlagCreate(&g_flag_grp,"g_flag_grp",0,&err);
    	
    	//启动OS,进行任务调度
    	OSStart(&err);
    								
    	printf(".......
    ");
    					
    	while(1);
    	
    }
    
    
    
    void task1(void *parg)
    {
    	uint32_t t=0;
    	OS_ERR err;
    	
    	OS_FLAGS flag = 0;
    	printf("task1 is create ok
    ");
    
    	while(1)
    	{
    		//等待事件标志组
    		//0x01|0x02  就是等待bit0和bit1
    		//0:不做超时等待
    		//OS_OPT_PEND_FLAG_SET_ANY  等待其中一个标志位
    		//OS_OPT_PEND_FLAG_CONSUME  等待对应的时间成功后,将对应的时间标志位清零
    		//OS_OPT_PEND_BLOCKING  阻塞形式等待信号量,若等不了信号量,则让出CPU使用权给其他任务
    		//不需要时间戳(时间标记):用于记录等待信号量花了多长时间,默认写NULL,不记录
    		
    		//或同步
    		//flag = OSFlagPend(&g_flag_grp,0x01|0x02,0,OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME+OS_OPT_PEND_BLOCKING,NULL,&err);
    		//与同步
    		flag = OSFlagPend(&g_flag_grp,0x01|0x02,0,OS_OPT_PEND_FLAG_SET_ALL + OS_OPT_PEND_FLAG_CONSUME+OS_OPT_PEND_BLOCKING,NULL,&err);
    
    		if(flag & 0x01)
    		{
    			printf("bit0 set
    ");
    		}
    		if(flag & 0x02)
    		{
    			printf("bit1 set
    ");
    		}
    	}
    }
    
    
    //中断服务函数  在CORE里面的start_stm32f40_41xxx.s这个汇编里面找
    void EXTI0_IRQHandler(void)//PA0
    {
    	uint8_t b=0;
    	OS_ERR err;
    	//进入中断
    	OSIntEnter();
    	//判断确实进中断标志
    	//if(EXTI_GetITStatus(EXTI_Line9) !=RESET) //==SET
    	if((EXTI->PR & (0x1<<0)) !=0)
    	{
    		b=1;
    		//清楚中断标志位   往里面写1   记住一定要清空
    		//EXTI_ClearITPendingBit(EXTI_Line0);
    		EXTI->PR = (0x1<<0);
    	}		
    	//退出中断
    	OSIntExit(); 
    	if(b)
    	{
    		//设置事件标志组的bit0
    		OSFlagPost(&g_flag_grp,0x01,OS_OPT_POST_FLAG_SET,&err);
    	}
    	
    }
    
    //中断服务函数  在CORE里面的start_stm32f40_41xxx.s这个汇编里面找
    void EXTI2_IRQHandler(void)//PA0
    {
    	uint8_t b=0;
    	OS_ERR err;
    	//判断确实进中断标志
    	if(EXTI_GetITStatus(EXTI_Line2) !=RESET) //==SET
    	{
    		b=1;
    		//清楚中断标志位   往里面写1   记住一定要清空
    		EXTI_ClearITPendingBit(EXTI_Line2);	
    	}
    	if(b)
    	{
    		//设置事件标志组的bit1
    		OSFlagPost(&g_flag_grp,0x02,OS_OPT_POST_FLAG_SET,&err);
    	}	
    }
    

      

     

      

  • 相关阅读:
    扫描线与悬线
    随机搜索与模拟退火
    树的直径相关
    分数规划及斜率优化
    数学-剩余系
    后缀数据结构
    AC自动机和KMP
    生命游戏和随机数之间某种不可言说的秘密
    转移了
    BZOJ 1710: [Usaco2007 Open]Cheappal 廉价回文
  • 原文地址:https://www.cnblogs.com/yuanqiangfei/p/15229696.html
Copyright © 2011-2022 走看看