zoukankan      html  css  js  c++  java
  • (uC/OS-II学习笔记)关于共享资源与信号量

    uC/os-ii中任务间相互通信的媒介叫做事件。

    关于OS_EVENT数据结构

    #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
        typedef struct os_event
        {
            INT8U    OSEventType;                    /* Type of event control block (see OS_EVENT_TYPE_xxxx)    */
            void    *OSEventPtr;                     /* Pointer to message or queue structure                   */
            INT16U   OSEventCnt;                     /* Semaphore Count (not used if other EVENT type)          */
            OS_PRIO  OSEventGrp;                     /* Group corresponding to tasks waiting for event to occur */
            OS_PRIO  OSEventTbl[OS_EVENT_TBL_SIZE];  /* List of tasks waiting for event to occur                */
    
    #if OS_EVENT_NAME_EN > 0u
            INT8U   *OSEventName;
    #endif
        } OS_EVENT;
    #endif
    OSEventType:事件类型(信号量、互斥信号量、邮箱、消息列队)
    OSEventCnt:计数器
    OSEventPtr:指向一个消息
    OSEventGrp与OSEventTbl[OS_EVENT_TBL_SIZE]:等待事件任务(类似于OSRdyTbl[]和OSRdyGrp)

    事件块实质是一个链表

    不同的任务如果使用共享资源,可能会出错。信号量类似于共享资源访问的一个标志。
    比如……我们把串口终端当做一个资源。
    TASK_1与TASK_2(TASK1优先级高于TASK_2)

    OS_EVENT MyFirstSem;
    char * CommonzSoure = "";
    
    void Task_1(void *pdata)
    {
        U32 i;
        
    #if OS_CRITICAL_METHOD == 3   //关中断的方法为3
        OS_CPU_SR cpu_sr;
    #endif
        
        OS_ENTER_CRITICAL();
        OS_CPU_SysTickInit(100000000/OS_TICKS_PER_SEC);
        OS_EXIT_CRITICAL();
        
        OSStatInit();   //统计任务 优先级最低
           
        MyFirstSem = *(OSSemCreate(1));
        
        //PIT0_Init(50000000);
        UART4_Init(115200);
        init_LED();
        
        pdata = pdata;                                
    
        
        
        while(1)
        {
            CommonzSoure = "TASK1 Using Common source ";
            
            for(i=0;CommonzSoure[i];i++)
                Uart4_SendByte(CommonzSoure[i]);
            
            OSTimeDly(1);       
        }
        
    }
    
    void Task_2(void *pdata)
    {
        U32 i;
        pdata = pdata;                                
    
        while(1)
        {
            CommonzSoure = "TASK2 Using Common source ";
            for(i=0;CommonzSoure[i];i++)
                Uart4_SendByte(CommonzSoure[i]);  
           
        }
      
    }

    任务1发送数据“TASK1 Using Common source”

    任务2发送数据“TASK2 Using Common source”

    任务切换的时候 数据发送会出错。(比如我们把串口终端当做一个实体的打印机)

    如果加入信号量(标记共享资源)

    OS_EVENT MyFirstSem;
    char * CommonzSoure = "";
    
    void Task_1(void *pdata)
    {
        U32 i;
        U8 err;
        
    #if OS_CRITICAL_METHOD == 3   //关中断的方法为3
        OS_CPU_SR cpu_sr;
    #endif
        
        OS_ENTER_CRITICAL();
        OS_CPU_SysTickInit(100000000/OS_TICKS_PER_SEC);
        OS_EXIT_CRITICAL();
        
        OSStatInit();   //统计任务 优先级最低
           
        MyFirstSem = *(OSSemCreate(1));
        
        //PIT0_Init(50000000);
        UART4_Init(115200);
        init_LED();
        
        pdata = pdata;                                
    
        
        
        while(1)
        {
    
            OSSemPend(&MyFirstSem,0,&err);
            CommonzSoure = "TASK1 Using Common source ";
                
            for(i=0;CommonzSoure[i];i++)
                Uart4_SendByte(CommonzSoure[i]);
            OSSemPost(&MyFirstSem);
            
            OSTimeDly(1);       
        }
        
    }
    
    void Task_2(void *pdata)
    {
        U32 i;
        U8 err;    
        pdata = pdata;                                
    
        while(1)
        {
            OSSemPend(&MyFirstSem,0,&err);
    
             
            CommonzSoure = "TASK2 Using Common source ";
            for(i=0;CommonzSoure[i];i++)
                Uart4_SendByte(CommonzSoure[i]); 
            OSSemPost(&MyFirstSem);
            
           
        }
      
    }

    OSSemAccept()可以无等待请求一个信号量。

    该函数只简单返回OSEventCnt的值,并在OSEventCnt值为真的时候做OSEventCnt--;

    调用OSSemAccept()函数,……不过目测资源都被TASK_2独占了。→_→

     同样,信号量也可以用于限制某个资源的任务个数。

    关于优先级反转与互斥信号量。

    信号量的使用可能会导致优先级反转。

    比如……

    由于任务C(低)得到信号量,任务A等待。任务B的优先级高于任务C,故任务B先运行。直到任务B,C运行完,任务C释放信号量,优先级最高的任务A才得到CPU资源。

    防止优先级反转的方法,在任务C得到信号量时把任务C的优先级升高,结束后再恢复。

    uC/OS-II,互斥信号量机制可以防止优先级反转。

    由于uC/OS-II不支持相同优先级,互斥信号量机制,可以使某个人物得到信号量时,优先级提到共享相同资源任务最高。

    OSMutexCreate(INT8U prio,INT8U *error)

    创建互斥信号量。

    uC/OS-II互斥信号量支持六种操作:创建、删除、等待、释放、无条件等待获取互斥信号量、获取互斥信号量当前状态。

  • 相关阅读:
    Maven插件系列之spring-boot-maven-plugin
    Java中getResourceAsStream的用法
    【redis】【linux】-bash: redis-cli: 未找到命令
    【bat】杀死指定端口
    【bat】查看端口占用情况
    【java】【springboot】nohup: 无法运行命令'java': 没有那个文件或目录
    【springboot】启动指定内存大小
    【java】【spring】源码分析,@AliasFor互为别名
    【idea】设置安装插件位置
    【记录】【springboot】java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal解决
  • 原文地址:https://www.cnblogs.com/hebaichuanyeah/p/3244962.html
Copyright © 2011-2022 走看看