简体   繁体   English

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

[英]Is it ok to store an 8- or 16-bit value to a 16-bit aligned buffer in this code?

I would like to save some value (8 or 16 bits) pointed by 8-bit pointer to a 16-bit aligned buffer. 我想保存一些由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-bit value - Is it ok to save 16-bit value which is casted when parameterized in 8-bit pointer (alignment violation)? 16位值-是否可以保存在8位指针中进行参数化(违反对齐)时强制转换的16位值? The final destination is a 16-bit buffer, it will be casted back to 16-bit alignment. 最终目标是16位缓冲区,它将被强制转换为16位对齐方式。 is it fine? 可以吗

  2. 8-bit value - As far as I know it should be fine with the code below. 8位值-据我所知,使用下面的代码应该可以。 But any suggestion in coding a better way? 但是在编码方面有什么建议吗?

EDIT 1. 编辑1。

the NvM_SrcPtr pointer parameter is passed something like this. 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:%d\n",GX);
    printf("%d\n",&GX);
    for(i=0;i<8;i++){
        printf("Bin:%d\n",GX&0b1<<i);
    }
    /*Pass INT8U to INT16U */
    unsigned __int16 *DDC;
    DDC=(unsigned __int16*)&GX;

    printf("Value:%d\n",*DDC);
    printf("%d\n",DDC);
    /*Clearly Address is same but printf may be diff*/
    for(i=0;i<8;i++){
        printf("Bin:%d\n",(*DDC)&0b1<<i);
    }
    for(i=8;i<16;i++){
        printf("Bin2:%d\n",(*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;
}

General rule is that you can dereference pointer only with correct type. 一般规则是,只能使用正确的类型取消引用指针。 You can convert pointer to other types, but if you want to dereference it, you need to convert it back to original type. 您可以将指针转换为其他类型,但是如果要取消引用它,则需要将其转换回原始类型。

These pointer conversions are implementation defined . 这些指针转换是实现定义的 This means that different pointers can have different presentations on some systems, and you should read the compiler manual on how these work on your system. 这意味着不同的指针在某些系统上可能具有不同的表示形式,因此您应该阅读编译器手册,以了解它们如何在系统上工作。 On typical modern system pointers usually use same representation and pointer conversions just work. 在典型的现代系统上,指针通常使用相同的表示形式,并且指针转换才起作用。

However, yours may be special case. 但是,您的情况可能特殊。 You see character type pointers are a special exception in C standard: they are guaranteed to have representation that is convertible to other pointer types, and they can be always dereferenced even if they were derived from other pointer types. 您会看到字符类型指针是C标准中的一个特殊例外:保证它们具有可转换为其他指针类型的表示形式,并且即使它们是从其他指针类型派生的,也可以始终取消引用它们。 So, if INT8U is unsigned char (which is very likely), your pointer conversions are fine. 因此,如果INT8Uunsigned char (很有可能),则指针转换就可以了。

8-bit with no conversions is fine: 没有转换的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-bit with conversions is most likely fine: 具有转换的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-bit -> 8-bit is most likely fine: 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-bit -> 16-bit is not fine: 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

As for the pointer alignment, this is something that you need to take care of. 至于指针对齐,这是您需要注意的事情。 If you convert pointer to other type, then misalign it, and convert it back, you may have undefined behaviour . 如果将指针转换为其他类型,然后将其未对齐,然后再转换回,则可能具有未定义的行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM