STM32/STM8技术william hill官网
直播中

张宇

7年用户 1624经验值
私信 关注
[问答]

如何在STM32快速创建 FREERTOS和RTX工程呢?

如何在STM32快速创建 FREERTOS和RTX工程


回帖(7)

訾存贵

2018-9-11 09:45:17
1.png 2.png
安装 cubeMX  由于使用MX下载固件库速度那是不说了相当慢啊  所以下载 STM32CUBEF0固件库然后下图安装
3.png

安装之后  新建一个工程
选择STM32F072RBT6,PINOUT 勾选  FREERTOS和 USART
因为我们调试可能需要使用
点击软件上方  齿轮键生成  keil 工程  至此
MX基于 HAL的库 生成完毕



举报

訾存贵

2018-9-11 09:50:58
使用MDK 打开工程
从上到下 的组依次为  OS 的C文件
.s 启动文件
用户文件
HAL库文件
CMSIS中间件文件
其中 在 第一组中的 cmsis_os.c 中实现了  cmsis_os  到FREERTOS 的中间层转换   稍后会讨论其中一处代码
4.png
接下来  添加自己的代码  首先添加 072 上面LED吧  板子不在身边  记得是PA5 控制
先看看  main.c 的 64 到 105行

  1. int main(void)
  2. {

  3.   /* USER CODE BEGIN 1 */

  4.   /* USER CODE END 1 */

  5.   /* MCU Configuration----------------------------------------------------------*/

  6.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  7.   HAL_Init();

  8.   /* Configure the system clock */
  9.   SystemClock_Config();

  10.   /* Initialize all configured peripherals */
  11.   MX_GPIO_Init();
  12.   MX_USART2_UART_Init();

  13.   /* USER CODE BEGIN 2 */

  14.   /* USER CODE END 2 */

  15.   /* Init code generated for FreeRTOS */
  16.   /* Create Start thread */
  17.   osThreadDef(USER_Thread, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  18.   osThreadCreate (osThread(USER_Thread), NULL);

  19.   /* Start scheduler */
  20.   osKernelStart(NULL, NULL);

  21.   /* We should never get here as control is now taken by the scheduler */

  22.   /* USER CODE BEGIN 3 */
  23.   /* Infinite loop */
  24.   while (1)
  25.   {

  26.   }
  27.   /* USER CODE END 3 */

  28. }
举报

訾存贵

2018-9-11 09:52:40
mian函数  C代码的入口  初始化一些硬件后
  osThreadDef(USER_Thread, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  osThreadCreate (osThread(USER_Thread), NULL);
  /* Start scheduler */
  osKernelStart(NULL, NULL);
定义了一个 线程 USER_Thread 然后启动OS  
注意 osThreadDef  是一个宏  定义一个用于描述  线程的结构体  并不是执行函数
宏的第二项参数 StartThread 为线程 入口函数地址。

  1. /* USER CODE BEGIN 4 */
  2. void Nucleo_072_Led(const void *par);
  3. /* USER CODE END 4 */

  4. static void StartThread(void const * argument)
  5. {

  6.   /* USER CODE BEGIN 5 */
  7.   osThreadDef(LED_Thread, Nucleo_072_Led, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  8.   osThreadCreate (osThread(LED_Thread), NULL);
  9.   /* Infinite loop */
  10.   for(;;)
  11.   {
  12.     osDelay(1);
  13.   }

  14.   /* USER CODE END 5 */

  15. }


至此mian函数的工作结束了 OS将转向 就绪线程并永不返回  也就是执行StartThread  


修改  StartThrea函数 如下
举报

訾存贵

2018-9-11 09:56:01
添加一个 LED 函数
  1. void Nucleo_072_Led(const void *par)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStruct;
  4.   __GPIOA_CLK_ENABLE();
  5.         
  6.            GPIO_InitStruct.Pin = GPIO_PIN_5;
  7.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  8.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  9.     GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

  10.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  11.         
  12.         for(;;)
  13.         {
  14.                 GPIOA->ODR^=GPIO_PIN_5;// PA5取反 LED闪烁
  15.                 osDelay(500);
  16.         }

  17. }

到这里可以编译下载到板子上运行 观察现象了
下面创建 RXT 的工程  新建一个工程  
勾选 如下选项
5.png
红框 不要添加  不知为何  楼主添加 MDK的 startup 编译通不过
F4 的工程没有包含  HAL  接下来 需要自行添加HAL 库
把原来的 main.c 复制一份更名为  rtx_main.c
6.png
文件添加完毕
接下来定义 头文件目录和 系统宏

7.png
修改 rtx_main.c  下面两处需要修改
举报

訾存贵

2018-9-11 09:59:24
  1.   {
  2.   osThreadDef( StartThread, osPriorityNormal, 0, 0);
  3.   osThreadCreate (osThread(StartThread), NULL);
  4.         }
  5. osThreadDef( Nucleo_072_Led, osPriorityNormal, 0, 0);
  6.   osThreadCreate (osThread(Nucleo_072_Led), NULL);

不知为何  ST写的 中间件和 MDK的 接口有一点差距  所以 创建线程的地方需要如上修改
修改 stm32f0xx_hal_conf.h
添加 图示内容  不出意外  下面 将可以直接编译了!
8.png
写的有些多了  本来想 继续写 RTOS 基于串口的  应用  太长了 下次发帖写了
下面提出一个讨论 MX 创建的  工程 FREERTOS 中 cmsis_os.c 中 创建一个信号量  
osSemaphoreCreate参数 count 直接
传递给 xSemaphoreCreateCounting的两个形参  
9.png
举报

訾存贵

2018-9-11 10:00:19
  1. #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )

该宏创建一个 数值型信号量 第一个参数是 信号量最大数值  第二个则为  初始化值
基于串口使用信号量  那么需要如下要求
假设 usart_sem 为串口使用的信号量
每收到一个数据 usart_sem ++  缓冲 1024字节
需要数据的线程 osSemaphoreWait(usart_sem ); 当有数据时 线程被激活  获取数据
如此我们知道 这个信号量的 最大值应为1024
可是使用 ST 的cmsis_os osSemaphoreCreate 创建一个信号亮 osSemaphoreCreate(0,1024);
会出现这样的问题 !  此信号量 被赋予初值1024  意味着 这个信号量将可以被osSemaphoreWait 1024次
显然这不是我们想要
通常  我们需要的数值型信号量  最大值可以很大  但是初值 基本为0,或1
举报

申换换

2018-9-11 10:00:33
cube创建 MDK编辑是最快的
举报

更多回帖

发帖
×
20
完善资料,
赚取积分