[MH22D3开发笔记]1. 变量地址对齐,宏__ALIGNED的使用
在移植某GUI到迅龙3号开发板的时候,gui内使用到了动态内存分配,第一次编译完成,运行,very good。运行良好!
为便于调试,修改了一下编译选项为-O0,再运行,oh,my god,跑飞了。。。
调试追踪。。。
发现到了这里,对内存对齐检查失败:
tlsf_t tlsf_create(void* mem)
{
#if _DEBUGif (test_ffs_fls()){return 0;}
#endifif (((tlsfptr_t)mem % ALIGN_SIZE) != 0){LLPRINT("tlsf_create: Memory must be aligned to %u bytes.\n",(unsigned int)ALIGN_SIZE);return 0;}control_construct(tlsf_cast(control_t*, mem));return tlsf_cast(tlsf_t, mem);
}
往前倒查,发现这个指针传入的是如下定义的数组:
static uint8_t tlsfMemBuf[MEM_SIZE];
真相大白,这个uint8_t 类型的定义,被编译器定义到一个非4字节对齐的地址了,所以后面代码对齐检测失败,导致后续内存分配失败。
既然知道原因了,那就好解决了,那就用宏__ALIGNED(4)让它4字节对齐呗:
static __ALIGNED(4) uint8_t tlsfMemBuf[MEM_SIZE];
好家伙,加进去编译,错误提示来了:
这意思认不到这个宏__ALIGNED啊
查一下关于编译器语法扩展对对齐指令的支持情况,如下:
看起来也没有问题啊,很标准,用的__ALIGNED(4)来使这个数组4字节对齐,为什么编译报错呢?
既然是一个宏(不是编译器语法),搜索一下__ALIGNED的定义看看:
被定义在文件“cmsis_armclang.h”
#ifndef __ALIGNED#define __ALIGNED(x) __attribute__((aligned(x)))
#endif
我用的编译器为AC6,在文件cmsis_compiler.h里面包含了文件“cmsis_armclang.h”
/** Arm Compiler above 6.10.1 (armclang)*/
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100)#include "cmsis_armclang.h"
知道了这个关系,那就好解决了,在定义数组
static __ALIGNED(4) uint8_t tlsfMemBuf[MEM_SIZE];
的文件前面加入对文件cmsis_armclang.h的引用就可以了:
#include "cmsis_compiler.h"
再编译,运行,ok!
为了兼容编译器不同版本,代码建议使用宏__ALIGNED来对齐地址,尽量不要使用
attribute((aligned(4)))之类的与编译器相关的语法来定义。
原创文章,转载请注明出处,未经书面允许,不得用于商业用途