1、RTOS工程建立
由于未使用过STM32CubeMX,这次尝试使用Cube进行新建工程。
1、时钟树配置
时钟树较为基础,直接配置。
配置后发现锁相环PLLQ无法设置,为使USB OTG FS 时钟频率 为48Mhz,Q = 2;不知道为何无法配置,到代码中再看什么情况:应可修改为2。
2、Project Manager
Thread-safe Setting:启用或禁用线程安全的 C 库支持。主要影响的是 libc
(如 malloc
、printf
、errno
等)是否能安全地在多线程中使用。
Enable multi-threaded support(是否启用多线程支持):
✔ 勾选:开启线程安全支持,会自动让 newlib
(如 printf
、malloc
)在多线程环境(RTOS 下)中安全使用。
✖ 不勾选:默认这些库函数不加锁,多线程中使用可能导致崩溃或数据错乱。
Thread-safe Locking Strategy(用于配置如何在多线程下保护 C 库的访问方式):
选项 | 说明 |
---|---|
Default | 自动根据你是否启用了 RTOS(如 FreeRTOS)来选择合适的锁策略(通常是使用 RTOS 的 mutex ) |
User-defined | 你自己定义一组 __retarget_lock_...() 函数,来自定义锁行为(需要高级用户处理) |
None | 不使用任何线程锁(不建议在多线程环境中使用) |
为什么printf
、malloc等函数在多线程调用时会出现问题呢?其他普通函数不会出现问题?
在一个函数里只用了局部变量或只读数据,没有访问共享资源,比如全局变量、堆空间、硬件寄存器等,他是线程安全的,因为每个线程调用这个函数时,操作的是自己栈上的副本变量,互不干扰。
但标准库函数,比如 printf()
、malloc()
就不是这么简单的:它们通常共享全局资源,例如:
函数 | 共享资源 | 多线程风险 |
---|---|---|
printf() | 全局输出缓冲区 | 输出混杂,乱码 |
malloc() / free() | 全局堆内存 | 内存碎片、越界、崩溃 |
strtok() | 静态指针 | 分词混乱 |
errno | 全局错误码 | 错误码被覆盖 |
这些函数会修改/依赖全局变量或共享的内部结构。当多个线程同时调用它们时,没有加锁保护的话,就会互相干扰。也就是说比如
// 线程 Aprintf("Hello A\n");
// 线程 Bprintf("Hello B\n");
此时的输出可能会变为Hello Hello B
A
生成时报错:
HAL_Init和RTOS同时使用了systick作为时基,可能导致
-
FreeRTOS 的调度器无法正常启动
-
HAL_Delay()
行为异常 -
HAL_GetTick()
获取时间出错
将HAL库时基修改为TIM7或其他定时器。
2、代码编译
编译后报错,发现是中文路径或其他原因导致的文件生成不全:
重新生成后编译成功。