打印
[应用相关]

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

[复制链接]
3118|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
capturesthe|  楼主 | 2016-1-31 16:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
安装 cubeMX  由于使用MX下载固件库速度那是不说了相当慢啊  所以下载 STM32CUBEF0固件库然后下图安装




安装之后  新建一个工程 选择STM32F072RBT6

PINOUT 勾选  FREERTOS和 USART

因为我们调试可能需要使用

点击软件上方  齿轮键生成  keil 工程  至此

MX基于 HAL的库 生成完毕

使用MDK 打开工程
从上到下 的组依次为  OS 的C文件
.s 启动文件
用户文件
HAL库文件
CMSIS中间件文件

沙发
capturesthe|  楼主 | 2016-1-31 16:22 | 只看该作者
其中 在 第一组中的 cmsis_os.c 中实现了  cmsis_os  到FREERTOS 的中间层转换   稍后会讨论其中一处代码




接下来  添加自己的代码  首先添加 072 上面LED吧  板子不在身边  记得是PA5 控制

先看看  main.c 的 64 到 105行

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

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

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();

  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

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

  /* Start scheduler */
  osKernelStart(NULL, NULL);

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

  /* USER CODE BEGIN 3 */
  /* Infinite loop */
  while (1)
  {

  }
  /* USER CODE END 3 */

}


使用特权

评论回复
板凳
capturesthe|  楼主 | 2016-1-31 16:23 | 只看该作者
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 为线程 入口函数地址。


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


修改  StartThrea函数 如下

/* USER CODE BEGIN 4 */
void Nucleo_072_Led(const void *par);
/* USER CODE END 4 */

static void StartThread(void const * argument)
{

  /* USER CODE BEGIN 5 */
  osThreadDef(LED_Thread, Nucleo_072_Led, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
  osThreadCreate (osThread(LED_Thread), NULL);
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }

  /* USER CODE END 5 */

}
添加一个 LED 函数
void Nucleo_072_Led(const void *par)
{
        GPIO_InitTypeDef GPIO_InitStruct;
  __GPIOA_CLK_ENABLE();
        
           GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
        
        for(;;)
        {
                GPIOA->ODR^=GPIO_PIN_5;// PA5取反 LED闪烁
                osDelay(500);
        }

}


使用特权

评论回复
地板
capturesthe|  楼主 | 2016-1-31 16:24 | 只看该作者
到这里可以编译下载到板子上运行 观察现象了


下面创建 RXT 的工程  新建一个工程  

勾选 如下选项


红框 不要添加  不知为何  楼主添加 MDK的 startup 编译通不过
F4 的工程没有包含  HAL  接下来 需要自行添加HAL 库

把原来的 main.c 复制一份更名为  rtx_main.c



文件添加完毕

接下来定义 头文件目录和 系统宏





修改 rtx_main.c  下面两处需要修改

使用特权

评论回复
5
capturesthe|  楼主 | 2016-1-31 16:25 | 只看该作者
  {
  osThreadDef( StartThread, osPriorityNormal, 0, 0);
  osThreadCreate (osThread(StartThread), NULL);
        }





osThreadDef( Nucleo_072_Led, osPriorityNormal, 0, 0);
  osThreadCreate (osThread(Nucleo_072_Led), NULL);
不知为何  ST写的 中间件和 MDK的 接口有一点差距  所以 创建线程的地方需要如上修改


修改 stm32f0xx_hal_conf.h
添加 图示内容  不出意外  下面 将可以直接编译了!!



写的有些多了  本来想 继续写 RTOS 基于串口的  应用  太长了 下次发帖写了

下面提出一个讨论 MX 创建的  工程 FREERTOS 中 cmsis_os.c 中 创建一个信号量  
osSemaphoreCreate参数 count 直接

传递给 xSemaphoreCreateCounting的两个形参  



原型
#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

不懂  这样设计意义何在?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

136

帖子

1

粉丝