標簽:ima image 刪除 src 刪除线 32位 就會 數據 max
RT-Thread 要支持多优先级,需要靠就绪列表的支持,从代码上看,就绪列表由两个在schedule.c文件定义的全局变量组成,一个是線程就緒優先級組rt_thread_ready_priority_group,另一个是線程優先級表rt_thread_priority_table[RT_THREAD_PRIORITY_MAX].
爲了快速找到線程在線程優先級表的插入和移除的位置,RT-Thread專門設置了一個線程就緒優先級組。從代碼上看,線程就緒優先級組就是一個32位的整數,每一個位對應一個優先級。一個就緒優先級組最多只能表示32個優先級。如果優先級超過32個怎麽辦,則可以定義一個線程就緒優先級數組,每一個數組成員都可以表示32個優先級。具體支持到多少由系統的RAM大小決定。線程就緒優先級組在schedule.c中定義
/* 線程就緒優先級組 */ rt_uint32_t rt_thread_ready_priority_group;
注意:當線程准備好,先在線程就緒優先級組的相应的位置1,然後再將線程插入線程優先級表。
在系统的下一个系统周期到来时,调度器需要选取优先级最高的线程去执行。从图線程就緒優先級組的位设置情况 我们一眼就可以看出線程就緒優先級組从右往左开始数,第一个置 1 的位是位 1,即表示此时就绪的线程当中,优先级最高的是线程 1,然後调度器从線程優先級表的索引 1 下取出线程 1 的线程控制块,从而切换到线程 1。但是,单片机没有眼睛,并不能跟人一样一眼就从線程就緒優先級組中看到那个第一个置 1 的位,怎么办?RT-Thread kservice.c 文件中,有一个专门的函数 __rt_ffffs,用来寻找 32 位整形数第一个(从低位开始)置 1 的位号,具体实现如下:
/** * 该函数用于从一个 32 位的数中寻找第一个被置 1 的位(从低位开始), * 然後返回该位的索引(即位号) * * @return 返回第一个置 1 位的索引号。如果全为 0,则返回 0。 */ int __rt_ffs(int value) { /* 如果值为 0,则直接返回 0 */ if (value == 0) return 0; (1) /* 检查 bits [07:00] 这里加 1 的原因是避免当第一个置 1 的位是位 0 时 返回的索引号与值都为 0 时返回的索引号重复 */ if (value & 0xff) (2) return __lowest_bit_bitmap[value & 0xff] + 1; /* 检查 bits [15:08] */ if (value & 0xff00) (3) return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9; /* 检查 bits [23:16] */ if (value & 0xff0000) return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17; /* 检查 bits [31:24] */ (5) return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25; }
/* * __lowest_bit_bitmap[] 数组的解析 * 将一个 8 位整形数的取值范围 0~255 作为数组的索引,索引值第一个出现 1(从最低位开始) 的位号作为该数组索引下的成员值。 * 举例:十进制数 10 的二进制为:0000 1010, 从最低位开始,第一个出现 1 的位号为 bit1,则有__lowest_bit_bitmap[10]=1 * 注意:只需要找到第一个出现 1 的位号即可 */ const rt_uint8_t __lowest_bit_bitmap[] = { /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
/* 線程優先級表 */ rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
void rt_schedule_insert_thread(struct rt_thread *thread) { register rt_base_t temp; /* 關中斷 */ temp = rt_hw_interrupt_disable(); /* 改變線程狀態 */ thread->stat = RT_THREAD_READY; /* 將線程插入就緒列表 */ rt_list_insert_before(&(rt_thread_priority_table[thread->current_priority]),&(thread->tlist)); /* 设置線程就緒優先級組中对应的位 */ rt_thread_ready_priority_group |= thread->number_mask; /* 開中斷 */ rt_hw_interrupt_enable(temp); }
void rt_schedule_remove_thread(struct rt_thread *thread) { register rt_base_t temp; /* 關中斷 */ temp = rt_hw_interrupt_disable(); /* 将线程从就绪列表刪除 */ rt_list_remove(&(thread->tlist)); if (rt_list_isempty(&(rt_thread_priority_table[thread->current_priority]))) { rt_thread_ready_priority_group &= ~thread->number_mask; } /* 開中斷 */ rt_hw_interrupt_enable(temp); }
標簽:ima image 刪除 src 刪除线 32位 就會 數據 max
原文地址:https://www.cnblogs.com/tansuoxinweilai/p/14965666.html