你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C031评测】适配FreeRTOS添加shell任务

[复制链接]
andey 发布时间:2024-3-11 22:44

概述

嵌入式MCU开发中Free-RTOS是个使用比较常用的系统,,freertos 的内核文件相对很少,而且官方的代码下已经支持了CORTEX-M0+架构,我们基本不用修改什么就能把官方的代码适配到STM32C0的板子上。

我们先简答看下freertos的代码目录结构(芯片架构相关的我们只关注IAR cortex-m0):

FreeRTOS\Source\
|-- croutine.c
|-- event_groups.c
|-- list.c
|-- queue.c
|-- readme.txt
|-- stream_buffer.c
|-- tasks.c
`-- timers.c
|-- include
|   |-- FreeRTOS.h
|   |-- StackMacros.h
|   |-- atomic.h
|   |-- croutine.h
|   |-- deprecated_definitions.h
|   |-- event_groups.h
|   |-- list.h
|   |-- message_buffer.h
|   |-- mpu_prototypes.h
|   |-- mpu_wrappers.h
|   |-- portable.h
|   |-- projdefs.h
|   |-- queue.h
|   |-- semphr.h
|   |-- stack_macros.h
|   |-- stdint.readme
|   |-- stream_buffer.h
|   |-- task.h
|   `-- timers.h
|-- portable
|   |-- IAR
|   |   |-- ARM_CM4F
|   |   |   |-- port.c
|   |   |   |-- portasm.s
|   |   |   `-- portmacro.h
|   |-- MemMang
|   |   |-- ReadMe.url
|   |   |-- heap_1.c
|   |   |-- heap_2.c
|   |   |-- heap_3.c
|   |   |-- heap_4.c
|   |   `-- heap_5.c

从上面的代码目录树看代码代码量还是不到的,一共需要的.c .s 文件一共10个文件左右,因为操作系统依赖的portable相关的代码官方的代码结构里已经有了,理论上把这些文件组织到工程内部编译通过操作系统就移植完成了。 MemMang 目录下freertos 创建任务及资源需要动态malloc 内存,需要支持内存管理的接口,根据实际的情况选择一个就行,本次移植使用的是heap_4.c文件。

iar1111.jpg

解决上述编译问题后基本代码适配已经完成,根据对应的错误解决编译问题即可,系统编译完后成后,我们添加shell任务用于和系统进行交互,shell的移植可以查看此链接【STM32MP135-DK】裸机移植shell

main函数添加测试代码创建shell 任务:

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
   xTaskCreate((TaskFunction_t )littleshell_main_entry,
                (const char*    )"shell",
                (uint16_t       )SHELL_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )SHELL_TASK_PRIO,
                (TaskHandle_t*  )&ShellTask_Handler);
   vTaskStartScheduler();
  /* USER CODE END 3 */

添加shell 任务后板卡验证运行:

20240311-222944.gif

从上面的log 可知shell 任务调度运行正常。

移植适配遇到的问题

问题1:

stm32 的HAL库接管了systick,freertos的任务调度也会使用systick造成了这部分的耦合,存在冲突需要解决这部分的耦合

修改办法:

问了解决耦合问题,systick的中断统一由freertos管理,对HAL库使用的systick相关接口定义的是weak类型可以进行overwrite 覆盖对应代码如下:

/* Includes ------------------------------------------------------------------*/
#include "stm32c0xx_hal.h"

static volatile uint32_t tick = 0;

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    HAL_StatusTypeDef  status = HAL_OK;
    /* Return function status */
    return status;
}

void HAL_IncTick(void)
{
  tick++;
}


uint32_t HAL_GetTick(void)
{
  return tick;
}


void HAL_SuspendTick(void)
{

}

void HAL_ResumeTick(void)
{

}

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"

extern void vApplicationTickHook(void)
{
  HAL_IncTick();
}

问题2:

移植后会进入hardfault,对应死机现场如下:

hard_fault.jpg

查看对应的死机现场发现在main函数入口打印信息的时候进入了systick中断,这时调度器还没初始化成功,错误的触发了任务调度触发死机,原因为进入main函数时总中断开关是开启的,从而触发错误的相应了中断。

修改方法:

进入main函数时关闭总中断,总中断的开启时机交给调度器去控制,从而避免上述问题,因为适配使用的IAR使用了IAR 内置函数关闭中断对应修改代码如下


}#if defined (__ICCARM__)
#include "intrinsics.h"
#
endif
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* STM32C0xx 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
     */
#if defined (__ICCARM__)
   __disable_interrupt();
#endif
收藏 评论0 发布时间:2024-3-11 22:44

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版