开放原子训练营(第四季)TobudOS-基于STM32H750XBH+STM32CubeMX+HAL库+KEIL 移植 TobudOS

1.TobudOS

1.1.简介

TobudOS是开放原子开源基金会孵化的,面向物联网领域开发的实时操作系统,具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率,助力物联网终端设备及业务快速接入云上服务和应用。

1.2.特点

(1).小体积

最小内核:RAM 0.6KB,ROM 1.8KB 典型 LoraWAN 及传感器应用:RAM 3.3KB,ROM 12KB

(2).低功耗

休眠最低功耗低至 2uA 支持外设功耗管理框架

(3).丰富的 IoT 组件

集成主流 IoT 协议栈 多种通信模组SAL层适配框架; 支持 OTA 升级 提供简单易用端云 API,加速用户业务接入腾讯云

(4).可靠的安全框架

多样化的安全分级方案 均衡安全需求&成本控制

(5).良好的可移植性

内核及IoT组件高度解耦,提供标准适配层 提供自动化移植工具,提升开发效率

(6).便捷的调试手段

提供云化的最后一屏调试功能 故障现场信息自动上传云平台,方便开发人员调试分析

2.准备工作

2.1. 软件准备

STM32CubeMX  (代码将使用HAL库)  下载地址:

下载地址: https://www.st.com/zh/development-tools/stm32cubemx.html

KEIL  下载地址:

https://www.keil.com/demo/eval/arm.htm

开发板芯片为STM32H750XBH6,提前安装好安装Keil.STM32H7xx_DFP.3.1.1.pack系列器件支持包

支持包下载地址:

https://www.keil.arm.com/packs/stm32h7xx_dfp-keil/boards/

2.2.硬件准备

EVB_AIoT_STM32开发板,STM32H750XBH6主控芯片。

3.TobudOS移植

3.1.新建裸机工程

3.1.1.新建STM32Cubemx项目

1.新建项目

3.1.2.选择对应芯片型号

1.输入芯片型号搜索。

2.选择芯片。

3.1.3.关闭内存管理

3.1.4.时钟源选择外部晶振

3.1.5.设置串口UART5

开发板与外部连接的串口为UART5,其他开发板根据自己选择。

1.开启UART5

2.通信参数默认

1.搜索PB13引脚

2.将PB13引脚设置为UART5_TX

3.1.6.设置LED引脚

1.将PB1设置成输出

3.1.7.设置按键KEY引脚

设置PJ3引脚为输入,上拉。

3.1.8.设置中断

1.开启UART5中断

1.Hard fault,Pendable request,Time base三个中断不生成中断函数。前两个中断函数tobudOS会在RTOS里面对这三个中断函数进行接管,最后的Time base中断需要我们重写,下面会讲到。

3.1.9.配置时钟

3.1.10.工程和代码生成配置

1.选择工程配置。

2.选择工程。

3.填写工程名称和保存位置。

4.选择IDE为 MDK-ARM

1.选择工程配置。

2.选择代码生成。

3.选择只生成用到的库。

4.生成.C  .H代码。

1.生成代码

3.2.KEIL设置

1.开启MicroLIB。到时候print函数需要重构。

1.下载器选择ST-LINK。

1.打开下载自动复位运行选项。

1.编译,下载。

3.3.准备tobudOS源码

atomgit的下载地址:

https://atomgit.com/OpenAtomFoundation/TobudOS

3.4.内核移植

3.4.1.在工程下新建tobudOS文件夹

把需要的内核文件都复制进该文件夹下。

3.4.2.添加内核代码到工程

1.新建三个gruops:tos/arch   tos/kernel   tos/cmsis

1.

tobudOS\arch\arm\arm-v7m\common\tos_cpu.c

tobudOS\arch\arm\arm-v7m\cortex-m7\armcc\port_c.c

tobudOS\arch\arm\arm-v7m\cortex-m7\armcc\port_s.S

添加进文件。

1.

tobudOS\kernel\core\内所有添加进文件

1.

tobudOS\osal\cmsis_os\cmsis_os.c

添加进文件。

3.4.3.添加tobudOS头文件目录

把需要的头文件目录包含进去。

3.4.4.新建 TobudOS 系统配置文件 tos_config.h

新建一个User文件夹

新建一个User Groups

包含User的头文件

新建一个tos_config.h 头文件

将下面的代码复制进tos_config.h

#ifndef _TOS_CONFIG_H_
#define  _TOS_CONFIG_H_

#include "stm32h7xx.h"	// 目标芯片头文件,用户需要根据情况更改

#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u

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

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

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

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

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

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

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

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

#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE        0x100	// 配置TobudOS默认动态内存池大小

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#define	TOS_CFG_OBJ_DYNAMIC_CREATE_EN	1u		// 配置是否开启任务的动态分配处理和堆栈

#endif

把tos_config.h放入User Groups

4.创建任务,测试移植效果

4.1.包含tos_k.h和stdio.h头文件

4.2.重写SYSTICK中断函数 SysTick_Handler

void SysTick_Handler(void)
{
  HAL_IncTick();

  if (tos_knl_is_running())
  {
    tos_knl_irq_enter();
    tos_tick_handler();
    tos_knl_irq_leave();
  }
}

4.3.重构fputc fgetc用于printf

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
  return (ch);
}

int fgetc(FILE *f)
{
  int ch;
  while (__HAL_UART_GET_FLAG(&huart5, UART_FLAG_RXNE) == RESET)
    ;
  __HAL_UART_CLEAR_OREFLAG(&huart5);
  HAL_UART_Receive(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
  return (ch);
}

4.4.创建LED任务

创建一个LED任务,让LED间隔1000ms亮灭,并打印任务信息。

k_task_t led_thread; // LED任务句柄
#define LED_THREAD_STACK_SIZE 512
uint8_t led_thread_stack[LED_THREAD_STACK_SIZE]; //LED任务内存空间

void led_thread_entry(void *arg) // LED任务入口函数
{
  while (1) // 任务内死循环
  {
    HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); // LED开启
    printf("led_thread running,LED ON\r\n");                 // 打印信息
    tos_task_delay(1000);                                    // 阻塞延时

    HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); // LED关闭
    printf("led_thread running,LED OFF\r\n");                  // 打印信息
    tos_task_delay(1000);                                      // 阻塞延时
  }
}

4.5.创建KEY按键任务

创建一个KEY任务,让按键单击时,打印单击信息.

k_task_t key_thread; // KEY任务句柄
#define KEY_THREAD_STACK_SIZE 512
uint8_t key_thread_stack[KEY_THREAD_STACK_SIZE]; //KEY任务内存空间

void key_thread_entry(void *arg) //KEY任务入口函数
{
  uint8_t press = 0; // 记录KEY状态

  while (1) // 任务内死循环
  {
    if (HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) //KEY按下
    {
      if (press == 0)
      {
        press = 1;                                 // 记录KEY状态
        printf("key_thread runing,KEY被单击\r\n"); // 打印信息
      }
    }
    else
      press = 0;

    tos_task_delay(20); //阻塞延时
  }
}

4.6.内核初始化,任务创建和运行

在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_UART5_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  //在硬件初始化后,开始初始化tobudOS
  printf("Welcome to TobudOS(%s)\r\n", TOS_VERSION); //打印tobudOS版本信息
  tos_knl_init(); //内核初始化
  //创建LED任务
  tos_task_create(&led_thread,
                  "led_thread",
                  led_thread_entry,
                  NULL,
                  3,
                  led_thread_stack,
                  LED_THREAD_STACK_SIZE,
                  0);
  //创建KEY任务
  tos_task_create(&key_thread,
                  "key_thread",
                  key_thread_entry,
                  NULL,
                  3,
                  key_thread_stack,
                  KEY_THREAD_STACK_SIZE,
                  0);
  //启动任务
  tos_knl_start();

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4.7.编译下载,测试结果

编译下载。串口助手输出信息。

并观察到开发板LED闪烁

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值