UCOSIII interrupt and time management

Publisher:SerendipityLoveLatest update time:2019-04-25 Source: eefocusKeywords:UCOSIII Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Interrupt service function


1. Interrupt: The process of terminating the current task in response to the request of an internal or external asynchronous event and processing the task required by the asynchronous event is called interruption.


      Learn how to write interrupt service functions under UCOSIII!


If you use UCOIII, you will first perform conditional compilation, then execute the interrupt service routine, and finally exit the UCOIII interrupt. The interrupt function is as follows:


void USART1_IRQHandler(void) //Serial port 1 interrupt service routine

{

       u8 Res;

 

#if SYSTEM_SUPPORT_OS //Use UCOS operating system

       OSIntEnter();   

#endif

 

       if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //Receive interrupt (the received data must end with 0x0d 0x0a)

       {

              Res =USART_ReceiveData(USART1);//(USART1->DR); //Read the received data

      

              if((USART_RX_STA&0x8000)==0)//receiving is not completed

              {

                     if(USART_RX_STA&0x4000) //Received 0x0d

                     {

                            if(Res!=0x0a)USART_RX_STA=0; //Receive error, restart

                            else USART_RX_STA|=0x8000; //Receiving completed

                     }

                     else //Has not received 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; //Receive data error, restart receiving         

                            }            

                     }

              }            

  }

 

 #if SYSTEM_SUPPORT_OS 

       OSIntExit(); //Exit interrupt

 #endif

}

Entering and exiting the interrupt service function

After entering the interrupt service function, use the function OSIntEnter()


void OSIntEnter (void)

{

      if (OSRunning != OS_STATE_OS_RUNNING) //Judge whether UCOSIII is running

      {

              return

      }

      if (OSIntNestingCtr >= (OS_NESTING_CTR)250u)//Judge the number of interrupt nesting

      {

            return;

      }

     OSIntNestingCtr++; //Record interrupt nesting times. UCOSIII supports up to 250 levels of interrupt nesting.

}

When exiting the interrupt service function, call the function OSIntExit();


UCOSIII critical section code protection

Critical sections are also called critical regions, which are sections of code that must run completely and continuously and cannot be interrupted. When accessing these critical sections, they need to be protected.


Two different protection methods:


①When the macro OS_CFG_ISR_POST_DEFERRED_EN is 0, UCOSIII uses the method of disabling interrupts to protect the critical section code. When it is set to 1, it will use the method of locking the scheduler to protect the critical section code.


②UCOSIII defines a macro for entering the critical section code: OS_CRITICAL_ENTER(), and defines two macros for exiting the critical section code: OS_CRITICAL_EXIT and OS_CRITICAL_EXIT_NO_SCHED().


For example, in the main function, when creating the start function, it is considered uninterruptible, so it is protected and then unprotected after creation:


int main(void)

{

       OS_ERR err; //Error value: all are macro definitions. Find the meaning of the returned error value according to the corresponding value.

       CPU_SR_ALLOC();

      

       delay_init(168); //Clock initialization

       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Interrupt group configuration

       uart_init(115200); //Serial port initialization

       LED_Init(); //LED initialization

 

       OSInit(&err); //Initialize UCOSIII

       OS_CRITICAL_ENTER(); //Enter the critical section

       //Create the start task

       OSTaskCreate((OS_TCB * )&StartTaskTCB, //Task control block

                             (CPU_CHAR * )"start task", //task name

                 (OS_TASK_PTR )start_task, //task function

                 (void *)0, //Parameters passed to the task function

                 (OS_PRIO )START_TASK_PRIO, //Task priority

                 (CPU_STK * )&START_TASK_STK[0], //task stack base address

                 (CPU_STK_SIZE)START_STK_SIZE/10, //Task stack depth limit

                 (CPU_STK_SIZE)START_STK_SIZE, //Task stack size

                 (OS_MSG_QTY) 0, //The maximum number of messages that the task internal message queue can receive. When it is 0, it is forbidden to receive messages.

                 (OS_TICK) 0, //When the time slice rotation is enabled, the time slice length is 0, which is the default length.

                 (void *) 0, // user-supplemented storage area

                 (OS_OPT )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //Task options

                 (OS_ERR * )&err); //Store the return value of the function when an error occurs

       OS_CRITICAL_EXIT(); //Exit the critical section

       OSStart(&err); //Start UCOSIII

       while(1);

}

UCOSIII Time Management

Task Delay

 The task in UCOSIII is an infinite loop and a preemptive kernel. In order to prevent high-priority tasks from monopolizing the CPU, other lower-priority tasks can be given the opportunity to obtain CPU usage rights. All tasks except the idle task in UCOSIII must call the delay function provided by the system at the appropriate location to pause the current task for a period of time and perform a task switch.


There are two delay functions, OSTimeDly() and OSTimeDlyHMSM().


   The OSTimeDly() function has three working modes: relative mode, periodic mode and absolute mode.


void OSTimeDly (OS_TICK dly, //Time slice number

                 OS_OPT opt, //Working mode

                 OS_ERR *p_err) // Error code

   The OSTimeDlyHMSM() function works only in relative mode.


void OSTimeDlyHMSM (CPU_INT16U hours,//hour

                     CPU_INT16U minutes, // minutes

                     CPU_INT16U seconds, // seconds

                     CPU_INT32U milli, // subtle

                     OS_OPT opt, //Working mode, different working modes have different time ranges

                     OS_ERR *p_err)

-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------


Cancel the delay of a task

The delayed task can enter the ready state by calling the function OSTimeDlyResume() in other tasks to cancel the delay. This function will eventually trigger a task scheduling.


Getting and setting the system time

UCOSIII defines a global variable OSTickCtr of type CPU_INT32U to record the number of system clock beats. It is initialized to 0 when OSInit() is called. After that, OSTickCtr increases by 1 for each clock beat.


 OSTimeSet() allows users to change the value of the current clock tick counter, use with caution! ! ! !


OSTimeGet() is used to obtain the value of the migration clock beat counter.

Keywords:UCOSIII Reference address:UCOSIII interrupt and time management

Previous article:Communication between UCOSIII tasks
Next article:UCOSIII's five system tasks and hook function writing

Recommended ReadingLatest update time:2024-11-23 06:46

C51 interrupts and using interrupt priorities
The basic structure of the 8051 series MCU includes: 32 I/O ports (4 groups of 8-bit ports); two 16-bit timer counters; full-duplex serial communication; 6 interrupt sources (2 external interrupts, 2 timer/counter interrupts, 1 serial port input/output interrupt), two-level interrupt priority; 128 bytes of built-in RA
[Microcontroller]
Usage of interrupt and using in C51
void INT0()interrupt 0 using 1 {.... ..... } interrupt 0 indicates external interrupt 0; interrupt 1 indicates timer interrupt 0; interrupt 2 indicates external interrupt 1; interrupt 3 indicates timer interrupt 1; interrupt 4 indicates a serial port interrupt; using 0 is the 0th group of registers; using 1 is the fi
[Microcontroller]
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号