访问缓冲区总是 returns 0,尽管实际值在 Atmel Studio 调试器中可见
Accessing a buffer always returns 0, although the actual value is visible in Atmel Studio Debugger
这是一个非常具体的问题,可能没有直接的答案,因此欢迎任何想法。
背景:
我正在 Atmel Studio 中使用 C 为 SAME70Q21 微处理器开发应用程序。该应用程序通过 USB 与主机 PC 交换数据。我使用 Atmel Studio 提供的 ASF 驱动程序来构建特定于供应商的 USB 设备,并编写了基于 WinUSB 的自定义驱动程序。
当从主机接收数据包时,接收器模块使用 DMA 将接收到的数据包复制到我的程序在启动接收器时指定的缓冲区。之后,调用中断。在这个中断中,我的程序应该将消息从缓冲区复制到消息堆栈,然后重新启动接收器。
问题:
现在,无论何时接收到消息,程序都会像缓冲区没有内容一样工作。从缓冲区 returns 零复制消息。与缓冲区(buffer[0]++、buffer[0]+4 或其他)交互会导致缓冲区内的寻址值跳转到 0。
我已经使用 Atmel Studio Debugger 观看了该程序。缓冲区包含接收到的消息,但显然微控制器无法访问它。该消息在内存中也可见(见图)。我还尝试使用指针和 memcpy 直接访问缓冲区地址,但没有任何结果。当我使用调试器更改缓冲区中的单个值时,整个缓冲区都可用,但只能在收到下一条消息之前使用。
中断处理程序代码:
void main_vendor_bulk_out_received(udd_ep_status_t status,
iram_size_t nb_transfered, udd_ep_id_t ep)
{
UNUSED(ep);
if (UDD_EP_TRANSFER_OK != status) {
return; // Error in USB module, abort without restarting the receiver
}
//signal main loop that a message has been received
bulk_rx_received = true;
//this was a test, copy first value from the buffer bulk_rx_buf to a local var, this always returns 0
uint8_t x = bulk_rx_buf[0];
//this is supposed to copy the data to the message stack, but the copy will always contain only zeroes
memcpy(message_stack[message_stack_pointer], bulk_rx_buf, BULK_BUFFER_SIZE);
message_stack_pointer++;
if(message_stack_pointer == 32){
message_stack_pointer = 0;
}
//restart the USB endpoint service, contains pointer to buffer, its size, pointer to callback
udi_vendor_bulk_out_run(bulk_rx_buf, BULK_BUFFER_SIZE, main_vendor_bulk_out_received);
}
Picture of the memory viewer, the received message is "RUNA"
我找到了解决方案:
这是一个错误,因为我对 ARM 类型的 MCU 缺乏经验。
DMA将USB数据拷贝到RAM后,需要手动刷新处理器的Cache。 DMA 不触发刷新事件。
使用 ASF 时,使用
SCB_InvalidateDCache_by_Addr(BULK_BUFER_ADRESS, BULK_BUFFER_SIZE);
强制MCU刷新缓冲区的缓存版本。
这是一个非常具体的问题,可能没有直接的答案,因此欢迎任何想法。
背景: 我正在 Atmel Studio 中使用 C 为 SAME70Q21 微处理器开发应用程序。该应用程序通过 USB 与主机 PC 交换数据。我使用 Atmel Studio 提供的 ASF 驱动程序来构建特定于供应商的 USB 设备,并编写了基于 WinUSB 的自定义驱动程序。 当从主机接收数据包时,接收器模块使用 DMA 将接收到的数据包复制到我的程序在启动接收器时指定的缓冲区。之后,调用中断。在这个中断中,我的程序应该将消息从缓冲区复制到消息堆栈,然后重新启动接收器。
问题: 现在,无论何时接收到消息,程序都会像缓冲区没有内容一样工作。从缓冲区 returns 零复制消息。与缓冲区(buffer[0]++、buffer[0]+4 或其他)交互会导致缓冲区内的寻址值跳转到 0。
我已经使用 Atmel Studio Debugger 观看了该程序。缓冲区包含接收到的消息,但显然微控制器无法访问它。该消息在内存中也可见(见图)。我还尝试使用指针和 memcpy 直接访问缓冲区地址,但没有任何结果。当我使用调试器更改缓冲区中的单个值时,整个缓冲区都可用,但只能在收到下一条消息之前使用。
中断处理程序代码:
void main_vendor_bulk_out_received(udd_ep_status_t status,
iram_size_t nb_transfered, udd_ep_id_t ep)
{
UNUSED(ep);
if (UDD_EP_TRANSFER_OK != status) {
return; // Error in USB module, abort without restarting the receiver
}
//signal main loop that a message has been received
bulk_rx_received = true;
//this was a test, copy first value from the buffer bulk_rx_buf to a local var, this always returns 0
uint8_t x = bulk_rx_buf[0];
//this is supposed to copy the data to the message stack, but the copy will always contain only zeroes
memcpy(message_stack[message_stack_pointer], bulk_rx_buf, BULK_BUFFER_SIZE);
message_stack_pointer++;
if(message_stack_pointer == 32){
message_stack_pointer = 0;
}
//restart the USB endpoint service, contains pointer to buffer, its size, pointer to callback
udi_vendor_bulk_out_run(bulk_rx_buf, BULK_BUFFER_SIZE, main_vendor_bulk_out_received);
}
Picture of the memory viewer, the received message is "RUNA"
我找到了解决方案: 这是一个错误,因为我对 ARM 类型的 MCU 缺乏经验。 DMA将USB数据拷贝到RAM后,需要手动刷新处理器的Cache。 DMA 不触发刷新事件。
使用 ASF 时,使用
SCB_InvalidateDCache_by_Addr(BULK_BUFER_ADRESS, BULK_BUFFER_SIZE);
强制MCU刷新缓冲区的缓存版本。