想弄明白freertos内部是如何工作的?
从哪里入手呢?那么先看看TASK吧。结果发现TASK里面调用了LIST。然后看了几篇文章,发现至少有两篇文章说,首先要弄懂LIST,也就是需要弄懂链表。于是找谭浩强的C语言看了看。说这种是单链表,如下
STRUCT student {
DATA;
next * student_ptr;
}
而这种是双链表,如下
STRUCT student {
DATA;
next *student_ptr;
previous *student_Ptr;
}
可见,链表是靠内存的真实物理地址来寻址的,地址找到了,那么所对应的数据也就找到了。
那么知道了这些,如何读懂链表的那些函数呢?就是freertos源码里面的list.C。
可以发现,list.C和LIST.H包含了所有的list函数。可见很清晰,隔离做的不错。
list.C可以看到 作者很久没有更新了,尽管freertos版本经常更新。list.C里面仅仅有5个函数
void vListInitialise( xList *pxList );
void vListInitialiseItem( xListItem *pxItem );
void vListInsert( xList *pxList, xListItem *pxNewListItem );
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
void vListRemove( xListItem *pxItemToRemove );
如此少的函数,直接读源码吧,并查阅了一些资料,感觉比较好的有
看了这些以后,发现还是迷迷糊糊。
原因就是我对链表太陌生了。一直以来我写程序从来不用链表的,链表用了就可能出错。与写出安全的程序是相违背的。但这次是为了读懂代码,所以不得不硬头皮想办法。
最好的办法就是弄个简单的例子,用keil 、MDK运行一下。
#include "list.h"
xList list;
xListItem item1 = {1};
xListItem item2 = {2};
xListItem item3 = {3};
xListItem item4 = {4};
int main(void)
{
vListInitialise((xList *) &list);
vListInitialiseItem( (xListItem *) &item1);
vListInitialiseItem( (xListItem *) &item2);
vListInitialiseItem( (xListItem *) &item3);
vListInitialiseItem( (xListItem *) &item4);
vListInsertEnd((xList *) & (list), &item1);
vListInsertEnd((xList *) & (list), &item2);
vListInsertEnd((xList *) & (list), &item3);
vListInsertEnd((xList *) & (list), &item4);
vListRemove(&item3);
while (1);
}
这样就彻底理解了。当然说起来轻巧,弄这个例子过程也比较曲折。
另外,如果随意(不按照item的顺序)的 添加删除ITEM,可能就会在
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
就是这句话停在了这里出不来。
好了,到点吃饭了,有空再议。
==================================================
再举个例子吧,这次不按照1/2/3/4顺序添加,当然Freertos是按照顺序的。
例子如下:
#include "list.h"
xList list;
xListItem item1 = {1};
xListItem item2 = {2};
xListItem item3 = {3};
xListItem item4 = {4};
int main(void)
{
vListInitialise((xList *) &list);
vListInitialiseItem( (xListItem *) &item1);
vListInitialiseItem( (xListItem *) &item2);
vListInitialiseItem( (xListItem *) &item3);
vListInitialiseItem( (xListItem *) &item4);
vListInsertEnd((xList *) & (list), &item1); //【a】
vListInsertEnd((xList *) & (list), &item4); //【b】
vListInsertEnd((xList *) & (list), &item3); // 【c】
vListInsert((xList *) & (list), (xListItem *)&item2); //[D]
vListRemove(&item4); //[E]
while (1);
}