ucos实时系统--不支持时间片轮训版本 SysTick 配置分析

来源:互联网 发布:华为抢购软件神器 编辑:程序博客网 时间:2024/06/06 19:34

目的:看看ucos中SysTick的中断优先级配置情况。

关于 SysTick  定时器的 说明参见我的另一个文章。--STM32F10XXXX---SysTick滴答定时器

在系统启动多任务后的第一个任务TaskStart中(即调用过OSStart()函数后),

先初始化BSP(Board Support Package)板级支持包:

  1. 设定RCC(复位和实时时钟控制)外设,对系统时钟源进行设置
  2. 初始化系统驱动程序;

然后调用OS_CPU_SysTickInit()完成对系统Tick的设定。

先上程序:

os_cpu_c.c中的相关宏定义

/***********************************************************************************************************                                          SYS TICK DEFINES**********************************************************************************************************/#define  OS_CPU_CM3_NVIC_ST_CTRL    (*((volatile INT32U *)0xE000E010))   /* SysTick Ctrl & Status Reg. */#define  OS_CPU_CM3_NVIC_ST_RELOAD  (*((volatile INT32U *)0xE000E014))   /* SysTick Reload  Value Reg. */#define  OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018))   /* SysTick Current Value Reg. */#define  OS_CPU_CM3_NVIC_ST_CAL     (*((volatile INT32U *)0xE000E01C))   /* SysTick Cal     Value Reg. *///SysTick校准值寄存器#define  OS_CPU_CM3_NVIC_ST_CTRL_COUNT                    0x00010000     /* Count flag.                */#define  OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC                  0x00000004     /* Clock Source.              */#define  OS_CPU_CM3_NVIC_ST_CTRL_INTEN                    0x00000002     /* Interrupt enable.          */#define  OS_CPU_CM3_NVIC_ST_CTRL_ENABLE                   0x00000001     /* Counter mode.              */


SysTick设置:

/***********************************************************************************************************                                          OS_CPU_SysTickInit()** Description: Initialize the SysTick.** Arguments  : none.** Note(s)    : 1) This function MUST be called after OSStart() & after processor initialization.**********************************************************************************************************/void  OS_CPU_SysTickInit (void){    INT32U  cnts;    //通过已经设置的RCC_ClocksTypeDef的HCLK_Frequency时钟频率 如:72M    cnts = OS_CPU_SysTickClkFreq() / OS_TICKS_PER_SEC; //<span style="font-family: Arial, Helvetica, sans-serif;">OS_TICKS_PER_SEC设置为1000</span>    OS_CPU_CM3_NVIC_ST_RELOAD = (cnts - 1); //得到的值写入 Systick 重装载数值寄存器                                                 /* Enable timer.                                      */    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;                                                 /* Enable timer interrupt.                            */    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;}

上边的SysTick外设的宏定义中的注释可能有错误:

OS_CPU_CM3_NVIC_ST_CTRL_INTEN  :SysTick一定是向下计数的模式,该位决定----当事件到来时,是否发出异常请求。

OS_CPU_CM3_NVIC_ST_CTRL_ENABLE:定时器使能。

OS_CPU_SysTickInit实现功能:

  • SysTick自动重装载值寄存器 填充;
  • SysTick控制状态寄存器设置:选择内核时钟(FCLK)、定时器使能、事件到达触发异常

SysTick异常处理程序:
/***********************************************************************************************************                                         OS_CPU_SysTickHandler()** Description: Handle the system tick (SysTick) interrupt, which is used to generate the uC/OS-II tick*              interrupt.** Arguments  : none.** Note(s)    : 1) This function MUST be placed on entry 15 of the Cortex-M3 vector table.**********************************************************************************************************/void  OS_CPU_SysTickHandler (void){    OS_CPU_SR  cpu_sr;    OS_ENTER_CRITICAL();                         /* Tell uC/OS-II that we are starting an ISR          */    OSIntNesting++;    OS_EXIT_CRITICAL();    OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */    OSIntExit();                                 /* Tell uC/OS-II that we are leaving the ISR          */}

先OSIntNesting++;Tell uC/OS-II我们正在开始一个ISR终端服务程序。
后OSTimeTick(); 目的是在时钟节拍到来时,检查每个任务的任务控制块中的.OSTCBDly-1后是否为0,如果是,那么表明这个任务刚才是挂起的状态,此时应改变为就绪态
最后是OSIntExit(); ---OS_SchedNew();调度发生

说说OSTimeTick(); 
任务状态图如下:

先弄几个宏定义
OS_EXT  BOOLEAN           OSRunning;                       /* Flag indicating that kernel is running   */
#if OS_TICK_STEP_EN > 0OS_EXT  INT8U             OSTickStepState;          /* Indicates the state of the tick step feature    */#endif
/***********************************************************************************************************                                   Values for OSTickStepState** Note(s): This feature is used by uC/OS-View.**********************************************************************************************************/#if OS_TICK_STEP_EN > 0#define  OS_TICK_STEP_DIS             0u    /* Stepping is disabled, tick runs as mormal               */#define  OS_TICK_STEP_WAIT            1u    /* Waiting for uC/OS-View to set OSTickStepState to _ONCE  */#define  OS_TICK_STEP_ONCE            2u    /* Process tick once and wait for next cmd from uC/OS-View */#endif
#define  OS_TASK_IDLE_PRIO  (OS_LOWEST_PRIO)            /* IDLE      task priority
/***********************************************************************************************************                              TASK STATUS (Bit definition for OSTCBStat)**********************************************************************************************************/#define  OS_STAT_RDY               0x00u    /* Ready to run                                            */#define  OS_STAT_SEM               0x01u    /* Pending on semaphore                                    */#define  OS_STAT_MBOX              0x02u    /* Pending on mailbox                                      */#define  OS_STAT_Q                 0x04u    /* Pending on queue                                        */#define  OS_STAT_SUSPEND           0x08u    /* Task is suspended                                       */#define  OS_STAT_MUTEX             0x10u    /* Pending on mutual exclusion semaphore                   */#define  OS_STAT_FLAG              0x20u    /* Pending on event flag group                             */#define  OS_STAT_MULTI             0x80u    /* Pending on multiple events                              */#define  OS_STAT_PEND_ANY         (OS_STAT_SEM | OS_STAT_MBOX | OS_STAT_Q | OS_STAT_MUTEX | OS_STAT_FLAG)
/***********************************************************************************************************                           TASK PEND STATUS (Status codes for OSTCBStatPend)**********************************************************************************************************/#define  OS_STAT_PEND_OK              0u    /* Pending status OK, not pending, or pending complete     */#define  OS_STAT_PEND_TO              1u    /* Pending timed out                                       */#define  OS_STAT_PEND_ABORT           2u    /* Pending aborted                                         */




OSTimeTick(); 
/***********************************************************************************************************                                         PROCESS SYSTEM TICK** Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known*              as a 'clock tick').  This function should be called by the ticker ISR but, can also be*              called by a high priority task.** Arguments  : none** Returns    : none**********************************************************************************************************/void  OSTimeTick (void){    OS_TCB    *ptcb;#if OS_TICK_STEP_EN > 0    BOOLEAN    step;#endif#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register     */    OS_CPU_SR  cpu_sr = 0;#endif#if OS_TIME_TICK_HOOK_EN > 0    OSTimeTickHook();                                      /* Call user definable hook                     */#endif#if OS_TIME_GET_SET_EN > 0    OS_ENTER_CRITICAL();                                   /* Update the 32-bit tick counter               */    OSTime++;    OS_EXIT_CRITICAL();#endif    if (OSRunning == OS_TRUE) {#if OS_TICK_STEP_EN > 0        switch (OSTickStepState) {                         /* Determine whether we need to process a tick  */            case OS_TICK_STEP_DIS:                         /* Yes, stepping is disabled                    */                 step = OS_TRUE;                 break;            case OS_TICK_STEP_WAIT:                        /* No,  waiting for uC/OS-View to set ...       */                 step = OS_FALSE;                          /*      .. OSTickStepState to OS_TICK_STEP_ONCE */                 break;            case OS_TICK_STEP_ONCE:                        /* Yes, process tick once and wait for next ... */                 step            = OS_TRUE;                /*      ... step command from uC/OS-View        */                 OSTickStepState = OS_TICK_STEP_WAIT;                 break;            default:                                       /* Invalid case, correct situation              */                 step            = OS_TRUE;                 OSTickStepState = OS_TICK_STEP_DIS;                 break;        }        if (step == OS_FALSE) {                            /* Return if waiting for step command           */            return;        }#endif        ptcb = OSTCBList;                                  /* Point at first TCB in TCB list               */        while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) {     /* Go through all TCBs in TCB list//遍历              */            OS_ENTER_CRITICAL();            if (ptcb->OSTCBDly != 0) {                     /* No, Delayed or waiting for event with TO     */                if (--ptcb->OSTCBDly == 0) {               /* Decrement nbr of ticks to end of delay       */                                                           /* Check for timeout                            */                    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {//不为就绪态,置成就绪态                        ptcb->OSTCBStat  &= ~(INT8U)OS_STAT_PEND_ANY;          /* Yes, Clear status flag  就绪态OS_STAT_RDY */                        ptcb->OSTCBStatPend = OS_STAT_PEND_TO;                 /* Indicate PEND timeout 挂起状态设置为挂起超时<span style="font-family: Arial, Helvetica, sans-serif;">OS_STAT_PEND_TO</span>   */                    } else {                        ptcb->OSTCBStatPend = OS_STAT_PEND_OK;//否则挂起状态OK                    }                    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?   任务暂停?    */                        OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready  不是暂停,将它就绪        */                        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;                    }                }            }            ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list                */            OS_EXIT_CRITICAL();        }    }}

OSIntExit();
---待续,,,,



0 0
原创粉丝点击