c - 在双缓冲区交换期间处理 UART ISR

标签 c buffer interrupt stm32 uart

我正在为 STM32F 处理器上的 UART 开发双缓冲区。以下示例在每次 UART ISR 运行时将数据添加到缓冲区。当主进程想要从中提取数据时,这个缓冲区就会被交换。

我担心可能出现的拐角情况。在我交换缓冲区之后但在我重置接收缓冲区计数之前,ISR 可能会触发。这意味着我的缓冲区大小和计数将不同步。

处理这种特殊情况的最佳方法是什么?

uint8_t rxBufferA[MAX_RX_BUFFER_SIZE];
uint8_t rxBufferB[MAX_RX_BUFFER_SIZE];
uint8_t *receivingBuffer;
uint8_t *processingBuffer;
volatile uint32_t rxBufferSize;

uart_isr() {
  receivingBuffer[rxBufferSize++] = RECEIVE_DATA_REGISTER
}


main() {

  receivingBuffer = &rxBufferA;
  processingBuffer = &rxBufferB;

  while(1) {

    if (rxBufferSize > 0) {
      uint32_t i = 0;
      uint8_t *ptemp = receivingBuffer;
      uint8_t bufferSize = 0;

      /* zero out processing buffer */
      memset(processingBuffer, 0, MAX_RX_BUFFER_SIZE);

      /* swap receiving and processing buffers */
      receivingBuffer = processingBuffer
      processingBuffer = ptemp;

      /* WHAT IF THE ISR FIRES HERE??? */         

      /* save off buffer size and reset count */
      bufferSize = rxBufferSize;
      rxBufferSize = 0;

      /* process rx data */
    } 
  }
}

最佳答案

你需要临界区。交换缓冲区时禁用用户中断。

顺便说一下,不需要归零

关于c - 在双缓冲区交换期间处理 UART ISR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56137758/

相关文章:

c - skb->data_len 、 skb->len 、 skb->mac_len 的值为 0 是否正确?

C程序不断关闭

python - 如何将数据发送到 wave.writeframesraw(data)

php - 可能 "undo"在 PHP 脚本中发送 HTTP header 和此类中间执行?

c - 为什么Linux内核在preempt_schedule_irq中启用中断?

JavaScript 方法执行中断

c - 使用指针在数组中存储字符

c - 如何用 C 读取 CSV 文件的第一个条目?

消费者-生产者。没有错误。有时工作。为什么?

c - AVR ATmega48的中断编程