uart-serial-baremetal

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

UART Serial (Bare-Metal)

UART串行通信(裸机)

Purpose

用途

Implement UART/USART for debug console and device communication: baud rate calculation, 8N1 framing, polling and interrupt-driven I/O, overrun handling, and optional DMA basics.
为调试控制台和设备通信实现UART/USART:包括波特率计算、8N1帧格式、轮询与中断驱动I/O、溢出处理,以及可选的DMA基础功能。

When to Use

适用场景

  • First
    printf
    /log output on new hardware
  • Serial protocol to sensor/module
  • Replacing blocking HAL_UART with minimal driver
  • Fixing garbled or missing characters
  • 在新硬件上实现首个
    printf
    /日志输出
  • 与传感器/模块的串行协议通信
  • 用轻量驱动替代阻塞式HAL_UART
  • 修复乱码或丢字符问题

Workflow

实现流程

1. Baud rate (STM32)

1. 波特率配置(STM32)

BRR = pclk / (16 * baud)   /* oversampling by 16 — check RM for USART */
c
void usart2_init(uint32_t pclk, uint32_t baud) {
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
    /* GPIO PA2/PA3 AF — see gpio-baremetal */

    USART2->BRR = pclk / baud;  /* simplified — RM has fractional formula */
    USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}
Verify
pclk
from actual clock tree (
SystemCoreClock
, APB prescaler).
BRR = pclk / (16 * baud)   /* oversampling by 16 — check RM for USART */
c
void usart2_init(uint32_t pclk, uint32_t baud) {
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
    /* GPIO PA2/PA3 AF — see gpio-baremetal */

    USART2->BRR = pclk / baud;  /* simplified — RM has fractional formula */
    USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
}
从实际时钟树(
SystemCoreClock
、APB预分频器)确认
pclk
的值。

2. Polling TX/RX

2. 轮询式TX/RX

c
void uart_putc(USART_TypeDef *u, char c) {
    while (!(u->SR & USART_SR_TXE))
        ;
    u->DR = (uint8_t)c;
}

char uart_getc(USART_TypeDef *u) {
    while (!(u->SR & USART_SR_RXNE))
        ;
    return (uint8_t)u->DR;
}
c
void uart_putc(USART_TypeDef *u, char c) {
    while (!(u->SR & USART_SR_TXE))
        ;
    u->DR = (uint8_t)c;
}

char uart_getc(USART_TypeDef *u) {
    while (!(u->SR & USART_SR_RXNE))
        ;
    return (uint8_t)u->DR;
}

3. Interrupt-driven RX ring buffer

3. 中断驱动的RX环形缓冲区

c
void USART2_IRQHandler(void) {
    if (USART2->SR & USART_SR_RXNE) {
        uint8_t b = USART2->DR;
        rb_push(&rx_rb, b);
    }
    if (USART2->SR & USART_SR_ORE) {
        (void)USART2->DR;  /* clear overrun — required on STM32 */
    }
}
c
void USART2_IRQHandler(void) {
    if (USART2->SR & USART_SR_RXNE) {
        uint8_t b = USART2->DR;
        rb_push(&rx_rb, b);
    }
    if (USART2->SR & USART_SR_ORE) {
        (void)USART2->DR;  /* clear overrun — required on STM32 */
    }
}

4. retarget
printf
(newlib)

4. 重定向
printf
(newlib)

c
int _write(int fd, char *ptr, int len) {
    (void)fd;
    for (int i = 0; i < len; i++)
        uart_putc(USART2, ptr[i]);
    return len;
}
Link with
--specs=nosys.specs
or provide full syscalls.
c
int _write(int fd, char *ptr, int len) {
    (void)fd;
    for (int i = 0; i < len; i++)
        uart_putc(USART2, ptr[i]);
    return len;
}
链接时使用
--specs=nosys.specs
,或提供完整的系统调用。

5. Agent usage

5. Agent使用方式

/uart-serial-baremetal Calculate USART BRR for 115200 at 84 MHz PCLK
/uart-serial-baremetal Calculate USART BRR for 115200 at 84 MHz PCLK

Common Problems

常见问题

SymptomCauseFix
Garbage charsWrong baud/PCLKRecompute BRR; check APB divider
Lost bytesORE not clearedRead DR on ORE; use IRQ + ringbuf
No outputTX pin not AFGPIO alternate function
printf
hangs
_write
missing
Implement retarget
症状原因解决方案
乱码波特率/PCLK错误重新计算BRR;检查APB分频器
丢字节未清除ORE标志发生ORE时读取DR;使用IRQ+环形缓冲区
无输出TX引脚未配置为AF设置GPIO复用功能
printf
挂起
缺少
_write
实现
完成重定向实现

Related Skills

相关技能

  • skills/baremetal/gpio-baremetal
    — TX/RX pin mux
  • skills/baremetal/interrupts-and-exceptions-baremetal
    — USART IRQ
  • skills/baremetal/dma-baremetal
    — UART RX DMA
  • skills/embedded/openocd-jtag
    — semihosting alternative
  • skills/baremetal/gpio-baremetal
    — TX/RX引脚复用配置
  • skills/baremetal/interrupts-and-exceptions-baremetal
    — USART中断
  • skills/baremetal/dma-baremetal
    — UART RX DMA
  • skills/embedded/openocd-jtag
    — semihosting替代方案