裸机开发最后的救赎
目录
1 开篇
又滚回windows了,真香
2 一个最简单的工程
2.1 你需要 STM32CubeMX 这个神器
为了操作方便–我买了一个 stm32nucleo-f103
2.2 通过Board Selector 新建一个工程
有这个小板子的好处是可以通过用它的模版工程
2.2.1 找到对应工程
2.2.2 设置系统时钟
这里我习惯(其实也没有习惯–菜鸟哪有习惯)把系统时钟设置到最高
2.2.3 找到 FREETROS 激活它
2.2.4 更换系统的时钟源
3 进入任务
到此,生成 keil5 工程,测试一下能不能编译下载
3.1 新建一个任务
新建一个任务 myTask_LED 在这里,我调整了 defaultTask 的 Priority 级别
在板子上有个灯
在 Func_LED 中添加对 LED的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| /** * @brief Function implementing the myTask_LED thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_Func_LED */ void Func_LED(void const * argument) { /* USER CODE BEGIN Func_LED */ /* Infinite loop */ for(;;) { //osDelay(50); vTaskDelay(100); HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); //osDelay(50); vTaskDelay(100); HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET); } /* USER CODE END Func_LED */ }
|
3.2 把 stlink 的串口用起来
3.2.1 覆盖串口输出函数
由于 printf 最终是调用 fputc 输出数据,fputc是一个弱引用(weak)函数,覆写即可重定向printf
1 2 3 4
| int fputc(int ch, FILE *f) { HAL_USART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); return ch; }
|
3.2.2 串口输出测试
1 2
| /* Infinite loop */ printf("UART Transmit\r\n");
|
到这步正常输出了
4 添加一个串口服务
4.1 打开串口的接收中断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 这里只有一位数据做缓存 // 这里大量发送数据会有丢数据,这个没找到问题再哪里 uint8_t aRxBuffer;
// 在 main 配置完成后添加 /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1); /* USER CODE END 2 */
// 在下面添加数据处理函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART2) { HAL_UART_Transmit(&huart2, (uint8_t *)&aRxBuffer, 1,0xFFFF); HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1); } }
|
这样串口算是工作起来了
5 任务的挂起和恢复
到这里算是要精细话的操作 freertos 了,这边就比较的陌生。
找到一个资料,FreeRTOS任务状态信息查询
为什么要找它,我在这会先依靠cubeMX来管理任务,但控制任务需要任务句柄,但是在现在的代码中,两个任务句柄的是类似匿名的,我的思路是先尝试把句柄查出来
上面画掉的部分是不需要的,为什么,这就要来读一读,直接生成的代码
1 2 3 4 5 6 7 8
| /* Create the thread(s) */ /* definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of myTask_LED */ osThreadDef(myTask_LED, Func_LED, osPriorityHigh, 0, 128); myTask_LEDHandle = osThreadCreate(osThread(myTask_LED), NULL);
|
我被教程给带偏了,一心想着,为什么没有配置 任务句柄,人家是在create的时候返回的。
1 2 3 4
| // 默认任务的句柄 defaultTaskHandle // LED 任务的句柄 myTask_LEDHandle
|
我觉得,我需要看看别人是怎么写得
下一页吧