我在PC(mingw32,32bit arch)上模拟来自嵌入式系统(stm32,KeilμVision5,MDK-ARM)的代码.ARM编译器的对齐方式与我的桌面mingw构建不匹配:
// ARM Code (ARM compiler uses __packed)
typedef __packed struct _file
{
uint8_t var1;
uint16_t var2;
} FILE;
// PC mingw gcc code trying to emulate layout above.
typedef struct __attribute__((packed, aligned(1))) _file
{
uint8_t var1;
uint16_t var2;
} FILE;
Run Code Online (Sandbox Code Playgroud)
在源代码中,我执行以下操作:file.var1 = 0x22; file.var2 = 0xAA55;
然后将其写入内存.当我读取它显示的嵌入式系统上的内存时0x22, 0x55, 0xAA
.在Windows机器上读取0x22, 0xFF, 0x55, 0xAA
,与在2填充第二个字节.我该如何纠正这种行为?
我们正在将嵌入式应用程序从 Windows CE 移植到不同的系统。当前的处理器是STM32F4。我们当前的代码库大量使用 TLS。新原型运行的是 KEIL CMSIS RTOS,其功能大大减少。
在http://www.keil.com/support/man/docs/armcc/armcc_chr1359124216560.htm上,它说从5.04开始支持线程本地存储。现在我们使用的是5.04。问题是,当将我们的程序与__thread int a;
链接器的变量定义链接时,无法找到__aeabi_read_tp
对我来说有意义的。
我的问题是:是否有可能实施__aeabi_read_tp
并且会起作用,还是还有更多的内容?
如果这对我们来说根本不可能:有没有办法仅在软件中实现 TLS?我们暂时不讨论那里的性能。
编辑__aeabi_read_tp
我尝试通过查看旧的 freeBSD 源和其他源来
实现。虽然该函数主要是在汇编中实现的,但我发现了一个 C 版本,可归结为:
extern "C"
{
extern osThreadId svcThreadGetId(void);
void *__aeabi_read_tp()
{
return (void*)svcThreadGetId();
}
}
Run Code Online (Sandbox Code Playgroud)
这基本上所做的就是给我当前正在执行的线程的 ID (void*)。如果我理解正确的话,那就是我们想要的。这可能行得通吗?