使用STM32CubeIDE移植腾讯物联网OS TencentTiny-OS

TencentTiny-OS、STM32F103C8和STM32CubeIDE

前言概要

腾讯最近发布了自己的IoT操作系统TencentOS tiny,具备小体积、低功耗、集成主流IoT协议栈、和自家IoT Hub无缝结合、安全、移植性等等优势。可以移植到多种主流MCU上,并且提供了详尽的移植说明和使用文档。
对个人而言,还是能兼容多种MCU平台以及和自家IoT Hub的无缝整合最具吸引力。
如果是用腾讯IoT的话,确实可以减少开发测试人力成本,实现多硬件平台的兼容,让产品快速测试、开发和上线交付。

STM32F103X系列是使用非常广泛的中档MCU,属于arm-v7m系列cortex-m3核,因为便宜好用厂商支持多,大量廉价开发板也都用它。因此,TencentOS tiny对其有完备的移植支持,提供了全套移植代码。

STM32CubeIDE则是ST收购了Atollic之后,基于原来的TrueStudio(已停止更新)推出的全功能开发IDE,
自带gcc工具链,CubeMX无缝整合,功能强大,非常好用,推荐使用(其实基本就是原来的TrueStudio,基于Eclipse CDT)。

因为TencentOS tiny官网的移植说明是基于Makefile的,配置繁琐易出错,不方便。
所以本文使用ST官方推荐的All in one式的STM32CubeIDE,把移植过程做一个简单步骤的说明。
(TencentOS tiny已经把所有大多数STM系列的移植代码都完成,因此本文实际只是个编译流程)

需要用的软件:

  • STM32CubeMX
  • STM32CubeIDE
  • TencentOS tiny

需要用的硬件:

  • STM32F103FC8开发板
  • STLink V2调试器

链接

TencentOS tiny

  1. TencentOS tiny Github:https://github.com/Tencent/TencentOS-tiny
  2. TencentOS tiny 官网地址:https://cloud.tencent.com/product/tos-tiny

STM32CubeIDE

  1. TSTM32CubeIDE 官网地址

一、STM32CubeMX生成工程

这一步基本可以参照TencentOS tiny 官网的说明
https://github.com/Tencent/TencentOS-tiny/blob/master/doc/TencentOS-tiny-porting-gcc.md,
只是中间需要注意打开SWD调试选项和最终生成工程的类型

  1. 创建工程,选择MCU为STM32F103C8
    在这里插入图片描述
  2. 设定SYS,打开SWD调试选项
    在这里插入图片描述
    CubeMX默认不打开SWD调试,感觉是个坑,不注意这一点,第一次下载之后,STLink就再也连不少设备了。只能用:开发板的RST接地->再次连接->RST悬空的方式重新下载, 非常麻烦。
    详细请参照该篇文章
  3. 使用内部LSE,如需使用外部晶振,在RCC中打开

在这里插入图片描述
5. 配置串口1,串口2,串口1用于日志,串口2保留用于以后和ESP8266通信接入腾讯IoT-Hub
在这里插入图片描述
6. 设置工程名、工程属性
在这里插入图片描述
7. 设置代码生成规则
在这里插入图片描述
9. 选择使用HAL(默认选项)
在这里插入图片描述
10. 生成工程
在这里插入图片描述

二、STM32CubeIDE工程设置和移植代码修改

  1. 复制以下TencentOS-tiny的代码到工程下的src目录
  • arch
  • board
  • kernel
  • osal

复制完成后,因为F103是armv7m m3核,STM32CubeIDE的内置工具链是gcc系列,所以

  • 在arm目录下,除下面之外的目录和文件全部删除(否则会参与编译出现重复定义等错误)
    - arm\arm-v7m\common
    - arm\arm-v7m\cortex-m3\gcc
  • 在board目录下,只保留
    - board\NUCLEO_STM32F103RB\TOS_CONFIG 目录
    初次之外的所有目录和文件也都删除,并将目录名改为STM32F103C8
    (借用STM32F103RB的配置头文件)

打开生成的TencentOS-tiny-STMF103工程,刷新工程即可看到添加后代码文件,正确修改后的文件结构如下图:
在这里插入图片描述

  1. 工程设置
    打开工程属性,在C++ General -> Paths and Symbols 追加下面的目录:
  • kernel/core/include
  • kernel/pm/include
  • arch/arm/arm-v7m/cortex-m3/gcc
  • arch/arm/arm-v7m/common/include
  • osal/cmsis_os
  • board/STM32F103C8/TOS_CONFIG
    如下图:
    在这里插入图片描述
  1. 修改中断代码

(注意将添加代码置于USER CODE BEGIN和 USER CODE END 注释块中间,这样在CubeMX重新生成依赖代码时依然可以保留有自己的代码)

修改stm32f1xx_it.c文件:

  • 增加头文件引用
/* USER CODE BEGIN Includes */
#include "tos.h"
/* USER CODE END Includes */
  • 将PendSV_Handler中断函数标记为__weak
__weak void PendSV_Handler(void)
{
}
  • 在SysTick_Handler中断函数添加如下代码:
void SysTick_Handler(void)
{
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
  if( tos_knl_is_running() ) {
	  tos_knl_irq_enter();
	  tos_tick_handler();
	  tos_knl_irq_leave();
  }
  /* USER CODE END SysTick_IRQn 1 */
}

在这里插入图片描述
4. 增加demo代码和启动代码

修改main.c文件:

  • 头文件引用
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h"
/* USER CODE END Includes */
  • 添加demo代码(2个任务交替打印串口)
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

//task1
#define TASK1_STK_SIZE		512
void task1(void *pdata);
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);

//task2
#define TASK2_STK_SIZE		512
void task2(void *pdata);
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);

void task1(void *pdata)
{
   int count = 1;
   char buffer[64] = {0};
   while(1) {
   	snprintf(buffer, sizeof(buffer), "task 1 %04d\r\n", count++);
   	HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 0xFFFF);
       //HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
       osDelay(2000);
   }
}
void task2(void *pdata)
{
   int count = 1;
   char buffer[64] = {0};
   while(1) {
   	snprintf(buffer, sizeof(buffer), "task 2 %04d\r\n", count++);
   	HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), 0xFFFF);
       osDelay(1000);
   }
}
/* USER CODE END 0 */
  • main函数中添加启动代码
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();

 /* USER CODE BEGIN Init */
 /* USER CODE END Init */

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

 /* USER CODE BEGIN SysInit */
 /* USER CODE END SysInit */

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

 /* USER CODE BEGIN 2 */
 osKernelInitialize();                 //TOS Tiny kernel initialize
 osThreadCreate(osThread(task1), NULL);// Create task1
 osThreadCreate(osThread(task2), NULL);// Create task2
 osKernelStart();                      //Start TOS Tiny
 /* USER CODE END 2 */

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

在这里插入图片描述

三、编译工程和调试

  1. 如果配置正确,即可正常编译成功如下:
    在这里插入图片描述
  2. 如果STLink已经正确配置好(SWD),就可以进行调试了:
    将开发板的PA10(RX),PA9(TX)分别接USB转TTL的TX和RX引脚后打开串口,就
    可以观察到串口上的日志输出,表示TencentOS tiny已经正常跑起来了。如下:
    在这里插入图片描述

四、代码下载

为了方便参考,生成的代码已经放到csdn上,下载后即可编译。
下载连接
后续将与腾讯IoT-Hub关联的功能做介绍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章