Ucos-ii how to get the highest-priority task

Source: Internet
Author: User

Ucos_ii when a task switch is in progress, the highest priority task in the current ready queue is selected to run. So how did Ucos_ii find the Task with the highest priority?

Start with the following code snippet to analyze

#define Os_lowest_prio           63u/   * Defines the LOWEST priority, can be assigned ...         */static  void  os_schednew (void) {#if Os_lowest_prio <= 63u/* See if we support up to +                        tasks                   */    I nt8u   y;    Y             = osunmaptbl[osrdygrp];    Ospriohighrdy = (int8u) ((y << 3u) + osunmaptbl[osrdytbl[y]); #else                                            */  

Visible, Ospriohighrdy can be obtained by calculating osrdygrp,osunmaptbl and OSRDYTBL. So what is the meaning of these three parameters, explained below?

Pre-defined:

#if os_lowest_prio <= 63u#define  os_rdy_tbl_size   ((Os_lowest_prio)/8u + 1u)/* SIZE of Ready table                         */#if Os_lowest_prio <= 63utypedef  int8u    os_prio; #if os_lowest_prio <= 63u#define  os_rdy_tbl_size   ( (Os_lowest_prio)/8u + 1u)/* Size of Ready table                         */#if os_lowest_prio <= 63utypedef  int8u    Os_prio;

Osrdytbl

Os_ext  Os_prio           osrdytbl[os_rdy_tbl_size];       /* Table of tasks which is ready to run    */

The visible osrdytbl is an array of type int8u of length 8, where each bit represents the priority 0-63.

Osrdytbl[0] Bit7. Bit0--    Prio7  . PRIO0OSRDYTBL[1] Bit7. Bit0--    Prio15. PRIO8OSRDYTBL[2] Bit7. Bit0--    Prio23. PRIO16OSRDYTBL[3] Bit7. Bit0--    Prio31. PRIO24OSRDYTBL[4] Bit7. Bit0--    Prio39. PRIO32OSRDYTBL[5] Bit7. Bit0--    Prio47. PRIO40OSRDYTBL[6] Bit7. Bit0--    Prio55. PRIO48OSRDYTBL[7] Bit7. Bit0--    Prio63. Prio56

Each Task in the ready state can have the corresponding position 1 in osrdytbl[] based on its priority value. For example, if a Task with ready has a priority value of 4, you need to set osrdytbl[0] |= bit_4.

Osrdygrp

  Os_ext  Os_prio           osrdygrp;                        /* Ready List Group                         

Each bit of the OSRDYGRP represents the group of each priority in osrdytbl[]. For example, the Prio5 Task is in the ready state and it belongs to Osrdytbl[0], so osrdygrp |= bit_0. Another example is the Prio13 Task is in the ready state, it belongs to Osrdytbl[1], so osrdygrp |= bit_1.

Osunmaptbl

int8u Const OSUNMAPTBL[256] = {0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x00 to 0x0F    */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x10 to 0x1F */ 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x20 to 0x2F */4u, 0u, 1u, 0u, 2  U, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x30 to 0x3F * * 6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0U, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x40 to 0X4F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 0  U, 1u, 0u,/* 0x50 to 0x5f */5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u,/* 0x60                   To 0x6F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x70 to 0x7F  */7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x80 to 0x8F */4u, 0U, 1u, 0u, 2u, 0u, 1u, 0U, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x90 to 0x9F */5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 0  U, 2u, 0u, 1u, 0u,/* 0xA0 to 0xAF */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u,                   /* 0xb0 to 0xBF */6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u,/* 0xC0 to 0U */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0xD0 to 0xDF * /5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0xE0 to 0xEF */4u, 0u, 1u, 0 U, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u//0xF0 to 0xFF */};

Each member of osunmaptbl[] represents the bit position where the least significant bit (the lowest non-zero bit) is located for a int8u number (0-255). For example, 0x01, 0x03, 0x05, their least significant bits are bit_0, so osunmaptbl[1], osunmaptbl[3], osunmaptbl[5] are all 0. And 0x2, 0x6, 0xA, their least significant bits are bit_1, so osunmaptbl[2], osunmaptbl[6], osunmaptbl[10] are all 1. Therefore, you can use osunmaptbl[] to quickly determine the location of the least significant bit of a number of a int8u type by using a table-checking method.

Let's take a look at how Ucos_ii handles priority.

1. When a task is created, it calls the

int8u  os_tcbinit (int8u    prio,                   os_stk  *ptos,                   os_stk  *pbos,                   int16u   ID,                   int32u   stk_size,                   void    *pext,                   int16u   opt)
which
#if os_lowest_prio <= 63u                                         /* Pre-compute X,                  Y        *             /ptcb->ostcby = (int8u) (PRIO >> 3u);        PTCB->OSTCBX             = (int8u) (Prio & 0x07u);                                                                  /* Pre-compute BITX and bity         */        ptcb->ostcbbity          = (Os_prio) (1uL << ptcb->ostcby);        Ptcb->ostcbbitx          = (Os_prio) (1uL << PTCB->OSTCBX);

Visible in Os_tcbinit () in the Prio bit2-bit0 assigned to PTCB->OSTCBX, Bit5-bit3 was assigned to PTCB->OSTCBY. Therefore, Ptcb->ostcby represents the group number of the Prio in osrdytbl[], and PTCB->OSTCBX represents the bit position of the prio in Osrdytbl[ptcb->ostcby].

2. Now look at the Ostimetick () query Task in the ready state.

if ((Ptcb->ostcbstat & os_stat_suspend) = = Os_stat_rdy) {/  * is task suspended?       */                        osrdygrp               |= ptcb->ostcbbity;  /* No, make ready  */                        osrdytbl[ptcb->ostcby] |= ptcb->ostcbbitx;                    }

Here, the bit position in osrdygrp corresponding to the group number of the task priority is 1, which corresponds to the position 1 of the task priority in Osrdytbl[ptcb->ostcby].

3. Back to the previous mentioned,

static  void  os_schednew (void) {#if Os_lowest_prio <= 63u/* See if we support up to +                        tasks                   */
   
    int8u   y;    Y             = osunmaptbl[osrdygrp];    Ospriohighrdy = (int8u) ((y << 3u) + osunmaptbl[osrdytbl[y]);
   
In order to find the task of the highest priority in the ready queue (the lower number corresponding to higher), you need to find the one with the smallest group numbers and the smallest number within the group. Osunmaptbl[] is the table that is used to find the least significant bit of a int8u type number. Thus, the value corresponding to the highest priority in the current ready queue can be calculated.

Reference:

Priority the decision table Osunmaptbl principle Interpretation UCos


















Ucos-ii how to get the highest-priority task

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.