UCOSIII中断和时间管理

1.1、UCOSIII中断:

中断:应内部或外部异步事件的请求中止当前任务,而去处理异步事件所要求的任务的过程叫做中断。

如何在UCOSIII下编写中断服务函数!

void USART1_IRQHandler(void)
{
	OSIntEnter();
	// 中断服务程序
	OSIntExit();
}

串口中断服务函数:

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#ifdef SYSTEM_SUPPORT_OS	 	
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#ifdef SYSTEM_SUPPORT_OS	 
	OSIntExit();  											 
#endif

1.2、进入和退出中断服务函数:

进入中断服务函数以后使用函数 OSIntEnter()

void  OSIntEnter (void)
{
    if (OSRunning != OS_STATE_OS_RUNNING) {                 /* Is OS running?                                         */
        return;                                             /* No                                                     */
    }

    if (OSIntNestingCtr >= (OS_NESTING_CTR)250u) {          /* Have we nested past 250 levels?                        */
        return;                                             /* Yes                                                    */
    }

    OSIntNestingCtr++;                                      /* Increment ISR nesting level                            */
}

OSIntNestingCtr来记录中断嵌套次数,UCOSIII最多支持250级的中断嵌套。退出中断服务函数时要调用函数 OSIntExit()

void  OSIntExit (void)
{
    CPU_SR_ALLOC();



    if (OSRunning != OS_STATE_OS_RUNNING) {                 /* Has the OS started?                                    */
        return;                                             /* No                                                     */
    }

    CPU_INT_DIS();
    if (OSIntNestingCtr == (OS_NESTING_CTR)0) {             /* Prevent OSIntNestingCtr from wrapping                  */
        CPU_INT_EN();
        return;
    }
    OSIntNestingCtr--;
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* ISRs still nested?                                     */
        CPU_INT_EN();                                       /* Yes                                                    */
        return;
    }

    if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {        /* Scheduler still locked?                                */
        CPU_INT_EN();                                       /* Yes                                                    */
        return;
    }

    OSPrioHighRdy   = OS_PrioGetHighest();                  /* Find highest priority                                  */
    OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;     /* Get highest priority task ready-to-run                 */
    if (OSTCBHighRdyPtr == OSTCBCurPtr) {                   /* Current task still the highest priority?               */
        CPU_INT_EN();                                       /* Yes                                                    */
        return;
    }

#if OS_CFG_TASK_PROFILE_EN > 0u
    OSTCBHighRdyPtr->CtxSwCtr++;                            /* Inc. # of context switches for this new task           */
#endif
    OSTaskCtxSwCtr++;                                       /* Keep track of the total number of ctx switches         */

#if defined(OS_CFG_TLS_TBL_SIZE) && (OS_CFG_TLS_TBL_SIZE > 0u)
    OS_TLS_TaskSw();
#endif

    OSIntCtxSw();                                           /* Perform interrupt level ctx switch                     */
    CPU_INT_EN();
}

2、UCOSIII临界段代码保护

临界段代码也叫做临界区,是指那些必须完整连续运行,不可被打断的代码段。当访问这些临界段代码的时候需要对这些临界段代码的时候需要对这些临界段代码进行保护。

当宏 OS_CFG_ISR_POST_DEFERRED_EN为0时,UCOSIII使用中断的方式来保护临界段代码,当设置为1的时候就会采用给调度器上锁的方式来保护临界段代码。

UCOSIII定义了一个进入临界段代码的宏:OS_CRITTICAL_ENTER(),定义了两个退出临界段代码的宏:OS_CRITICAL_EXITOS_CRITICAL_EXIT_NO_SCHED()


3、UCOSIII时间管理

3.1、任务延时:

UCOSIII中的任务是一个无限循环并且还是一个抢占式内核,为了使高优先级的任务不至于独占CPU,可以给其他优先级较低任务获取CPU使用权的机会,UCOSIII中除空闲任务外的所有任务必须在合适的位置调用系统提供的延时函数,让当前的任务暂停运行一段时间并进行一个任务切换。

延时函数有两种,OSTimeDly()OSTimeDlyHMSM()

  • OSTimeDly()函数有三种工作模式:相对模式,周期模式和绝对模式。

    void  OSTimeDly (OS_TICK   dly,
                     OS_OPT    opt,
                     OS_ERR   *p_err)
    
  • OSTimeDlyHMSM()函数仅在相对模式下工作。

    #if OS_CFG_TIME_DLY_HMSM_EN > 0u
    void  OSTimeDlyHMSM (CPU_INT16U   hours,
                         CPU_INT16U   minutes,
                         CPU_INT16U   seconds,
                         CPU_INT32U   milli,
                         OS_OPT       opt,
                         OS_ERR      *p_err)
    

3.2、取消任务的延时:

延时任务任务可通过在其他任务调度函数 OSTimeDlyResume() 取消延时而进入就绪状态,此函数最后会引发一次任务调度。

3.3、获取和设置系统时间:

UCOSIII定义了一个 CPU_INT32U类型的全局变量 OSTickCtr来记录系统时钟节拍数,在调用OSInit() 时被初始化为0,以后每发生1个时钟节拍,OSTickCtr加1。

  • OSTimeSet() 允许用户改变当前时钟节拍计数器的值,慎用!!!
  • OSTimeGet()用来获取动迁时钟节拍计数器的值。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值