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是真正免费的系统。

 uCOSii系统的中断管理_第1张图片

你可能感兴趣的:(产品研发,uCOSii,实时操作系统,RTOS,中断嵌套,单片机)