• uCOSii系统的中断管理


    uCOSii系统的中断管理

    1、在使用uCOSii系统时,中断服务程序需要调用两个函数OSIntEnter()和OSIntExit()。

    OSIntEnter() 进入中断时,OSIntNesting来统计中断嵌套次数,告知uCOSii系统,当前中断服务程序正在执行;

    OSIntExit()退出中断时,OSIntNesting来统计中断嵌套次数,告知uCOSii系统,当前的中断已经处理完成;
    注意:切记上述两个函数必须成对出现中断服务程序中,这种用法和FreeRTOS不同。

    2、OSIntEnter()函数

    函数功能:在进入中断服务函数时,需要OSIntNesting来统计中断嵌套次数

    void OSIntEnter (void)

    {

    if (OSRunning == OS_TRUE)

    {

            if (OSIntNesting < 255u)

            {

                OSIntNesting++;/*中断嵌套次数加1*/

            }

        }

    }

    3、OSIntExit()函数

    函数功能:在退出中断服务函数时,需要用OSIntNesting来统计中断嵌套次数

    void  OSIntExit (void)

    {

    #if OS_CRITICAL_METHOD == 3u

        OS_CPU_SR  cpu_sr = 0u;

    #endif

    if (OSRunning == OS_TRUE)

    {

            OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量

            if (OSIntNesting > 0u)

            {/*防止OSIntNesting在做减法时由0x00变为0xFF*/

                OSIntNesting--;/*中断嵌套次数减1*/

            }

            if (OSIntNesting == 0u)

            {/*中断嵌套次数OSIntNesting =0*/

                if (OSLockNesting == 0u)

                {/*多任务上锁嵌套OSLockNesting=0表示没有上锁 */

                    OS_SchedNew();

       //准备好的任务,找出优先级最高的任务的优先级,赋值给OSPrioHighRdy

                    OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

       //根据OSPrioHighRdy,读取最高优先级任务控制块的指针” ,保存到OSTCBHighRdy

                    if (OSPrioHighRdy != OSPrioCur)

                    {

       //OSPrioHighRdy为最高优先级任务的优先级

       //OSPrioCur为当前任务的优先级

       //如果当前任务的优先级最高优先级任务的优先级不等,则切换任务

       //在中断服务程序中,若出现更高优先级任务处于准备状态时,则执行任务切换功能

    #if OS_TASK_PROFILE_EN > 0u

                        OSTCBHighRdy->OSTCBCtxSwCtr++;//切换任务次数计数器加1

    #endif

                        OSCtxSwCtr++;//上下文切换次数计数器加1

                        OSIntCtxSw();

          /*OSIntCtxSw()表示在中断服务程序中执行任务切换,退出中断便执行新任务*/

                    }

                }

            }

            OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)

        }

    }

    4uCOSii中断引用举例

    #include "Timer2_Task.h"

    #include "includes.h"

    #include "LED.h"

    u16 MilliSecond;//毫秒计数器

    void TIM2_Interrupt_Initializtion(u16 arr,u16 psc);

    //通用定时器2中断初始化

    //这里时钟选择为APB12倍,而APB136M

    //arr:自动重装值。

    //psc:时钟预分频数

    //这里使用的是定时器2!

    //TIM2_Interrupt_Initializtion(1000,36);

    //arr=1000,psc=36,则为0.5ms,误差为0.5us;

    //TIM2_Interrupt_Initializtion(2000,36);

    //arr=2000,psc=36,则为1ms,误差为0.5us;

    //TIM2_Interrupt_Initializtion(4000,36);

    //arr=4000,psc=36,则为2ms,误差为0.5us;

    void TIM2_Interrupt_Initializtion(u16 arr,u16 psc)

    {

             TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

             NVIC_InitTypeDef NVIC_InitStructure;

             RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

        //使能定时器TIM2APB1外设时钟

            

             //定时器TIM2初始化

             TIM_TimeBaseStructure.TIM_Period = arr-1;

        //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         

             TIM_TimeBaseStructure.TIM_Prescaler =psc-1;

        //设置用来作为TIMx时钟频率除数的预分频值

             TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

        //设置时钟分割:TDTS = Tck_tim

             //计算公式:arr*psc/72000000/1,arr=1000,psc=72,则为1ms,误差为1us;

             TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

        //TIM向上计数模式

             TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

        //根据指定的参数初始化TIMx的时间基数单位

            

            TIM_SetCounter(TIM2,0);                   //设置TIM2的计数器值为0;

        TIM_ClearFlag(TIM2, TIM_FLAG_Update);  //清除TIM2溢出的待处理标志位

             TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIM2中断的待处理位

             TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //允许TIM2溢出产生中断

             //中断优先级NVIC设置

             //NVIC_PriorityGroup_4设置NVIC中断分组4:表示抢占优先级为4,取值为0~15,没有响应优先级,取值为0

      //NVIC_PriorityGroup_3设置NVIC中断分组3:表示抢占优先级为3,取值为0~7,响应优先级只有1,取值为0~1

             //NVIC_PriorityGroup_2设置NVIC中断分组3:表示抢占优先级为2,取值为0~3,响应优先级只有2,取值为0~3

             //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4

             NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断

             NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11; 

        //设置抢占优先级为11

             NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //设置响应优先级为0

             NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ通道被使能

             NVIC_Init(&NVIC_InitStructure);

        //根据NVIC_InitStruct中指定的参数初始化NVIC嵌套向量中断控制寄存器

             TIM_Cmd(TIM2, ENABLE);//使能TIM2外设

      MilliSecond=0;//毫秒计数器

    }

    //函数功能:TIM21ms中断一次

    void TIM2_IRQHandler()

    {

             OSIntEnter();//在进入中断服务函数时,需要用OSIntNesting来统计中断嵌套次数

             if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) //TIM2计数器溢出产生中断

             {

               MilliSecond++;//毫秒计数器加1

               if(MilliSecond>=1000)//TIM21ms中断一次,1000表示1

               {

                         MilliSecond=0;

                         LED0=!LED0;

               }

               TIM_ClearITPendingBit(TIM2,TIM_IT_Update);

         //清除TIM2计数器的溢出中断标志;

             }

             OSIntExit();//在退出中断服务函数时,需要用OSIntNesting来统计中断嵌套次数

    }

    5uCOSii系统不是免费的

        uCOSii是开源的,但不是免费的。如果你真想要用免费的系统,还是选择FreeRTOS吧。从技术角度或者从商业角度,同FreeRTOS相比,uCOSii没有任何优势。FreeRTOS是真正免费的系统。

     

  • 相关阅读:
    Pandas数据分析一览-短期内快速学会数据分析指南(文末送书)
    【C语言】文件操作
    上市公司信息透明度数据(1991-2019年)包含stata源代码和数据
    Lodash初识
    Docker部署MySQL双主双从,主主互备
    Android App内存泄漏原理、检测及修改方案
    TCP协议的秘密武器:流量控制与拥塞控制
    预处理详解
    Java_位运算符简述
    竞赛 深度学习图像修复算法 - opencv python 机器视觉
  • 原文地址:https://blog.csdn.net/weixin_42550185/article/details/131082896