HAL_BUSY xảy ra khi nào trong UART DMA?

Giải thích lỗi HAL_BUSY khi gọi HAL_UART_Transmit_DMA() trong lúc UART/DMA vẫn đang truyền dữ liệu trước đó.

2 phút đọc
STM32 / DMA cover

Ghi chú nhanh

HAL_BUSY thường xảy ra khi bạn gọi HAL_UART_Transmit_DMA() trong lúc UART/DMA vẫn đang bận truyền dữ liệu trước đó.

Ví dụ sai rất quen thuộc:

HAL_UART_Transmit_DMA(&huart1, buf1, len1);
HAL_UART_Transmit_DMA(&huart1, buf2, len2); // có thể trả về HAL_BUSY

DMA không phải là queue. Nó không tự nhớ “gửi xong buf1 thì gửi tiếp buf2”. Nó chỉ nhận một vùng nhớ, truyền vùng đó, rồi kết thúc.

Vì sao lỗi này hay đánh lừa người mới?

Vì tên hàm có chữ DMA, nhiều người kỳ vọng rằng “đã dùng DMA thì không blocking, vậy cứ gọi thoải mái”.

Thực tế, DMA chỉ giúp CPU không phải tự đẩy từng byte ra UART. Nhưng trạng thái truyền vẫn cần được quản lý.

Nếu lần truyền trước chưa xong, lần gọi mới có thể bị từ chối bằng HAL_BUSY.

Một tình huống thực tế

Bạn redirect printf() sang DMA:

int _write(int file, char *ptr, int len)
{
    HAL_UART_Transmit_DMA(&huart1, (uint8_t *)ptr, len);
    return len;
}

Nhìn qua có vẻ rất thông minh: printf() không còn blocking nữa.

Nhưng nếu hai dòng log đi xuống gần nhau:

printf("ADC start");
printf("ADC value = %d", value);

Dòng thứ hai có thể gọi DMA khi dòng thứ nhất vẫn chưa truyền xong. Nếu không kiểm tra return value, log sẽ mất âm thầm. Đây là loại bug rất khó chịu: firmware vẫn chạy, chỉ có log là “mất trí nhớ”.

Cách xử lý đúng hơn

Thay vì gọi DMA trực tiếp cho từng lần printf(), nên dùng kiến trúc:

printf()
  -> _write()
  -> ghi vào Ring Buffer
  -> nếu DMA rảnh thì start transmit
  -> Tx complete callback gửi chunk tiếp theo

Khi đó, DMA chỉ truyền một chunk tại một thời điểm. Các log mới được giữ trong buffer chờ lượt.

Checklist khi gặp HAL_BUSY

Cách nhớ

DMA là người vận chuyển, không phải hàng đợi.
Muốn xếp hàng log → cần Ring Buffer hoặc queue.

Bài liên quan nên đọc tiếp

Thấy nội dung này hữu ích?

Lưu lại hoặc chia sẻ cho người cũng đang học firmware, BIOS/UEFI và embedded systems.

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.