《FreeRTOS内核解析v0.1LOVT》由会员分享,可在线阅读,更多相关《FreeRTOS内核解析v0.1LOVT(51页珍藏版)》请在金锄头文库上搜索。
1、FreeRTOS内核解析FreeRTOS是一种小型的嵌入式实时系统内核,应用比较广泛,并且开源,商业免费。在STM32F4系列上移植FreeRTOS Start System Peripheral Init OS Init TASK A OS Task Scheduler TASK B TASK C 图1 OS操作流程在FreeRTOS内核中涉及的文献: 1. croutine.c 协线程文献,和任务类似,在系统资源比较缺少下使用。2. list.c 列表构造描述,在内核整体控制上都使用了列表格式数据解决。一切 的数据构造基本。3. queue.c 队列,任务和任务之间的通讯解决。 4. Ti
2、mers.c 软定期,以任务形式存在。5. Port.c 硬件与系统内核交互部分。SVC、PENDSC、中断等设立。汇编与C的结合6. Heap.c 堆栈内存空间。内存空间申请,释放。在这里我们使用heap_4.c。7. tasks.c 所有任务有关函数。8. cmsisi_os.c 系统有关接口CMSISI_OS原则化,接口解决。 heap_4.c 实现原理:申请一块静态内存,按照堆的方式解决。涉及内存申请,释放,自动合并相连的空闲内存。 应用API函数: void *pvPortMalloc(size_t xWantedSize); void vPortFree(void *pv); si
3、ze_t xPortGetFreeHeapSize(void); 内部过程函数: static void prvHeapInit(void); static void prvInsertBlockIntoFreeList(xBlockLink *pxBlockToInsert) ; /申请内存空间块描述 可以看做一种节点typedef struct A_BLOCK_LINK struct A_BLOCK_LINK *pxNextFreeBlock; /指向下一块内存 size_t xBlockSize; /空闲块大小xBlockLink;/指向开始和结尾 xStart是静态内存 pxEnd 是
4、个指针 xBlockLink xStart, *pxEnd = NULL节点数据空间。节点数据空间。在系统蛇口中要考虑到字节对齐的问题。因此在申请一块内存时,要先进行内存字节格式对齐。也就是说1-7个字节格式化后也为8个字节。#define portBYTE_ALIGNMENT 8 /8字节对齐#define portBYTE_ALIGNMENT_MASK ( 0x0007 ) /对齐掩码static const unsigned short heapSTRUCT_SIZE = (sizeof(xBlockLink) + (portBYTE_ALIGNMENT - 1) & portBYTE_
5、ALIGNMENT_MASK);/静态内存 作为整个内存空间 configTOTAL_HEAP_SIZE 宏定义设立 根据需求设立大小static unsigned char ucHeapconfigTOTAL_HEAP_SIZE; #define heapADJUSTED_HEAP_SIZE(configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT) /实际可用大小 在初始化prvHeapInit()函数中 假设configTOTAL_HEAP_SIZE为1024 (0x400)在实际使用空间中 起码可以保持 1024 - 8个字节空间可用pucAlignedHe
6、ap 指向了8字节对齐化了的地址xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;xStart.xBlockSize = (size_t)0;假设ucHeap是一种不对齐的地址 0x00427c58;那么8字节对齐后为0x00427c600x00427c58 0x00428058。 0x00427c60 pucAlignedHeap 指向该位置xStart可以看做独立该空间的一种节点 大小为0 指向空间的开始地址xStart-pxNextFreeBlock 指向pucAlignedHeappucHeapEnd = pucAlignedHeap
7、 + xTotalHeapSize;pucHeapEnd -= heapSTRUCT_SIZE;pxEnd = (void *)pucHeapEnd; 更新pxEnd 指向pxEnd-xBlockSize = 0;pxEnd-pxNextFreeBlock = NULL;0x00428050(pxEnd)。 NULL(pxNextFreeBlock )pxFirstFreeBlock = (void *)pucAlignedHeap;pxFirstFreeBlock-xBlockSize = xTotalHeapSize - heapSTRUCT_SIZE;pxFirstFreeBlock-p
8、xNextFreeBlock = pxEnd;xFreeBytesRemaining -= heapSTRUCT_SIZE; /更新空闲大小使用标志 高位置1xBlockAllocatedBit = (size_t)1) pxNextFreeBlock对齐损失节点数据空间pxEnd申请内存pvPortMalloc(size_t xWantedSize) xWantedSize为要申请内存的大小,返回该内存的指针if(pxEnd = NULL)/未初始化 先进行初始化prvHeapInit();xWantedSize += heapSTRUCT_SIZE;/实际使用的空间为节点+内存xWante
9、dSize设立的大小也要字节对齐化解决pxPreviousBlock = &xStart;pxBlock = xStart.pxNextFreeBlock;while(pxBlock-xBlockSize pxNextFreeBlock != NULL) /遍历全局 查看足够大的空闲内存pxPreviousBlock = pxBlock;pxBlock = pxBlock-pxNextFreeBlock;pxPreviousBlock 指向 xStartpxBlock 注意:这里的B 数据都是空闲内存B空闲B空闲B空闲B。ENDpxPreviousBlock pxBlock B空闲B空闲B空闲
10、B。END pxPreviousBlock pxBlock (该空间足够大)B空闲B空闲B空闲B。END pvReturn pvReturn 返回空间地址pxPreviousBlock-pxNextFreeBlock = pxBlock-pxNextFreeBlock; pxPreviousBlock pxBlock 这里pxBlock不为空 断开空闲链表B空闲B空闲B数据B。END空间大 一分为二pxNewBlockLink = (void *)(unsigned char *)pxBlock) + xWantedSize);pxNewBlockLink-xBlockSize = pxBlock-xBlockSize - xWantedSize;pxBlock-xBlockSize = xWantedSize; 这里可以看出节点中的大小涉及节点所占空间 pxBlock pxNewBlockLink B空闲B要用内存空闲B。ENDprvInsertBlockIntoFreeList(pxNewBlockLink); 把新块插入空闲列表xFreeBytesRemaining -= pxBlock-xBlockSize; 更新剩余空间pxBlock-xBlockSize |= xBlockAllocatedBit; 节点长度高位置1pxBlock-pxNextFreeBl