C CORTEX-M4:如何访问 uint8_t 由 UART (vcom) 作为 int32_t 发送的数据

C CORTEX-M4: How to access uint8_t data sent by UART (vcom) as int32_t

我正在尝试使用 LPCOpen 提供的 VCOM 示例测试我的 LPC4370 cortex-m4 micro(LPC Link2 评估板)和我的计算机之间的通信。 我只是想从 matlab 发送数据,将它们复制到 int32_t 数组中,然后将它们发送回主机。

这是我试过的。 来自 Matlab:

fwrite(serial_object,raw_data,'int32');

C部分,我只总结了相关代码:

#define RAW_SIZE      1024
unsigned char uint8_t;
typedef int int32_t;

// My Buffer
__DATA(RAM) int32_t buffer_rt_s[RAW_SIZE] = {0};

// VCOM-UART rx buffer
static uint8_t g_rxBuff[4*RAW_SIZE];

int i;

int main()
{
  vcom_bread((uint8_t*)&g_rxBuff[0], 4*RAW_SIZE);

    for(i=0; i < RAW_SIZE; i=i+1)
    {
     buffer_rt_s[i]=(int32_t*)(&g_rxBuff[0]+i*4);
    }
    vcom_write((uint8_t*)&buffer_rt_s[0], 4*RAW_SIZE);
}

我想在这里做什么

for(i=0; i < RAW_SIZE; i=i+1)
{
buffer_rt_s[i]=(int32_t*)(&g_rxBuff[0]+i*4);
}

是每次迭代访问接收缓冲区前进4个字节。 所以我要地址

(&g_rxBuff[0]+i*4)

然后对于该位置的内容,指定我想要一个 32 位数字(即 4 个字节):

(int32_t*)

Results form Matlab plot. 对我来说,这很像是我在读取接收缓冲区的地址而不是内容。 请注意,我已经在 matlab 中使用了 vcom 函数,而且我确信它们可以正常工作。

如有任何帮助,我们将不胜感激。 安德里亚

这里有很多不同的问题。

  • 通过 UART 或其他数据通信发送的任何数据协议都称为 "network endianess"。这是通信协议使用的 MS/LS 字节顺序。按照传统,这几乎总是大端。

    您的 PC 几乎可以肯定是小端。 Cortex M4 同时支持 big 和 little 但通常默认为 little endian。 LPC4370就是这种情况。

    在做任何其他事情之前,你需要弄清楚字节是如何存储在内存和协议中的。

  • g_rxBuff不一定分配在偶地址上,接收协议也不一定分配整数在偶地址上。这意味着通过 int32_t 访问它的内容可能会导致访问不对齐。

  • 通过 int32_t 指针访问来访问 uint8_t 数组始终是一个严格的别名违规错误。 (你可以反过来做,作为一个特例。)参见 What is the strict aliasing rule?

为了避免后两个问题,您可以在特定地址分配内存,然后使用memcpy 硬拷贝所有内存。或者,使用一些 union 技巧:

typedef union
{
  uint8_t u8 [4];
  int32_t i32;
} i32_t;

所以,在遵循@Lundin 的提示后,我post 在这里提供了对我有用的解决方案。 这是我的联合声明:这确保数据是 4 字节对齐的。

#define RAW_SIZE      64

/* my nt32 buff */
__DATA(RAM) int32_t buffer_rt_s[RAW_SIZE] = {0};

union Buffer {
    uint8_t g_rxBuff[4*RAW_SIZE];
    int32_t g_rxBuff32[RAW_SIZE];
};

这是我对 LPCOpen USB Driver

的用法
/* Union init */
Buffer b;

/* read on byte at a time*/
vcom_bread(&(b.g_rxBuff[0]), 4*RAW_SIZE);

/* do something with the data */

buffer_rt_s[i]=b.g_rxBuff32[i];

/* write - note that this cast is legal */
vcom_write((uint8_t*)&buffer_rt_s[0], 4*RAW_SIZE);

我希望这可以帮助其他人使用这种驱动程序:)