FreeRTOS中列表和列表项插入函数分析

发布者:WanderlustGlow最新更新时间:2020-04-01 来源: eefocus关键字:FreeRTOS  列表  列表项  插入函数 手机看文章 扫描二维码
随时随地手机看文章

在学习FreeRTOS的过程中,看到列表和列表项插入的时候,对于列表插入函数vListInsert(),理解起来感觉比较费劲。于是对照函数画个示意图,帮助理解。


先看看列表插入函数代码。


void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )

{

    ListItem_t *pxIterator;

    const TickType_t xValueOfInsertion=pxNewListItem->xItemValue;

    listTEST_LIST_INTEGRITY( pxList );

    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );

    if( xValueOfInsertion == portMAX_DELAY )

    {

    pxIterator = pxList->xListEnd.pxPrevious;

    }

    else

    {

        for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) 

        {

        }

    }

    pxNewListItem->pxNext = pxIterator->pxNext;

    pxNewListItem->pxNext->pxPrevious = pxNewListItem;

    pxNewListItem->pxPrevious = pxIterator;

    pxIterator->pxNext = pxNewListItem;

    pxNewListItem->pvContainer = ( void * ) pxList;

    ( pxList->uxNumberOfItems )++;

}


参数: pxList:列表项要插入的列表;

pxNewListItem:要插入的列表项

const TickType_t xValueOfInsertion=

pxNewListItem->xItemValue:


获取要插入列表项值(列表项成员变量xItemValue的值),根据这个值来确定列表项要插入的位置。


listTEST_LIST_INTEGRITY( pxList )和listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ):检查列表和列表项完整性。


if( xValueOfInsertion == portMAX_DELAY ):

获取列表项插入到什么位置,如果插入列表项的值等于portMAX_DELAY,即列表项值为最大值,此时插入的位置为列表最末尾

pxIterator = pxList->xListEnd.pxPrevious:

获取要插入点,列表中xListEnd表示列表末尾,初始化列表时xListEnd的列表值也是portMAX_DELAY,尽管两个值一样,但是要把插入的列表项放在xListEnd前面。


for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion;

pxIterator = pxIterator->pxNext ) :

如果列表项的值不等于portMAX_DELAY那么就需要在列表中遍历,寻找插入位置,用for循环遍历列表寻找插入点。

通过上面可以知道, pxNewListItem为要插入的列表项,pxIterator为要插入的插入点位置。


假如现在的列表项如下:

在这里插入图片描述

此时我们要将 50 插入到列表中去

在这里插入图片描述

那么此时pxNewListItem指向的就是50这一项,pxIterator指向的就是40这一项。由上面的for循环也可以看出

pxIterator->pxNext->xItemValue <= xValueOfInsertion;

列表中的值小于等于当要插入的值,插入点就继续指向下一个,此时要插入的值是50,它会依次和列表中的值20、30、40、60比较,当比较到60时,插入点的值是60,大于要插入的值50,此时for循环退出,插入点指向40这一项。


此时列表的状态入下图所示。

在这里插入图片描述

下来开始执行列表插入操作。


pxNewListItem->pxNext = pxIterator->pxNext;


将插入点指向的下一个列表项赋值给新插入列表项的下一项。

在这里插入图片描述

此时列表项50的下一项指向了列表项60.


pxNewListItem->pxNext->pxPrevious = pxNewListItem;


将新插入列表项的下一项的前一项设置为新插入列表项。


也就是说此时列表项60的上一个列表项指向了50。

在这里插入图片描述

pxNewListItem->pxPrevious = pxIterator;


下来将新插入列表项的前一个列表项设置为插入点。


此时列表项50的前一项指向了40。

在这里插入图片描述

pxIterator->pxNext = pxNewListItem;


将新插入列表项指向插入点的下一项

在这里插入图片描述

此时列表项40的下一项是列表项50,列表项50的下一项是60。列表项60的前一项是列表项50,列表项50的前一项是列表项40。


pxNewListItem->pvContainer = ( void * ) pxList:


插入后,列表项成员变量pvContainer记录此列表项属于哪个列表。


pxList->uxNumberOfItems:列表成员数量加1。


这样列表项50就成功的插入到列表中去了,插入的过程就是将插入点与后面的连接项断开,然后重新连接到新插入项上。在把新插入项和断开的连接项连接起来。这样通过图示就可以很清晰的看到列表插入的过程,下来再去看代码的时候,理解起来就更容易了。

关键字:FreeRTOS  列表  列表项  插入函数 引用地址:FreeRTOS中列表和列表项插入函数分析

上一篇:FreeRTOS+STM32F103中断中发送任务通知单片机死机问题
下一篇:STM32F407ZGT6用滴答定时器实现精确延时(寄存器版)

推荐阅读最新更新时间:2024-11-05 20:18

FreeRTOS 在STM32上的移植 V1.0
FreeRTOS作为开源的轻量级实时性操作系统,不仅实现了基本的实时调度、信号量、队列和存储管理,而且在商业应用上不需要授权费。 FreeRTOS的实现主要由list.c、queue.c、croutine.c和tasks.c 4个文件组成。list.c 是一个链表的实现,主要供给内核调度器使用;queue.c 是一个队列的实现,支持中断环境和信号量控制;croutine.c 和task.c是两种任务的组织实现。对于croutine,各任务共享同一个堆栈,使RAM的需求进一步缩小,但也正因如此,他的使用受到相对严格的限制。而task则是传统的实现,各任务使用各自的堆栈,支持完全的抢占式调度。 FreeRTOS的主
[单片机]
<font color='red'>FreeRTOS</font> 在STM32上的移植 V1.0
SDCC编译器和FreeRTOS在C8051F上的开发应用
MCS-51系列单片机应用广泛,在我国学习研究的人较多。使用C语言在单片机上开发程序可提高开发效率,目前针对该内核兼容单片机开发的C语言编译器有Keil、Tasking、Raisonance、IAR和Hi-Tech等,但这些都是商业化的产品,使用需要付费购买。使用专为单片机开发的免费C语言编译器SDCC(Small Device C Compiler)则是一个不错的选择。 由于技术和工艺的发展,各种MCS~51系列内核兼容的新型单片机不断推出,除了运行速度提高,内部资源也逐渐丰富。例如,Silicon Labs公司推出的C8051F系列单片机,兼容8051内核,功能强大,运算速度快,处理能力强,为复杂软件的运行提供了可能。
[单片机]
SDCC编译器和<font color='red'>FreeRTOS</font>在C8051F上的开发应用
基于STM32的FREERTOS应用的几个常见问题
1、怎样将 FreeRTOS 移植到不同的Cortex-M 内核? 答:若需将 FreeRTOS 移植到正确的Cortex-M 产品,您必须从正确的目录导入 “port.c”文件。例如,若微控制器是带有IAR 工具的 Cortex-M0 内核,则您必须从“FreeRTOS\Source\portable\IAR\ARM_CM0” 获取 port.c。 2、FreeRTOS 使用需要ROM/RAM? 答:这取决于您的编译器、代码架构,以及RTOS 内核配置。一般来说, RTOS 内核本身需要大约 5到 10 K 字节 ROM 空间。 如果创建的线程或队列数增加,RAM 使用量就会上升。 3、怎样设置 CPU 时钟? 答:CPU 时钟
[单片机]
STM8L101F3P6-官方库的Bug列表(不断维护)
STM8L101F3P6该款MCU官方库stsw-stm8012UtilitiesSTM8L101_EVALCommonstm8l_eval_i2c_ee.c文件中sEE_WritePage函数中 while((uint16_t)(*NumByteToWrite) 0) { /* Send the byte to be written */ I2C_SendData( *pBuffer); /* Test on EV8 and clear it */ /* Wait till all data have been physically transferred on the bus */ while
[单片机]
STM32F407上调试freeRTOS问题
是在正点原子的阿波罗STM32F429开发板上的例子改来的,他们的编译没有问题,我编译时出现如下问题: 定位到出错的地方,代码是: 再追代码,configMAX_SYSCALL_INTERRUPT_PRIORITY 的定义是: #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (8 - configPRIO_BITS) ) 其中 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 定义为: #define configLIBRARY_MAX
[单片机]
STM32F407上调试<font color='red'>freeRTOS</font>问题
基于STM32F407的FreeRTOS学习笔记(8)
前面几期我们介绍过队列、二进制 信号 量以及计数信号量。但是在使用二进制信号量的时候会有一种优先级反转问题的出现,简而言之就是低优先级任务因为无法及时释放信号量而导致等待信号量发生的高优先级任务迟迟无法进行。 众所周知, FreeRTOS 的各任务的运行顺序是由任务的优先级决定的,优先级高的任务比优先级低的任务先执行。 假设我们有三个任务:任务H,任务M,任务L,分别代表高优先级,中优先级以及低优先级。 任务H和任务M同时被挂起,正在等待某一个事件的发生 , 同时任务H和任务L使用同样的全局资源 (意味着当任务L正在占用全局资源时任务H的执行需要等待任务L执行完释放信号量) 当任务L运行时占用了全局资源。 任务H的事件
[单片机]
基于STM32F407的<font color='red'>FreeRTOS</font>学习笔记(8)
STM32+freeRTOS学习笔记-1.使用cube MX创建一个freeRTOS的keil工程
硬件:机智云STM32平台V2.1 软件:cube MX+keil MDK-ARM V5 机智云的STM32开发平台小巧玲珑,用起来也顺手,所以就将正点原子的战舰开发板扔一旁吃灰了。目前刚开始学习,用到的硬件资源也不多,后续做相关实验时说不准又捡起来了。 1.简单介绍一下cube MX的使用 下载安装的过程就不在赘述,直接开始使用。 双击打开cube MX,点击新建工程 由于本底板的MCU型号是:STM32F103C8T6,所以按照下图来选择就对了。这个根据当时自己使用的MCU型号来对应选择就好了。 接着就是资源配置界面了, 1、先配置RCC的时钟源为外部高速时钟 2、配置时钟系统,其实很简单,
[单片机]
STM32+<font color='red'>freeRTOS</font>学习笔记-1.使用cube MX创建一个<font color='red'>freeRTOS</font>的keil工程
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved