FreeRTOS的源代码个人分析(基于KEIL下STM32F103的Demo) 七

FreeRTOS的堆栈管理系统 heap_2.c的分析FreeRTOS的源代码里有5种堆栈管理系统,分别命名heap1.c,heap2.c到heap5.c 均放在FreeRTOS\Source\portable\MemMang 这个文件夹里面,对于M3内核的单片机而言,其Demo默认采用的是heap2.c这个系统,这里分析一下这个管理系统的源代码。首先,对于ARM内核,其汇编编程有一套APPCS规则
摘要由CSDN通过智能技术生成

FreeRTOS的堆栈管理系统 heap_2.c的分析

FreeRTOS的源代码里有5种堆栈管理系统,分别命名heap1.c,heap2.c到heap5.c 均放在FreeRTOS\Source\portable\MemMang 这个文件夹里面,对于M3内核的单片机而言,其Demo默认采用的是heap2.c这个系统,这里分析一下这个管理系统的源代码。

首先,对于ARM内核,其汇编编程有一套APPCS规则(参考这个博文:APPCS汇编编程规则),其为ARM公司制定的一套编程规则。其中一点提到的是:sp指向最后一个压入的值,数据栈由高地址向低地址生长)类型,即满递减堆栈,并且对堆栈的操作是8字节对齐。因此,在STM32F10x.s这个用汇编编写的启动文件里,在代码块里有ALIGN=3这么一个属性,就是让堆栈是8字节对齐的。在heap2.c的一开头,就有一个宏定义:

/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )

其左边configTOTAL_HEAP_SIZE 是定义在FreeRTOSConfig.h中的,值为17K,也就是DEMO默认给堆管理系统的最大的管理内存大小为17KB,如果你的处理器的内存够大,可以可以设置为更大的。后者portBYTE_ALIGNMENT定义在portmacro.h中,代表的就是字节对齐的数量,也就是8,为什么这里会让总大小减去对齐大小8?这是因为在下面的申请堆的内存时:

/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
    /* The application writer has already defined the array used for the RTOS
    heap - probably so it can be placed in a special segment or address. */
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */

我们不知道申请到的内存的地址大小是否是8的整数,也就是8字节对齐的地址。举一个简单的例子,假如我们要申请的内存为32个字节(必须为8字节对齐),而我们申请到的内存的首地址为0x0200_0003,这样末尾地址就是0x0200_0022。因为要8字节对齐,因此实际我们可使用的内存是从0x0200_0008开始到0x0200_0001F共24个字节,因为从0x0200_0020到0x0200_0022之间不足8个字节了,所以末尾这3个字节也被舍去,再加上开头舍去的5个字节,一共是8个字节被舍去,因此实际得到的内存大小是期望的总数减去对齐大小8。(PS:但如果申请的内存的首地址刚好就是对齐的,那么开头地址的8个字节也会被舍去不被使用)

下面几行定义了内存块的结构体:

/* Define the linked list structure.  This is used to link free blocks in order
of their size. */
typedef struct A_BLOCK_LINK
{
    struct A_BLOCK_LINK *pxNextFreeBlock;   /*<< The next free block in the list. */
    size_t xBlockSize;                      /*<< The size of the free block. */
} BlockLink_t;

从这个定义可以看出,结构体内仅含有两个成员,一个是该内存块的下一个空闲内存块的地址,另一个是这个内存块的大小。
heap2的内存管理结构如下:
这里写图片描述
每一个内存的开头都有一个BlockLint结构体,这个结构体的大小在CM3里是8字节,PNB指针是4个字节,BlockSize这个变量也是4个字节,一共8个字节,刚好是8字节对齐的。所以每一个内存块的实际可用内存大小是BlockSize减去heapSTRUCT_SIZE也就是8,因此比如要申请76个字节的内存,那么首先要8字节对齐,需要申请80字节内存,再加上管理块的8字节大小一共需要88字节的内存。

static const
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值