访问缓冲区总是 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刷新缓冲区的缓存版本。