本帖最后由 slotg 于 2019-12-20 14:22 编辑
工作上的编程一直都是使用标准库因此没有去留意过 STM32Cube 固件库的用法,这次的资料下载活动中下载了 AN4735_适用于STM32F0系列的STM32Cube固件例程.pdf 这份文档,因此也就认真的阅读了内容,这份文档描述了固件库里面有那些 HAL 库与 LL 库的例程,针对 ST 官方的不同开发板各有不同的例程可供参考:
然而在STM32中文官网下载的 STM32CubeF0_软件开发包.zip 似乎是破损解不开的,并且这个固件库的版本是 v1.10.0,而在英文官网里固件库版本已经是 v1.11.0 了,因此我从英文官网下载了最新的固件库。固件库里面的 STM32CubeF0GettingStarted.pdf 说明文档列表了这个版本有多少个例程:
新的固件库就会有比较多的例程,v1.11.0 就比 v1.10.0 多了几个,只是目前看起来针对 STM32F072RB-Nucleo 开发板的例程是比较丰富些,而且也只有这块开发板有 LL 库的例程。我手上有一块 STM32F030R8-Nucleo 开发板,因此来看看有什么有趣的例程可以跑跑的。
在固件库的 Applications 文件夹里面有一个 FreeRTOS 的例程 FreeRTOS_ThreadCreation,这是一个线程创建的例程,我直接编译后下载到 STM32F030R8-Nucleo 开发板后运行就看到板载的 LD2 开始闪烁。对于 FreeRTOS 我并不熟悉,因此参考了活动资料下载的 UM1722_如何使用STM32Cube中的实时作业系统.pdf 文档与其他 FreeRTOS 相关文档来了解一下这个例程的功能。
main 回圈:
- int main(void)
- {
- /* STM32F0xx HAL library initialization:
- - Configure the Flash prefetch
- - Systick timer is configured by default as source of time base, but user
- can eventually implement his proper time base source (a general purpose
- timer for example or other time source), keeping in mind that Time base
- duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
- handled in milliseconds basis.
- - Low Level Initialization
- */
- HAL_Init();
- /* Configure the System clock to 48 MHz */
- SystemClock_Config();
- /* Initialize LED */
- BSP_LED_Init(LED2);
-
- /* Thread 1 definition */
- osThreadDef(THREAD_1, LED_Thread1, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
-
- /* Thread 2 definition */
- osThreadDef(THREAD_2, LED_Thread2, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
-
- /* Start thread 1 */
- LEDThread1Handle = osThreadCreate(osThread(THREAD_1), NULL);
- /* Start thread 2 */
- LEDThread2Handle = osThreadCreate(osThread(THREAD_2), NULL);
- /* Set thread 2 in suspend state */
- osThreadSuspend(LEDThread2Handle);
- /* Start scheduler */
- osKernelStart();
- /* We should never get here as control is now taken by the scheduler */
- for (;;);
- }
线程1:
- static void LED_Thread1(void const *argument)
- {
- uint32_t count = 0;
- (void) argument;
- for (;;)
- {
- count = osKernelSysTick() + 5000;
- /* Turn on LED2 */
- BSP_LED_On(LED2);
- while (count > osKernelSysTick())
- {
- /* Toggle LED2 every 250ms*/
- osDelay(250);
- BSP_LED_Toggle(LED2);
- }
- /* Turn off LED2 */
- BSP_LED_Off(LED2);
- /* Resume Thread 2 */
- osThreadResume(LEDThread2Handle);
- /* Suspend Thread 1 : current thread */
- osThreadSuspend(LEDThread1Handle);
- }
- }
线程2:
- static void LED_Thread2(void const *argument)
- {
- uint32_t count;
- (void) argument;
- for (;;)
- {
- count = osKernelSysTick() + 10000;
- /* Turn on LED2 */
- BSP_LED_On(LED2);
- while (count > osKernelSysTick())
- {
- /* Toggle LED2 every 500ms*/
- osDelay(500);
- BSP_LED_Toggle(LED2);
- }
- /* Turn off LED2 */
- BSP_LED_Off(LED2);
- /* Resume Thread 1 */
- osThreadResume(LEDThread1Handle);
- /* Suspend Thread2 : current thread */
- osThreadSuspend(LEDThread2Handle);
- }
- }
在主回圈创建了 2 个线程,先挂起线程2 后启动 RTOS 内核,线程1 在 5 秒的时间内每 250ms 翻转板载 LD2 状态,5 秒后线程1 挂起,线程2 恢复。而线程2 在 10 秒的时间内每 500ms 翻转板载 LD2 状态,10 秒后线程2 挂起,线程1 恢复。所以板载 LD2 就是快闪 5 秒后慢闪 10 秒,一直持续这样的动作流程。
在中文官网 FreeRTOS 的其他参考文档:
STM32 FreeRTOS培训:FreeRTOS基本原理介绍.pdf
https://www.stmcu.com.cn/Designresource/design_resource_detail/file/502001/lang/ZH/token/a72dd7aa642eab37248f87b44aaa276e
FreeRTOS_ST April Training.pdf
https://www.stmcu.com.cn/Designresource/design_resource_detail/file/502002/lang/ZH/token/dbdd236cc947196c16e659444efb9352
|