linux_learn/docs/06-STM32与RTOS基础.md

9.6 KiB
Raw Permalink Blame History

06-STM32与RTOS基础

资料源: 1-程序源码_教程文档/ (野火系列)


一、这些资料是什么?

这部分是野火(EmbedFire)出品的 STM32 系列教程,在正点原子 ATK-DLRK356X 的资料盘中一并提供。虽然目标 MCU 是 STM32F4嵌入式通用概念适用于任何平台


二、核心教程清单

2.1 HAL 库基础

路径: [`1-程序源码_教程文档/1-[野火]《STM32 HAL库开发实战指南》/`](../%E5%8F%B6%E9%B9%8F%E7%A8%8B/A%E7%9B%98%EF%BC%88%E8%B5%84%E6%96%99%E7%9B%98%EF%BC%89/1-%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81_%E6%95%99%E7%A8%8B%E6%96%87%E6%A1%A3/1-%5B%E9%87%8E%E7%81%AB%5D%E3%80%8ASTM32%20HAL%E5%BA%93%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E3%80%8B/)

PDF: [`[野火EmbedFire]《STM32 HAL库开发实战指南——基于野火F4系列开发板》—20220913.pdf`](../%E5%8F%B6%E9%B9%8F%E7%A8%8B/A%E7%9B%98%EF%BC%88%E8%B5%84%E6%96%99%E7%9B%98%EF%BC%89/1-%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81_%E6%95%99%E7%A8%8B%E6%96%87%E6%A1%A3/1-%5B%E9%87%8E%E7%81%AB%5D%E3%80%8ASTM32%20HAL%E5%BA%93%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E3%80%8B/%5B%E9%87%8E%E7%81%ABEmbedFire%5D%E3%80%8ASTM32%20HAL%E5%BA%93%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E2%80%94%E2%80%94%E5%9F%BA%E4%BA%8E%E9%87%8E%E7%81%ABF4%E7%B3%BB%E5%88%97%E5%BC%80%E5%8F%91%E6%9D%BF%E3%80%8B%E2%80%9420220913.pdf)

→ 覆盖: GPIO / EXTI / USART / SPI / I2C / ADC / DAC / TIM / PWM / DMA / FSMC / SDIO

这对你有什么用?

虽然你用的是 Linux但理解外设的硬件工作原理很重要

  • STM32 的 SPI → 和 RK3568 的 SPI 本质上是一样的MISO/MOSI/SCK/CS
  • STM32 的 CAN → 原理和 RK3568 CAN 一样,差别在于 Linux 有 SocketCAN 抽象层
  • HAL 库的"结构体配置外设"模式 → 和 Linux DTS 的"设备树配置外设"思路一致,形式不同

2.2 RTOS 三部曲

RTOS PDF 核心概念
FreeRTOS [野火®]《FreeRTOS 内核实现与应用开发实战—基于STM32》.pdf 任务、队列、信号量、互斥锁、软件定时器、内存管理
uCOS-III [野火®]《uCOS-III内核实现与应用开发实战指南—基于STM32》.pdf 任务调度、时间管理、中断管理、就绪列表
RT-Thread [野火®]《RT-Thread 内核实现与应用开发实战—基于STM32》.pdf 线程、IPC、设备驱动框架、FinSH 控制台

为什么你应该至少学一种 RTOS

你的 CAN 协议栈最核心的部分(帧收发、超时管理、命令重发)就是 RTOS 经典问题的翻版:

  • CAN 帧接收 → RTOS 中断服务 + 队列
  • 命令超时重发 → RTOS 软件定时器
  • 收发线程分离 → RTOS 任务间通信
  • 信号表读写互斥 → RTOS 互斥锁

在 STM32 上理解这些概念,然后移植到 Linux pthread / timerfd / eventfd 上,会非常顺畅。

2.3 网络协议栈

路径: [`1-程序源码_教程文档/7-[野火]《LwIP应用开发实战指南》/`](../%E5%8F%B6%E9%B9%8F%E7%A8%8B/A%E7%9B%98%EF%BC%88%E8%B5%84%E6%96%99%E7%9B%98%EF%BC%89/1-%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81_%E6%95%99%E7%A8%8B%E6%96%87%E6%A1%A3/7-%5B%E9%87%8E%E7%81%AB%5D%E3%80%8ALwIP%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E3%80%8B/)
PDF: [`[野火]《LwIP应用开发实战指南—基于野火 STM32 全系列M4-M7开发板》.pdf`](../%E5%8F%B6%E9%B9%8F%E7%A8%8B/A%E7%9B%98%EF%BC%88%E8%B5%84%E6%96%99%E7%9B%98%EF%BC%89/1-%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81_%E6%95%99%E7%A8%8B%E6%96%87%E6%A1%A3/7-%5B%E9%87%8E%E7%81%AB%5D%E3%80%8ALwIP%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E3%80%8B/%5B%E9%87%8E%E7%81%AB%5D%E3%80%8ALwIP%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E2%80%94%E5%9F%BA%E4%BA%8E%E9%87%8E%E7%81%AB%20STM32%20%E5%85%A8%E7%B3%BB%E5%88%97%EF%BC%88M4-M7%EF%BC%89%E5%BC%80%E5%8F%91%E6%9D%BF%E3%80%8B.pdf)

→ 覆盖: TCP/IP 栈原理、socket API、HTTP/MQTT 应用、Wireshark 抓包分析

LwIP 是嵌入式 TCP/IP 实现。理解它有助于理解:

  • 你的 CAN 数据如果要上 MQTTTCP 层的重传/拥塞控制如何影响时效
  • Wireshark 抓包分析技能(对 CAN 调试同样适用——candump -l 生成的日志就是 CAN 的总线抓包)

2.4 其他指南

书籍 能学到什么
《RT-Thread 内核实现》 设备驱动框架——如何用 C 语言实现面向对象风格的驱动,类似 Linux 的 file_operations
《LiteOS开发实战》 华为物联网 OS了解轻量级 IPC (LiteIPC)
《emWin实战指南》 嵌入式 GUI可选了解
《电机应用开发实战指南》 BLDC/PMSM FOC 控制、编码器、电流采样

三、配套模块资料

路径: [`4-配套模块资料/`](../%E5%8F%B6%E9%B9%8F%E7%A8%8B/A%E7%9B%98%EF%BC%88%E8%B5%84%E6%96%99%E7%9B%98%EF%BC%89/4-%E9%85%8D%E5%A5%97%E6%A8%A1%E5%9D%97%E8%B5%84%E6%96%99/)

四、学习路径建议

路径A快速补课定向学

1. 只看 FreeRTOS 一本 (1周) → 会任务/队列/定时器
2. 写一个 "FreeRTOS 任务 + 软件定时器 + 队列" 的小项目
3. 回到 RK3568用 pthread + timerfd 复现相同逻辑

路径B系统学2-3个月

1. HAL库基础 (2周) → 裸机外设
2. FreeRTOS (3周) → 任务调度 + IPC
3. RT-Thread (2周) → 设备框架 + 驱动模型
4. LwIP (2周) → 网络协议栈
5. 电机开发 (2周) → 可选

五、STM32 与 Linux 的核心差异

概念 STM32 Linux
外设操作 直接读寄存器 GPIOA->ODR = 0x01 通过驱动文件 /sys/class/gpio/export
中断 NVIC + HAL_GPIO_EXTI_Callback 内核中断 → 下半部(tasklet/workqueue) → poll() / select()
定时器 HAL_TIM_Base_Start_IT timerfd_create / setitimer
任务调度 FreeRTOS vTaskDelay sched_yield / usleep / timerfd
日志 printf 到串口 syslog / printf 到 stdout
编译 Keil/IAR GCC 交叉编译

最大的思维转变Linux 里你不要直接操作寄存器——你通过文件描述符和标准 API 操作"服务"。