您的位置:首页 > 其它

FreeRTOS内存管理中字节对齐的理解

2020-02-13 22:45 701 查看

FreeRTOS内存申请函数pvPortMalloc()字节对齐的语句如下

 1.申请内存数字节对齐

            xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
xWantedSize 是要申请的字节数

portBYTE_ALIGNMENT是字节对齐数

portBYTE_ALIGNMENT_MASK 是字节对齐掩码


xWantedSize 是要申请的字节数,先按照数学思维理一理思路,比如需要申请21个字节且按照8字节对齐,申请的字节数必须是8的倍数才能达到字节对齐的目的,那么被除数是21,除数是8。21除以8余5,除数8必须减去余数5再加上被除数才能被8整除(8-5=3,21+3=24),所以会申请24个字节。代码实现为xWantedSize += (portBYTE_ALIGNMENT -xWantedSize%portBYTE_ALIGNMENT)。

 

FreeRTOS加入了portBYTE_ALIGNMENT_MASK来实现字节对齐的功能。

xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
我们发现,当portBYTE_ALIGNMENT 和portBYTE_ALIGNMENT_MASK满足如下关系时,

portBYTE_ALIGNMENT

portBYTE_ALIGNMENT_MASK

8(表示以8个字节对齐)

0x0007

4(表示以4个字节对齐)

0x0003

2(表示以2个字节对齐)

0x0001

1(表示以1个字节对齐)

0x0000

xWantedSize % portBYTE_ALIGNMENT 等价于 xWantedSize & portBYTE_ALIGNMENT_MASK。xWantedSize & portBYTE_ALIGNMENT_MASK 就是被除数xWantedSize 对除数portBYTE_ALIGNMENT取余的值。

 

2.内存堆起始地址字节对齐

pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );

&ucHeap[ portBYTE_ALIGNMENT ] 是编译器定义的内存堆的起始地址增加了portBYTE_ALIGNMENT ,

&ucHeap[ portBYTE_ALIGNMENT ]   &  ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) 等价于&ucHeap[ portBYTE_ALIGNMENT ]  对 portBYTE_ALIGNMENT 取余,然后&ucHeap[ portBYTE_ALIGNMENT ] 减去这个余数,得到的地址正好会被portBYTE_ALIGNMENT 整除,也就实现了字节对齐。

举例:

假设,为了好理解,编译器定义ucHeap地址为3,portBYTE_ALIGNMENT 为8,portBYTE_ALIGNMENT_MASK 为0x07。ucHeap[ portBYTE_ALIGNMENT ] 地址就为11,11&(~(0x07))为8。内存地址从3变成8,实现了内存堆地址的字节对齐。

 

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
qcmc123 发布了1 篇原创文章 · 获赞 0 · 访问量 816 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: