RT-Thread内核移植

2023-05-16

 

记录代码移植过程,成功一步记录一步

第一步:建立裸机程序

使用STM32CubeMx建立一个裸机程序

生成MDK5工程

第二步:参考0-bare-metal完成board.c、board.h文件

在Drivers组下添加board.c、board.h文件

添加board.c文件

实现board.c里面关于关于时钟配置、串口初始化、GPIO初始化等函数

void bsp_uart_init(void) 
{ 
    MX_USART1_UART_Init(); 
}
 
void bsp_uart_send(char c) 
{ 
    while ((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) == RESET)); 
    huart1.Instance->DR = c; 
} 
void bsp_led_init(void) 
{ 
    MX_GPIO_Init(); 
} 
void bsp_led_on(void) 
{ 
    HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin, GPIO_PIN_RESET); 
} 
void bsp_led_off(void) 
{ 
    HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin, GPIO_PIN_SET); 
}
void rt_hw_board_init() 
{ 
    /* HAL_Init() function is called at the beginning of program after reset and     before     *    the clock configuration. */ 
        HAL_Init(); 
    /* Clock Config: 
      * System Clock : 80M  
      * HCLK : 80M 
      * PCLK1 : 80M 
      * PCLK2 : 80M 
      * SDMMC1 : 48M 
      * USART1 : PCLK2 */ 
     SystemClock_Config(); 
     bsp_led_init(); 
     bsp_uart_init(); 
}

void SystemClock_Config(void)

void _Error_Handler(char *file, int line)

以上两个函数采用cubemx工具生成的函数,main函数和例程中一样

现象:

第三步:添加RT-Thread源码

拷贝RT-Thread源代码到工程路径下,当然也可以不移动,就是指定路径的时候长一点,没关系

添加两个新组一个叫做kernel,防止内核代码,另一个叫做CROTEX-M3放置平台相关代码,我用的是STM32F103ZET6使用的是crotex-m3内核。

添加相关文件到对应的组下面,添加完如图,对了还有一个rtconfig.h文件,用于配置和裁剪内核。

添加代码之后别忘了添加头文件,rtconfig.h文件放在了工程的根目录之下,别忘了添加头文件。

在编译之后有了有符号重定义,注释掉原有的函数

在编译之后有了有符号重定义,注释掉原有的函数
//void HardFault_Handler(void) 
//{ 
// /* USER CODE BEGIN HardFault_IRQn 0 */ 
// /* USER CODE END HardFault_IRQn 0 */ 
// while (1) 
// { 
// /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 
// /* USER CODE END W1_HardFault_IRQn 0 */ 
// } 
// /* USER CODE BEGIN HardFault_IRQn 1 */ 
// /* USER CODE END HardFault_IRQn 1 */ //}
 
//void PendSV_Handler(void) 
//{ 
// /* USER CODE BEGIN PendSV_IRQn 0 */ 
// /* USER CODE END PendSV_IRQn 0 */ 
// /* USER CODE BEGIN PendSV_IRQn 1 */ 
// /* USER CODE END PendSV_IRQn 1 */ 
//} 

编译下载正常运行

第四步:console移植,实现控制台输出功能

实现函数

void rt_hw_console_output(const char *str) 
{ 
    RT_ASSERT(str != RT_NULL); 
    while (*str != '\0') 
    { 
        if (*str == '\n') 
        { 
            bsp_uart_send('\r'); 
        } 
        bsp_uart_send(*str++); 
    } 
}

这个函数主要是实现bsp_usart_send,此函数在第二步已经实现。

接下来修改SysTick_Handler函数

/** * @brief This function handles System tick timer. */ 
void SysTick_Handler(void) 
{ 
    rt_interrupt_enter(); 
    rt_tick_increase(); 
    rt_interrupt_leave(); 
}

注意包含rtthread.h头文件

修改main函数如下

int main(void) 
{ 
    while (1) 
    { 
        /* USER CODE END WHILE */ 
        /* USER CODE BEGIN 3 */ 
        rt_kprintf("led on\n"); 
        rt_thread_delay(RT_TICK_PER_SECOND); 
        rt_kprintf("led off\n"); 
        rt_thread_delay(RT_TICK_PER_SECOND); 
        } 
    /* USER CODE END 3 */ 
}

编译下载输出如图

第五步:内存堆配置,实现动态内存管理功能

在rt_config.h中添加宏

//#define RT_USING_NOHEAP 
#define RT_USING_SMALL_MEM 
#define RT_USING_HEAP

注意:注释掉RT_USING_NOHEAP,如果有的话

在rt_hw_board_init函数中添加动态内存管理初始化函数

void rt_hw_board_init() 
{ 
    static uint8_t heap_buf[10 * 1024];
    ……….
    rt_system_heap_init(heap_buf, heap_buf + sizeof(heap_buf) - 1); 
}

在main函数中初始化一个线程函数

#define THREAD_PRIORITY 25 
#define THREAD_STACK_SIZE 512 
#define THREAD_TIMESLICE 5 
void test_thread_entry(void *parameter)
{ 
    while (1) 
    { 
        rt_kprintf("enter test thread\n"); 
        rt_thread_delay(RT_TICK_PER_SECOND); 
    }
} 
/** * @brief The application entry point. * * @retval None */ 
int main(void)
{ 
    rt_thread_t tid; 
    tid = rt_thread_create("test", 
                            test_thread_entry, 
                            RT_NULL, 
                            THREAD_STACK_SIZE, 
                            THREAD_PRIORITY, 
                            THREAD_TIMESLICE); 
    if (tid != RT_NULL) 
    { 
        rt_thread_startup(tid); 
        return 0; 
    }
    else 
    { 
        return -1; 
    } 
}

编译下载,输出如图

第六步:实现Finsh Shell功能

将components组件文件夹下的drivers和finsh文件添加到工程

新建finsh组和DeviceDrivers组,添加文件

 

在前几步添加文件的时候在Kernel组莫名少添加了device.c文件在调试的时候浪费很长时间,

在官方的1-basic的rt-thread\src文件下也没有,感受到来自NPC的调戏。

添加代码之后先修改board.c文件里的rt_hw_board_init函数,

/** * This function will initial STM32 board. */ 
void rt_hw_board_init() 
{ 
    static uint8_t heap_buf[10 * 1024]; 
    /* HAL_Init() function is called at the beginning of program after reset and before     *   the clock configuration. */ 
    HAL_Init(); 
    /* Clock Config: 
     * System Clock : 80M 
     * HCLK : 80M 
     * PCLK1 : 80M 
     * PCLK2 : 80M 
     * SDMMC1 : 48M 
     * USART1 : PCLK2 
    */ 
    SystemClock_Config(); 
    /* Configure the Systick interrupt time */ 
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND); 
    /* Configure the Systick */ 
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); 
    /* SysTick_IRQn interrupt configuration */ 
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 
    //bsp_led_init(); 
    stm32_hw_usart_init(); 
 
#ifdef RT_USING_CONSOLE 
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME); 
#endif #ifdef RT_USING_HEAP 
    rt_system_heap_init(heap_buf, heap_buf + sizeof(heap_buf) - 1); 
#endif
#ifdef RT_USING_COMPONENTS_INIT 
    rt_components_board_init(); 
#endif
}

stm32_hw_usart_init();

用来初始化并注册串口

屏蔽掉board.c文件里面串口初始化函数、串口发送函数、控制台输出函数,工作交给drv_usart.c。

接下来修改rtconfig.h中的宏定义

添加#define BSP_USING_UART1

添加后rtconfig.h如下

#ifndef RT_CONFIG_H__ 
#define RT_CONFIG_H__ 
/* Automatically generated file; DO NOT EDIT. */ 
/* RT-Thread Configuration */ 
/* RT-Thread Kernel */ 
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4 
#define RT_THREAD_PRIORITY_32 
#define RT_THREAD_PRIORITY_MAX 32 
#define RT_TICK_PER_SECOND 1000 
#define RT_USING_OVERFLOW_CHECK 
#define RT_USING_HOOK 
#define RT_IDEL_HOOK_LIST_SIZE 4 
#define IDLE_THREAD_STACK_SIZE 256 
#define RT_DEBUG 
/* Inter-Thread communication */ 
#define RT_USING_SEMAPHORE 
#define RT_USING_MUTEX 
#define RT_USING_EVENT 
#define RT_USING_MAILBOX 
#define RT_USING_MESSAGEQUEUE 
/* Memory Management */ 
//#define RT_USING_NOHEAP 
#define RT_USING_SMALL_MEM 
#define RT_USING_HEAP 
/* Kernel Device Object */ 
#define RT_USING_DEVICE 
#define RT_USING_CONSOLE 
#define RT_CONSOLEBUF_SIZE 128 
#define RT_CONSOLE_DEVICE_NAME "uart1" 
/* RT-Thread Components */ 
#define RT_USING_COMPONENTS_INIT 
#define RT_USING_USER_MAIN 
#define RT_MAIN_THREAD_STACK_SIZE 2048 
#define RT_MAIN_THREAD_PRIORITY 10 
/* C++ features */ 
/* Command shell */ 
#define RT_USING_FINSH 
#define FINSH_THREAD_NAME "tshell" 
#define FINSH_USING_HISTORY 
#define FINSH_HISTORY_LINES 5 
#define FINSH_USING_SYMTAB 
#define FINSH_USING_DESCRIPTION 
#define FINSH_THREAD_PRIORITY 20 
#define FINSH_THREAD_STACK_SIZE 4096 
#define FINSH_CMD_SIZE 80 
#define FINSH_USING_MSH 
#define FINSH_USING_MSH_DEFAULT 
#define FINSH_ARG_MAX 10 
/* Device virtual file system */ 
/* Device Drivers */ 
#define RT_USING_DEVICE_IPC 
#define RT_PIPE_BUFSZ 512 
#define RT_USING_SERIAL 
/* Env config */ 
#define SYS_PKGS_DOWNLOAD_ACCELERATE 
#define BSP_USING_UART1 
#endif 

之前mian函数中的初始化函数去掉

编译下载如图

出了问题,finsh没有跑起来,没有msh>,重启、没有、重启、还没有

调试了很久还是不行,之后经大神指点在rtdef.h文件如图位置添加了RT_USED

编译下载,还是没有,不过这次是因为串口接收引脚模式配置错误,修改之后编译下载运行,

成功运行,但是为什么要加RT_USED,还是不知道。

以上

对了,这种移植模式值得吐槽,希望以后官方可以更加人性化一点

这里可以下载移植好的程序

https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7794&page=1&extra=#pid37101

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RT-Thread内核移植 的相关文章

  • RISC与CISC

    作者 xff1a Austin Wang 链接 xff1a http www zhihu com question 20783321 answer 72598657 这里简单来谈一下 xff0c ARM和X86之间为什么不太具有可比性的问题
  • NandFlash和NorFlash的区别

    一 xff0e NAND和NOR的比较 NOR和NAND是现在市场上两种主要的非易失闪存技术 Intel于1988年首先开发出NOR flash技术 xff0c 彻底改变了原先由EPROM 和EEPROM一统天下的局面 紧接着 xff0c
  • 安装 CORD 之前需要了解的术语

    CORD Central Office Re Architected as a Data Center 是ONF组织推动的开源的边缘计算的项目 CORD 项目的官方资料包括源代码 xff0c 安装指导等 本文对官方安装指导涉及的一些术语进行
  • SoC嵌入式软件架构设计之一:系统内存需求评估

    博主 xff1a 吴跃前 转载自 xff1a http www cnblogs com yueqian scut p 4015046 html SoC嵌入式软件架构设计之一 xff1a 系统内存需求评估 内存是SoC System on C
  • S5PV210启动过程分析

    刚刚接触 S5PV210 xff0c 看了官方的数据手册感觉跟以前用的 STM32 单片机根本不在一个层面上 xff0c 当然两者的用途不同 xff0c 不具备可比性 可能之前习惯使用 STM32 等单片机 xff0c 现在接触 S5PV2
  • ARM支持的4种堆栈工作方式

    1 满递增堆栈 xff1a 堆栈指针指向最后压入堆栈的数据 xff0c 且由低地址向高地址生成 2 满递减堆栈 xff1a 堆栈指针指向最后压入堆栈的数据 xff0c 且由高地址向低地址生成 3 空递增堆栈 xff1a 堆栈指针指向下一个要
  • 前变址、回写前变址、后变址

    根据数据传输传输的时机以及在指令执行后基址寄存器是否被更新 xff0c 寄存器变址有前变址 回写前变址和后变址暗中方式 执行指令的时候 xff0c 如果先进行变址运算 xff0c 后传递数据 xff0c 那么这种方式就是前变址方式 如图1所
  • ubuntu 配置 tftp 服务器

    注意 xff1a 1 tftpboot为根目录 2 已经是root权限不用再加sudo 临时获取权限 3 使用netstat au grep tftp xff0c 保证tftp是启动的 出现 udp 0 0 tftp 则说明tftp服务已经
  • STM32启动文件详解

    先在RAM中分配系统使用的栈 xff0c RAM的起始地址为0x2000 0000 然后在RAM中分配变量使用的堆 然后在CODE区 flash 分配中断向量表 xff0c flash的起始地址为0x0800 0000 xff0c 该中断向
  • C语言细节之定义与声明

    什么是定义什么是声明 xff0c 似乎这俩个东西一样但是又有所区别 xff0c 思考一下 xff0c 如果你不能直接说出这二者的根本区别 xff0c 那么本文对你还是有点用处的 首先什么是定义 xff1f C 43 43 Primer 第四
  • 关于数据存储大小端模式的C语言题目

    int main int a 5 61 1 2 3 4 5 int ptr1 61 int amp a 43 1 int ptr2 61 int int a 43 1 printf 34 x x 34 ptr1 1 ptr2 return
  • 窥探引用和指针

    C语言面试题里面经常会出现一道题目 xff1a 向某个指定的内存地址写入特定的数据 xff0c 譬如向0x1234写入100 xff0c 做法如下 int 0x1234 61 100 解释一下就是将0x1234利用 int 强制转换为地址
  • STM32F101xxT6中VBAT 管脚上的怪现象

    转自 xff1a http bbs elecfans com forum php mod 61 viewthread amp tid 61 458808 amp extra 61 问题 xff1a 问题由某 UPS 制造公司提出 其工程师在
  • ST-LINK接口定义

    ST LINK接口定义 https www cnblogs com jieruishu p 9980350 html ST LINKIII管脚定义及接法 xff1a ST LINK IIILED灯三种状态含义 xff1a 常亮 xff1a
  • 罗德里格斯公式推导

    罗德里格斯公式推导 第一部分 向量 v 61 v x v
  • Ubuntu中的vi

    Windows中的常用编辑器 xff0c 如自带的notepad 比较好用的notepad 43 43 xff0c UltraEditor xff0c SlickEditor Linux中常用编辑器 xff0c 自带的最古老的vi 比较好用
  • 关于C++中的友元函数的总结

    转载自 xff1a http www cnblogs com BeyondAnyTime archive 2012 06 04 2535305 html 关于C 43 43 中的友元函数的总结 1 友元函数的简单介绍 1 1为什么要使用友元
  • 拷贝构造函数

    拷贝构造函数是重载构造函数的一种重要形式 xff0c 它的功能是使用一种已经存在的对象去初始一个新创建的同类对象 xff0c 它可以将一个已有对象的数据成员的值拷贝给正在创建的另一个同类的对象 拷贝构造函数与类同名 xff0c 没有返回值
  • cp: omitting directory ‘sp/’

    在linux中使用命令复制文件夹的时候出现的错误 xff1a cp omitting directory sp 解决办法 xff1a 使用递归拷贝 xff0c 在cp命令后面加上 r参数 xff0c 形如 xff1a cp r sp ica
  • LDR和ADR

    转自 xff1a https www douban com note 331036776 ARM汇编有ldr指令以及ldr adr伪指令 xff0c 他门都可以将标号表达式作为操作数 xff0c 下面通过分析一段代码以及对应的反汇编结果来说

随机推荐

  • 在显示屏上显示的数字的方法

    在现实屏上显示的数字的时候经常需要对数据进行分解 xff0c 得到数据 的每一位再依次显示 xff0c 方法有很多种 xff0c 下面介绍经常用到的3种方法 第一种方法 xff1a 不断的利用取整运算与取余运算得到每一位 void disp
  • 可变参数列表的简单实现

    使用可变参数列表实现一个sum函数 include lt stdio h gt define AUPBND sizeof int 1 define ADNBND sizeof int 1 define bnd X bnd sizeof X
  • 函数指针实例

    include lt stdio h gt void fun1 void printf 34 I 96 m fun1 n 34 void fun2 void printf 34 I 96 m fun2 n 34 void fun3 void
  • makefile小试牛刀

    使用make编译两个 c文件 div span style font size 14px a c void fun1 void int main fun1 return 0 span div div span style font size
  • 线程,进程,程序的区别

    转载自 xff1a https mp weixin qq com s O6 cZ9t8aJUMyeb7TbcbTQ 任务是代码运行的一个映象 xff0c 从系统的角度看 xff0c 任务是竞争系统资源的最小运行单元 任务可以使用或等待CPU
  • ubuntu14.04 samba服务器安装配置

    Data 2016 12 19 Author cjh Theme samba install andconfiguration 在介绍如何安装配置samba之前 xff0c 先简单介绍linux中两个命令的区别分别是update和upgra
  • 在数组中进行图形绘制

    include lt stdio h gt define k 2 43 1 define 2 define s 0 static unsigned short stop 61 s k k k k k k k s k k k k k k k
  • socket函数

    转自 xff1a http blog csdn net guoping16 article details 6584382 1 基本套接字函数 xff08 1 xff09 socket函数原型 socket 建立一个socket文件描述符
  • 进程与线程

    第一章 xff1a 计算机系统漫游 进程 xff1a 进程是操作系统对一个正在运行的程序的一种抽象 xff0c 一个系统可以同时运行多个进程 xff0c 看上去是CPU并发的执行多个程序 xff0c 实际上是通过进程切换来实现的 xff0c
  • GDI GDI+ 的区别

    转载自 xff1a http www cnblogs com lidabo p 3701252 html GDI 43 是GDI的下一个版本 xff0c 它进行了很好的改进 xff0c 并且易用性更好 GDI的一个好处就是你不必知道任何关于
  • GDI GDI+ 的区别

    转载自 xff1a http www cnblogs com lidabo p 3701252 html GDI 43 是GDI的下一个版本 xff0c 它进行了很好的改进 xff0c 并且易用性更好 GDI的一个好处就是你不必知道任何关于
  • 使用的DockPanel的心得

    使用这个控件的时候后一定要先Show this DockPlan1 才能使用DockTo this DockPlan1 DockStyle Bottom 固定位置 xff0c 否则会抛出异常
  • C#使用双缓冲解决绘图闪屏的问题

    最近在工作需要使用C 绘制图形 xff0c 看了一下绘制的函数觉得很简单就开始着手工作了 xff0c 但是在实际应用的时候发现鼠标进行绘制的时候会闪屏 xff0c 原因是图元重绘的时间不一致 xff0c 百度一下有很多更详细的 xff0c
  • 关于捕获键盘信息的processDialogkey方法

    转载自 xff1a http blog csdn net lucifinil s article details 6318189 在一些控件里的keydown方法 xff0c 没有办法捕获所有的按键消息 比如自己写一个窗体控件库 xff0c
  • C#泛型委托

    因为项目原因最近要使用C 进行编程 xff0c 于是每天现学现卖一点一点的进行开发 之前很长的时间一直使用C和C 43 43 进行编程 xff0c 于是转到C 一开始开始不是特别适应的 xff0c 特别是C 这门语言没有了指针 xff0c
  • 基于windows的Ubuntu双系统安装

    Data 2016 12 19 Author cjh Theme Ubuntu dual system installation 前期准备 1 Ubuntu相关版本镜像ios 2 UltraISO 用于制作U盘启动盘 3 EasyBCD 2
  • 汇编文件.S和.s的区别

    c C 原始程序 xff1b 预处理 编译 汇编 C C 43 43 原始程序 xff1b 预处理 编译 汇编 ccC 43 43 原始程序 xff1b 预处理 编译 汇编 cxx C 43 43 原始程序 xff1b 预处理 编译 汇编
  • 串口网口数据帧解析(支持连包、断传、错误数据过滤)

    本文转载自 xff1a https blog csdn net hwb 1988 article details 45872379 嵌入式系统中 xff0c 关于数据接受部分确实思考了很多 xff0c 下面总结下个人经验 关于串口传输 xf
  • Use of $Super$ $  and$Sub$ $to patch symbol definitions

    在无法修改现有符号的情况下 xff0c 可以使用特殊模式 现有符号无法修改 xff0c 例如 xff0c 如果它位于外部库或ROM代码中 在这种情况下 xff0c 您可以使用 Super 和 Sub 模式来修补现有符号 修补函数foo xf
  • RT-Thread内核移植

    记录代码移植过程 xff0c 成功一步记录一步 第一步 xff1a 建立裸机程序 使用STM32CubeMx建立一个裸机程序 生成MDK5工程 第二步 xff1a 参考0 bare metal完成board c board h文件 在Dri