1

我正在制作一台遥控机器,使用 pi pico 来驱动电机并读取一些传感器,并使用 raspberry pi 4 通过串行向 pi pico 发送命令并托管 Web 界面。

我正在从树莓派发送和接收命令,现在我坚持使用这段代码:

#include <string.h>

#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/irq.h"

#define UART_ID uart0
#define BAUD_RATE 19200
#define DATA_BITS 8
#define STOP_BITS 1
#define PARITY    UART_PARITY_NONE
#define UART_TX_PIN 0
#define UART_RX_PIN 1

static int chars_rxed = 0;

char uCommand[32] = {0, 0};

void on_uart_rx() {
    char tmp_string[] = {0, 0};
    while (uart_is_readable(UART_ID)) {
        uint8_t ch = uart_getc(UART_ID);
        tmp_string[0] = ch;
        strcat(uCommand, tmp_string);
        if(uart_is_writable(UART_ID)){
          uart_putc(UART_ID, '-');
          uart_puts(UART_ID, uCommand);
          uart_putc(UART_ID, '-');
        }
        chars_rxed++;
    }
}

int main(){

  uart_init(UART_ID, BAUD_RATE);

  gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
  gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
  uart_set_hw_flow(UART_ID, false, false);
  uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
  uart_set_fifo_enabled(UART_ID, false);

  int UART_IRQ = UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;

  irq_set_exclusive_handler(UART_IRQ, on_uart_rx);
  irq_set_enabled(UART_IRQ, true);
  uart_set_irq_enables(UART_ID, true, false);

  uart_puts(UART_ID, "\nOK\n");
    while (1){
        tight_loop_contents();
        if(uCommand[0] != 0){
          uart_putc(UART_ID, '/');
          uart_puts(UART_ID, uCommand);
          uart_putc(UART_ID, '/');
        }
      }
}

我的想法是在中断期间通过串行发送的命令并将其放在一个字符集中,然后解析它并在外部执行它。

尝试一下,我注意到它从来没有在 while 内输入 if 并且它没有完全“填充”“uCommand”字符集,但与发送的字符相比只有几个字符。

我希望我的问题不是题外话。

4

1 回答 1

1

您应该声明uCommand(和任何其他共享对象)volatile

while 循环正在等待uCommand[0] != 0变为真,但主线程不会修改uCommand[0],因此如果编译器“知道”它永远不可能为真,则编译器可以自由地“优化”掉整个代码块。

同样chars_rxed可能会因为您编写但从未阅读过而被优化掉。将其声明为 volatile 也可以防止这种情况发生。

明显冗余访问的优化通常仅在-O1设置或更高优化级别时发生。尽管无论如何您都应该在volatile这种情况下使用。

于 2021-08-13T14:41:50.967 回答