TencentOS-tiny 移植到STM32F407(MDK)

目录

一、移植前的准备工作

1. 硬件(STM32测试板)

2. 软件

3. 裸机工程

3.1选择芯片STM32F407VET6

3.2 Pinout&Configuration >> 配置GPIO

3.3 Pinout&Configuration >> 配置时钟源

3.4 Pinout&Configuration >> 配置串口

3.5 时钟配置

3.6 生成工程配置

3.7 生成代码配置

3.8 生成代码

3.9 裸机代码结构

二、移植TencentOS-tiny

1. TencentOS-tiny 架构

2. 获取TencentOS-tiny源码

3. TencentOS-tiny源码文件

4.添加TencentOS-tiny源码

4.1 添加分组目录

4.2 添加arch源码

4.3 添加内核源码

4.4 添加cmsis_os源码

4.5 添加tos_config

4.7 添加头文件

5. 修改stm32f4xx_it.c代码

5.1 添加tos头文件

5.2 修改PendSV_Handler 中断函数

5.3 修改SysTick_handle中断函数

6. 修改usart.c代码

6.1 printf函数重定向

7. 修改mian.c代码

7.1 添加cmsis_os.h头文件

7.2 添加Task函数

7.3 内核初始化,创建Task,开启调度

三、验证TencentOS-tiny移植结果


一、移植前的准备工作

1. 硬件(STM32测试板)

MCU:STM32F407VET6(RAM: 196K ,FLASH: 512K,最高168MHz工作频率)

晶振:8MHz

2. 软件

编译器环境:Keil MDK-ARM Version 5.33

STM32cube 初始化代码生成器:STM32CubeMX Version 6.20

3. 裸机工程

使用 STM32cubeMX 生成裸机代码

3.1选择芯片STM32F407VET6

3.2 Pinout&Configuration >> 配置GPIO

板载三个指示灯,原理图如下图所示。

接着配置控制指示灯的引脚,配置为推挽输出,输出电平为高电平,保证初始化后指示灯是灭的。

user Label(用户标签)中填写内容是用来表示该引脚的,代替实际引脚,提高代码的移植性。STM32cubeMX生成程序时会在 main.h 中添加宏定义,如下所示。

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

......

/* Private defines -----------------------------------------------------------*/
#define BLUETOOTH_EN_Pin GPIO_PIN_2
#define BLUETOOTH_EN_GPIO_Port GPIOE
#define BLUETOOTH_RST_Pin GPIO_PIN_3
#define BLUETOOTH_RST_GPIO_Port GPIOE
#define LED_Run_Pin GPIO_PIN_4
#define LED_Run_GPIO_Port GPIOE
#define LED_Status_Pin GPIO_PIN_5
#define LED_Status_GPIO_Port GPIOE
#define LED_Error_Pin GPIO_PIN_6
#define LED_Error_GPIO_Port GPIOE

3.3 Pinout&Configuration >> 配置时钟源

3.4 Pinout&Configuration >> 配置串口

3.5 时钟配置

芯片的最高时钟频率可达到168MHz

3.6 生成工程配置

3.7 生成代码配置

3.8 生成代码

3.9 裸机代码结构


二、移植TencentOS-tiny

1. TencentOS-tiny 架构

TencentOS tiny 由一个轻量级 RTOS 内核 + 多个物联网组件构成,其主体架构图(引用 腾讯物联网终端操作系统)如下图所示:

2. 获取TencentOS-tiny源码

可直接前往Github:https://github.com/Tencent/TencentOS-tiny 直接进行下载。

3. TencentOS-tiny源码文件

打开 TencentOS-tiny 源文件,如下图所示。其中一共有13个文件夹(以最新源码为主),各个文件夹的具体说明见【doc / 09.Code_Directories.md】这里较以往的源码增加一个qmk文件,是TencentOS的一个 Makefile 编译框架。

说明文件是使用Markdown语言编写的文件,后缀.md,查看使用 Visual Studio Code 软件。

4.添加TencentOS-tiny源码

新建工程文件夹develop,在其目录下新建如下图所示子目录文件夹。

board:目录下放入我们前面生成的裸机代码,全部复制粘贴即可;在裸机工程中添加 TencentOS-tiny 配置文件,可以直接找源码 board 目录下的 Demo 中找到相近的工程,将其 TOS_CONFIG 文件夹复制带该裸机工程中,这个配置主要用于我们对TencentOS-tiny 的功能进行裁剪,得到我们需要的配置。

Doc: 放入自己的文档。

其他:可以先全部从TencentOS-tiny源码中复制过来,然后按最终需要进行裁剪。

4.1 添加分组目录

在裸机工程中添加分组目录,分别为tos/arch、tos/kernel、tos/cmsis_os、tos/config

4.2 添加arch源码

根据所使用的芯片选择合适的文件,当前移植的芯片是 STM32F407VET6 ,属于ARM Cortex M4 内核,使用的编译器是Keil MDK-ARM

tos_cpu.c:在arch\arm\arm-v7m\common目录中;arm-v7m 架构共用的支持,是 TencentOS tiny 的 CPU 适配文件,包括堆栈初始化、中断适配等。

port_c.c:在 arch\arm\arm-v7m\cortex-m4\armcc 目录中;Systick操作接口移植实现。

port_s.S:在 arch\arm\arm-v7m\cortex-m4\armcc 目录中;是Tencent-Tiny 的任务调度汇编代码,主要用于弹栈压栈等处理工作。

注意:如果使用的编译器是 GCC,则选择 arch\arm\arm-v7m\cortex-m4\gcc 目录下的适配文件。

tos_fault.c:是针对TencnetOS-tiny硬件故障追踪功能的支持,此功能可以在 tos_config.h 中配置,如果加入的话,需要将功能中原有的 HardFault_Handler 屏蔽。

4.3 添加内核源码

内核源码 kernel 目录下包含 corepm 两个目录,其中 core 目录下的代码为基础内核,pm 目录下的代码为低功耗组件。进行基础移植时无需添加 pm 目录下的代码,只需添加全部的基本内核源码(kernel/core 目录下),如下图所示:

4.4 添加cmsis_os源码

cmsis_osTencentOS-tiny为兼容cmsis标准而适配的OS抽象层,可以简化用户将业务从其他RTOS迁移到TencentOS-tiny的工作量。

TencentOS-tiny 提供CMSIS-RTOS 1.0和2.0接口,当前使用的是1.0。

cmsis_os.c:在 osal\cmsis_os 目录中;

4.5 添加tos_config

#ifndef _TOS_CONFIG_H_
#define  _TOS_CONFIG_H_

#include "stm32f4xx.h"


#define TOS_CFG_TASK_PRIO_MAX           10u 	// 配置TencentOS tiny默认支持的最大优先级数量

#define TOS_CFG_ROUND_ROBIN_EN          0u		// 配置TencentOS tiny的内核是否开启时间片轮转

#define TOS_CFG_OBJECT_VERIFY_EN           1u	// 配置TencentOS tiny是否校验指针合法

#define TOS_CFG_TASK_DYNAMIC_CREATE_EN  1u		// TencentOS tiny 动态任务创建功能宏

#define TOS_CFG_EVENT_EN                1u		// TencentOS tiny 事件模块功能宏

#define TOS_CFG_MMBLK_EN                1u		//配置TencentOS tiny是否开启内存块管理模块

#define TOS_CFG_MMHEAP_EN               1u		//配置TencentOS tiny是否开启动态内存模块

#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN  1u		// TencentOS tiny 默认动态内存池功能宏

#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE        0x4000	// 配置TencentOS tiny默认动态内存池大小

#define TOS_CFG_MUTEX_EN                1u		// 配置TencentOS tiny是否开启互斥锁模块

#define TOS_CFG_MESSAGE_QUEUE_EN        1u		// 配置TencentOS tiny是否开启消息队列模块

#define TOS_CFG_MAIL_QUEUE_EN           1u		// 配置TencentOS tiny是否开启消息邮箱模块

#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN	1u	// 配置TencentOS tiny是否开启优先级消息队列模块

#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN	1u		// 配置TencentOS tiny是否开启优先级消息邮箱模块

#define TOS_CFG_TIMER_EN                1u		// 配置TencentOS tiny是否开启软件定时器模块

#define TOS_CFG_PWR_MGR_EN              0u		// 配置TencentOS tiny是否开启外设电源管理模块

#define TOS_CFG_TICKLESS_EN             0u		// 配置Tickless 低功耗模块开关

#define TOS_CFG_SEM_EN                  1u		// 配置TencentOS tiny是否开启信号量模块

#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN      1u	// 配置TencentOS tiny是否开启任务栈深度检测

#define TOS_CFG_FAULT_BACKTRACE_EN      0u		// 配置TencentOS tiny是否开启异常栈回溯功能

#define TOS_CFG_IDLE_TASK_STK_SIZE      128u	// 配置TencentOS tiny空闲任务栈大小

#define TOS_CFG_CPU_TICK_PER_SECOND     1000u	// 配置TencentOS tiny的tick频率

#define TOS_CFG_CPU_CLOCK               (SystemCoreClock)	// 配置TencentOS tiny CPU频率

#define TOS_CFG_TIMER_AS_PROC           1u		// 配置是否将TIMER配置成函数模式

#endif

4.7 添加头文件

 

5. 修改stm32f4xx_it.c代码

5.1 添加tos头文件

在 stm32f4xx_it.c 中添加 tos_k.h 头文件,用于调用API函数。

5.2 修改PendSV_Handler 中断函数

TencentOS-tiny内核中已经对pendSV异常进行了处理,在 PendSV_Handler 函数前添加 __weak 关键字(弱定义);

5.3 修改SysTick_handle中断函数

TencentOS-tiny内核需要Systick提供时钟节拍,在 SysTick_Handler 函数中添加 TencentOS tiny 的调度处理函数,如下图:

tos_knl_is_running() 函数判断内核是否正在运行。

os_tick_handler() 函数是系统用于更新时基用的。

6. 修改usart.c代码

6.1 printf函数重定向

在 usart.c 中添加 fputc 函数,用于重定义 putc 函数,可以是 printf 函数从串口1打印输出。

int fputc(int ch, FILE *f)//将 printf 函数重定向到串口1
{
  if (ch == '\n') 
  {
    HAL_UART_Transmit(&huart1, (void *)"\r", 1,30000);
  }
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

出现错误是因为缺 stdio.h 头文件,只需要在 main.h 文件中添加即可,如下图所示。

7. 修改mian.c代码

7.1 添加cmsis_os.h头文件

cmsis_os.h 头文件中包含TencentOS-tiny 相关头文件。

7.2 添加Task函数

// 定义任务栈大小和优先级参数等
#define TASK_STK_SIZE	1024
extern void OS_TaskEntry(void *arg);
osThreadDef(OS_TaskEntry, osPriorityNormal,1,TASK_STK_SIZE);

__weak void OS_TaskEntry(void *arg)	// 任务入口函数
{
	while (1)
	{
		printf("This is a demo task,please use your task enrty!\r\n");
		osDelay(1000);
	}
}

7.3 内核初始化,创建Task,开启调度

    osKernelInitialize();
    osThreadCreate(osThread(OS_TaskEntry), NULL);
    osKernelStart();

 


三、验证TencentOS-tiny移植结果

1. 点此按钮对工程进行编译。

2. 编译后,输出此信息表示编译成功。

3. 连接硬件并上电后,点击此按钮即可完成程序下载。

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值