C STM32向EEPROM写入有符号短路

C STM32向EEPROM写入有符号短路,c,stm32,eeprom,C,Stm32,Eeprom,我使用STM32F0单片机和模拟EEPROM。EEPROM将数据作为EE_可写变量(uint16\u t VirtAddress,uint16\u t data)并将其作为EE_ReadVariable(uint16\u t VirtAddress,uint16\u t*data)返回,但我的数据是int16\u t。所以我的问题是,我如何写和读签名短 根据,数据作为16位字存储在内存中,因此它是uint16\u t。这是存储在模拟EEPROM中的任何内容都必须是的底层数据类型。无论您存储什么,

我使用STM32F0单片机和模拟EEPROM。EEPROM将数据作为
EE_可写变量(uint16\u t VirtAddress,uint16\u t data)
并将其作为
EE_ReadVariable(uint16\u t VirtAddress,uint16\u t*data)
返回,但我的数据是
int16\u t
。所以我的问题是,我如何写和读签名短

根据,数据作为16位字存储在内存中,因此它是
uint16\u t
。这是存储在模拟EEPROM中的任何内容都必须是的底层数据类型。无论您存储什么,它都必须具有这种类型


int16\u t
保证具有与
uint16\u t
相同的大小。使用uint16\u t类型的中间变量

不幸的是,当涉及到硬件相关编程(如EEPROM仿真)时,C语言是愚蠢的。因此,您可以使用的唯一可靠解决方案是:

uint16_t u16;
EE_ReadVariable(VirtAddress, &u16);
int16_t i16;
i16 = (int16_t)u16;
或者:

memcpy(&i16, &u16, 2);
其他任何东西都是不安全和危险的。特别是,您不能这样做:

您也不能执行
i16=*(int16\u t*)&u16;//坏的


有关原因的更多信息,请参见此处:

您能详细说明一下吗?你的意思是像
EE_WriteVariable(VirtAddress,(uint16_t*)myData)
然后
EE_ReadVariable(VirtAddress,(int16_t*)数据)
?@muliku假设
myData
的定义如下:
int16\u t myData
:EE\u WriteVariable的第二个参数不是指针,因此需要像这样强制转换:
(uint16\u t)myData
EE\u ReadVariable
的第二个参数需要一个
uint16\u t
的地址,因此需要这样强制转换:
(uint16\u t*)&myData
-1表示“强制转换指针”,它将调用未定义的行为,尤其是在gcc上,会中断程序。类似地,@Fiddling Bits的注释也有同样严格的别名错误。这些东西现在很重要,因为每个人都在使用gcc进行嵌入式编程。@Lundin删除了这部分内容。你是不是建议我们不要专门为EEPROM等硬件模块键入cast?或者通常
EE_ReadVariable(VirtAddress,(uint16\u t*)&i16)是坏的吗?如果您查看clean flight的源代码
bt=(*(*(u IO uint32_t*)(BKPSRAM_BASE+4))这是为SRAM完成的(但不是读/写方法)@约翰:总的来说,这是不好的。但在嵌入式系统中,您必须始终在不同类型之间切换,就像EEPROM驱动程序一样。这在历史上不是一个问题,因为嵌入式编译器依赖于非标准扩展。但是随着gcc在嵌入式分支中的引入,系统会左右中断,因为它们包含严格的别名冲突。@ClamentJohn和yes,“干净飞行”(不管是什么)被打破了,如果这些地址的内存包含编译器识别为uint32_t变量或没有先前声明类型的内存以外的任何内容。经过进一步检查,它似乎是原始地址,没有声明类型,没有,没有严格的别名冲突。
EE_ReadVariable(VirtAddress, (uint16_t*)&i16); // BAD