c - 是否可以在此代码中将 8 位或 16 位值存储到 16 位对齐的缓冲区?



我想保存一些由 8 位指针指向 16 位对齐缓冲区的值(8 或 16 位)。

extern volatile INT16U NvM_Zone[128] __attribute((nodp, addr(NVRAM1_PAGE1_FIRST_ADDRESS)));
Std_ReturnType NvM_WriteBlock(NvM_BlockIdType BlockId, INT8U *NvM_SrcPtr) {
Std_ReturnType Res = E_OK;
NvM_ConfigType *nvm_config = &NvMConfig;
NvM_StatusType nvm_status = nvm_config->nvm_module_status;
if ((nvm_status == NVM_COMPLETED)) {
nvm_status = NVM_IN_PROGRESS;
nvm_config->nvm_data_info = &g_NvmDataList[0];
INT8U i = nvm_config->nvm_data_info[BlockId].data_start_addr;
INT8U size = nvm_config->nvm_data_info[BlockId].data_size_in_byte;
if (size == 2) {
INT16U *src = (INT16U*)NvM_SrcPtr;
INT16U *dst = &NvM_Zone[i];
*dst = *src;
} else {
INT8U *src  = NvM_SrcPtr;
INT16U *dst = &NvM_Zone[i];
*dst = (INT16U)(*src);
}       
NVRAM_SavePage(0);      // NVRAM_content : 0 ~ 63
NVRAM_SavePage(1);      // NVRAM_content : 64 ~ 127     
//NVRAM_SavePage(NVRAM2_PAGE1);
nvm_config->nvm_flash_cntr_in_rt++;
nvm_status = NVM_COMPLETED;
Res = E_OK;
} else {
Res = E_NOT_OK;
}
nvm_config->nvm_module_status = nvm_status;
return Res;
}
  1. 16 位值 - 是否可以保存 16 位值,该值在 8 位指针中参数化时强制转换(对齐冲突)? 最终目标是 16 位缓冲区,它将被强制转换为 16 位对齐。没事吗?

  2. 8 位值 - 据我所知,下面的代码应该没问题。但是对编码有更好的方法有什么建议吗?

编辑 1.

NvM_SrcPtr指针参数的传递内容如下。

INT8U Byte = 0x00U;
INT16U Word = 0x0000U;
NvM_WriteBlock(SPECIAL_MODE_TYPE_VAL, &Byte);
NvM_WriteBlock(SPECIAL_MODE_TYPE_VAL, (INT8U*)&Word);
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;

unsigned __int8 GX=7;
printf("Value:%dn",GX);
printf("%dn",&GX);
for(i=0;i<8;i++){
printf("Bin:%dn",GX&0b1<<i);
}
/*Pass INT8U to INT16U */
unsigned __int16 *DDC;
DDC=(unsigned __int16*)&GX;
printf("Value:%dn",*DDC);
printf("%dn",DDC);
/*Clearly Address is same but printf may be diff*/
for(i=0;i<8;i++){
printf("Bin:%dn",(*DDC)&0b1<<i);
}
for(i=8;i<16;i++){
printf("Bin2:%dn",(*DDC)&0b1<<i);
}
/*First 8 bit same*/
/*other 8 bit not sure because another 8bit give by address is not legal because not alloc*/
/*you can trans 8bit to 16bit using address if you dont fix another 8bit*/
/*if you want cover another value please make another 8bit stay original value*/
/*like below*/
unsigned __int16 NewValue=80;
*DDC=(*DDC)&(0xff00|NewValue);

/*By the way in multithreading case dont use this method because memory use will be too complex*/


return 0;
}

一般规则是只能使用正确的类型取消引用指针。您可以将指针转换为其他类型的指针,但如果要取消引用它,则需要将其转换回原始类型。

这些指针转换是实现定义的。这意味着不同的指针在某些系统上可以有不同的表示形式,您应该阅读编译器手册,了解这些指针如何在您的系统上工作。在典型的现代系统上,指针通常使用相同的表示形式,指针转换就可以了。

但是,您的情况可能是特例。您会看到字符类型指针是 C 标准中的一个特殊例外:它们保证具有可转换为其他指针类型的表示形式,并且即使它们派生自其他指针类型,也可以始终取消引用它们。因此,如果INT8Uunsigned char(很有可能),则指针转换正常。

没有转换的 8 位就可以了:

INT8U Byte = 0x00U;
INT8U *NvM_SrcPtr = &Byte;         // ok - matching type
INT8U *src = NvM_SrcPtr;           // ok - matching type
*dst = (INT16U)(*src);             // ok - dereference with original type

带转换的 16 位很可能没问题:

INT16U Word = 0x0000U;
INT8U *NvM_SrcPtr = &Word;         // impl.def or special case
INT16U *src = (INT16U*)NvM_SrcPtr; // impl.def or special case
*dst = *src;                       // ok - dereference with original type

16 位 -> 8 位很可能没问题:

INT16U Word = 0x0000U;
INT8U *NvM_SrcPtr = &Word;         // impl.def or special case
INT8U *src = NvM_SrcPtr;           // ok - matching type
*dst = (INT16U)(*src);             // ok if INT8U is unsigned char

8 位 -> 16 位行:

INT8U Byte = 0x00U;
INT8U *NvM_SrcPtr = &Byte;         // ok - matching type
INT16U *src = (INT16U*)NvM_SrcPtr; // impl.def 
*dst = *src;                       // invalid - derefence with invalid type

至于指针对齐,这是您需要注意的事情。如果将指针转换为其他类型,然后未对齐,然后再转换回来,则可能有未定义的行为

最新更新