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);
我希望这可以帮助其他人使用这种驱动程序:)
我正在尝试使用 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);
我希望这可以帮助其他人使用这种驱动程序:)