标签: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