ThreadX(二) ------移植到STM32

基于STM32CubeIDE移植ThreadX

新建裸机项目

  • 目录结构
    在这里插入图片描述
  • 主函数
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t pData[]="=========ThreadX========= ";
  /* USER CODE END 1 */
  .......
  .......
  .......	
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_UART_Transmit(&huart1, pData, sizeof(pData), HAL_MAX_DELAY);
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

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

在这里插入图片描述

ThreadX 源码

git clone https://github.com/azure-rtos/threadx.git

在这里插入图片描述

  • 主要的两个文件
文件夹内容
common源码
ports移植文件

在这里插入图片描述
找到threadx\ports\cortex_m4\gnu\example_build
把tx_initialize_low_level.S文件复制到\threadx\ports\cortex_m4\gnu\src
在这里插入图片描述
在这里插入图片描述

  • 回到STM32CubeIDE reflesh 工程

在这里插入图片描述

  • 开始添加编译

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 添加的两个头文件路径在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 添加上的源码路径
    在这里插入图片描述

修改文件

在这里插入图片描述
不出意外肯定是会报错的(移植怎么可能什么都不改是吧)
在这里插入图片描述
看下具体的错误,啊,原来是重复定义了,被threadx接管了,那么只要把它注释掉在编译。
在这里插入图片描述
在这里插入图片描述
果不其然 error 又出现了(哪有注释几行就完事了)
在这里插入图片描述
那看一下具体的错误,
RAM_segment_used_end
_vectors
-------------没有定义
那就去tx_initialize_low_level.S 里面看一下,解释下很清楚了。(为什么全英文的东西愿意看,就是threadx里面文件注释太全了,虽然是英文但是至少比没有注释强太多了)

在这里插入图片描述
在这里插入图片描述

  • 找到STM32某某_FLASH.ld,给他设置地址__RAM_segment_used_end__
__RAM_segment_used_end__ = .;

在这里插入图片描述

  • 找到 startup_stm32某某.s 里面 g_pfnVectors 中断向量 应该由 threadx 指向
    替换_vector = g_pfnVectors ,再次编译
    在这里插入图片描述
    在这里插入图片描述
    nice ! no error !!! 接下来就是跑threadx的了
    在这里插入图片描述

验证

  1. 首先加入头文件 “tx_api.h”
    在这里插入图片描述
  2. 调用 tx_kernel_enter()
    在这里插入图片描述
  3. 编写 void tx_application_define(void *first_unused_memory)就可以运行了
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "tx_api.h"
	........
	........
	........
/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
TX_THREAD my_thread_1;
TX_THREAD my_thread_2;

uint8_t pData1[]="I am thread1 ";
uint8_t pData2[]="I am thread2 ";
/* USER CODE END PV */
	........
	........
	........
int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t pData[]="=========ThreadX========= \n";
  /* USER CODE END 1 */
	........
	........
	........
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_SPI3_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Transmit(&huart1, pData, sizeof(pData), HAL_MAX_DELAY);

  tx_kernel_enter(); //threadx 入口

  /* USER CODE END 2 */

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


/* USER CODE BEGIN 4 */
void thread1_entry(ULONG entry_input)
{
	while(1)
	{
		  HAL_UART_Transmit(&huart1, pData1, sizeof(pData1), HAL_MAX_DELAY);
		  tx_thread_sleep(1000);// 线程睡眠1000 timer_ticks
	}
}

void thread2_entry(ULONG entry_input)
{
	while(1)
	{
		  HAL_UART_Transmit(&huart1, pData2, sizeof(pData2), HAL_MAX_DELAY);
		  tx_thread_sleep(500);// 线程睡眠500 timer_ticks
	}
}

void tx_application_define(void *first_unused_memory)
{
	/*线程1*/
	tx_thread_create(
			&my_thread_1,	//线程控制块指针
			"my_thread1",	//线程名字
			thread1_entry,  //线程入口函数
			0,				//线程入口参数
			first_unused_memory, //线程的起始地址(这里偷懒,没有进行分配,直接使用未用的起始地址)
			1024,	//内存区域大小K
			3,		//优先级3  (0~TX_MAX_PRIORITES-1)0  表示最高优先级
			3,		//禁用抢占的最高优先级
			TX_NO_TIME_SLICE,//时间切片值范围为 1 ~ 0xFFFF(TX_NO_TIME_SLICE = 0)
			TX_AUTO_START //线程自动启动
			);
	/*线程2*/
	tx_thread_create(
			&my_thread_2,	//线程控制块指针
			"my_thread2",	//线程名字
			thread2_entry,  //线程入口函数
			0,				//线程入口参数
			first_unused_memory+1024, //线程的起始地址+1024 (-被前面线程用掉了)
			1024,	//内存区域大小K
			1,		//优先级3  (0~TX_MAX_PRIORITES-1)0  表示最高优先级
			1,		//禁用抢占的最高优先级
			TX_NO_TIME_SLICE,//时间切片值范围为 1 ~ 0xFFFF(TX_NO_TIME_SLICE = 0)
			TX_AUTO_START //线程自动启动
			);
}
/* USER CODE END 4 */

乍看以为ok了,但实际上还是有些小毛病的,时间好像对不上号啊,
我的时钟频率是80Mhz,延时的时间跟想法有出入。
这里还有个地方需要修改就是系统的OS tick,根据设置按需修改
在这里插入图片描述
在这里插入图片描述
这样算出来应该差不了
在这里插入图片描述

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值