打印
[STM32F7]

学习笔记移植RT-Thread到STM32(基于潘多拉开发板)

[复制链接]
4123|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 Fillmore 于 2019-7-19 10:09 编辑

移植RT-Thread到STM32L475VET6的笔记.pdf (573.61 KB)
关注了解更多
从本文开始,记录自己的RT-Thread学习笔记,基于STM32L475VET6讲解,相关开发板用RTT&正点原子的潘多拉IoT Board开发板。本文先从Nano开始学起,个人觉得对于初学者,还是先学会Nano的移植,把内核部分向学一遍,再去学组件和设备驱动以及其他的东西,这里包括RT-Thread的内核移植、FinSH移植,相关代码到GitHub下载:https://github.com/sanjaywu/STM32L475_PANDORA_RT-Thread_DEMO

一、获取裸机工程
1、裸机工程可到GitHub下载:https://github.com/sanjaywu/STM32L475_PANDORA_DEMO,下载完成之后,打开工程文件夹,可以发现如下文件:



2、接着我们把HARDWARE、SYSTEM和USMART这三个文件删除,HARDWARE文件夹是裸机的外设驱动,在讲解移植的时候不需要用到,SYSTEM文件夹有delay延时、串口驱动和相关类型宏定义,在移植RT-Thread的时候,我们会重新实现delay延时和串口驱动以及类型宏定义。



二、下载 RT-Thread Nano 源码
1、RT-Thread Master 的源码可从 RT-Thread GitHub 仓库下载,Nano 就是从里面扣出来的,去掉了一些组件和各种开发板的 BSP,保留了 OS的核心功能,但足够我们使用。RT-Thread 官方并没有将抠出来的Nano 放 到 他 们 的 官 方 网 站 , 而 是 作 为 一 个 Package 放 在 了 KEIL 网 站:http://www.keil.com/dd2/pack/,目前最新的是3.1.1版本,打开这条连接,然后拉到下面找到RT-Thread的Package:



2、点击箭头下载,弹出窗口点击OK,然后开始下载:



3、下载完成之后双击安装这个pack,安装的路径和你安装MDK5的时候是一样的,我安装的是默认路径。

4、安装完成之后,找到你安装MDK5的路径,然后按这个路径找到RT-Thread的源码:C:\Keil_v5\ARM\PACK\RealThread\RT-Thread\3.1.1:



三、往裸机工程添加 RT-Thread 源码
1、在前面下载好的裸机工程里,再新建一个文件夹为RT-Thread的,然后将上面下载好的Nano版源码拷贝到这个文件:



2、对于Nano源码各个文件内容删减:

(1)打开bsp,这里RT-Thread是放底层驱动的东西:



除了board.c和rtconfig.h这两个文件,其他都删除,然后再新建一个board.h头文件。

(2)打开components,RT-Thread组件放置的地方,只有一个finsh,保留它,这个finsh非常好用:



(3)打开libcpu —> arm,因为用的是STM32L4xx,时候cortex-m4,所以只需保留cortex-m4即可,其它都删除:



(4)剩下的include和src文件设RT-Thread的头文件和内核源码,不能删除,保留完整。

(5)接着,新建一个文件夹来放设备驱动,命名device_drivers。这里为什么要用RT-Thread设备驱动呢,因为RT-Thread的finsh功能实现需要串口,这里就用先只设备驱动里面的串口驱动来实现,自己产品能够RT-Thread的master版本中整理出来,代码可以看工程(https://github.com/sanjaywu/STM32L475_PANDORA_RT-Thread_DEMO)里面的,这样既能实现finsh也能实现rt_kprintf。当然你也可以自己写一个串口驱动,只不过后面一直finsh就会很麻烦,读写函数都要改掉,而且容易出错。



最终移植整理好之后,RT-Thread的文件如下:



四、修改rt_config.h
#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__

/* RT-Thread内核部分 */
#define RT_NAME_MAX 8                                        //内核对象名称最大长度,大于该长度的名称多余部分会被自动裁掉
#define RT_ALIGN_SIZE 4                                        //字节对齐时设定对齐的字节个数。常使用ALIGN(RT_ALIGN_SIZE)进行字节对齐
#define RT_THREAD_PRIORITY_MAX 32                //定义系统线程优先级数;通常用RT_THREAD_PRIORITY_MAX-1定义空闲线程的优先级
#define RT_TICK_PER_SECOND 1000                        //定义时钟节拍,为1000时表示1000个tick每 秒,一个tick为1ms
#define RT_USING_OVERFLOW_CHECK                        //检查栈是否溢出,未定义则关闭
#define RT_DEBUG                                                //定义该宏开启debug模式,未定义则关闭
#define RT_DEBUG_INIT 0                                        //开启debug模式时:该宏定义为0时表示关闭打印组件初始化信息,定义为1时表示启用
#define RT_DEBUG_THREAD 0                                //开启debug模式时:该宏定义为0时表示关闭打印线程切换信息,定义为1时表示启用
#define RT_USING_HOOK                                        //定义该宏表示开启钩子函数的使用,未定义则关闭
#define IDLE_THREAD_STACK_SIZE 256                //定义了空闲线程的栈大小

/*
线程间同步与通信部分,
该部分会使用到的对象有信号量、
互斥量、事件、邮箱、消息队列、信号等
*/
#define RT_USING_SEMAPHORE                                //定义该宏可开启信号量的使用,未定义则关闭
#define RT_USING_MUTEX                                        //定义该宏可开启互斥量的使用,未定义则关闭
#define RT_USING_EVENT                                        //定义该宏可开启事件集的使用,未定义则关闭
#define RT_USING_MAILBOX                                //定义该宏可开启邮箱的使用,未定义则关闭
#define RT_USING_MESSAGEQUEUE                        //定义该宏可开启消息队列的使用,未定义则关闭
#define RT_USING_SIGNALS                                //定义该宏可开启信号的使用,未定义则关 闭

/* 内存管理部分 */
#define RT_USING_MEMPOOL                                //定义该宏可开启静态内存池的使用,未定义则关闭
#define RT_USING_MEMHEAP                                //定义该宏可开启两个或以上内存堆拼接的使用,未定义则关闭
#define RT_USING_SMALL_MEM                                //定义该宏可开启开启小内存管理算法,未定义则关闭
//#define RT_USING_SLAB                                        //定义该宏可开启SLAB内存管理算法,未定义则关闭
#define RT_USING_HEAP                                        //定义该宏可开启堆的使用,未定义则关闭

/* 内核设备对象 */
#define RT_USING_DEVICE                                        //表示开启了系统设备的使用,使用设备驱动
#define RT_USING_CONSOLE                                //定义该宏可开启系统控制台设备的使用,未定义则关闭
#define RT_CONSOLEBUF_SIZE 128                        //定义控制台设备的缓冲区大小
#define RT_CONSOLE_DEVICE_NAME "uart1"        //控制台设备的名称

/* 自动初始化方式 */
#define RT_USING_COMPONENTS_INIT                //定义该宏开启自动初始化机制,未定义则关闭
#define RT_USING_USER_MAIN                                //定义该宏  启设置应用入口为main函数
#define RT_MAIN_THREAD_STACK_SIZE 2048        //定义main线程的栈大小

/* FinSH */
#define RT_USING_FINSH                                        //定义该宏可开启系统FinSH调试工具的使用,未定义则关闭
#ifdef RT_USING_FINSH
#define FINSH_THREAD_NAME "tshell"                //开启系统FinSH时:将该线程名称定义为tshell
#define FINSH_USING_HISTORY                                //开启系统FinSH时:使用历史命令
#define FINSH_HISTORY_LINES 5                        //开启系统FinSH时:对历史命令行数的定义
#define FINSH_USING_SYMTAB                                //开启系统FinSH时:定义该宏开启使用Tab键,未定义则关闭
#define FINSH_THREAD_PRIORITY 20                //开启系统FinSH时:定义该线程的优先级
#define FINSH_THREAD_STACK_SIZE 4096        //开启系统FinSH时:定义该线程的栈大小
#define FINSH_CMD_SIZE 80                                //开启系统FinSH时:定义命令字符长度
#define FINSH_USING_MSH                                        //开启系统FinSH时:定义该宏开启MSH功能
#define FINSH_USING_MSH_DEFAULT                        //开启系统FinSH时:开启MSH功能时,定义该宏默认使用MSH功能
#define FINSH_USING_MSH_ONLY                        //开启系统FinSH时:定义该宏,仅使用MSH功能
#endif

/* 关于 MCU */
#define STM32L475VE                                                //定义该工程使用的MCU为STM32L475VE
#define RT_HSE_VALUE 8000000                        //定义时钟源频率
#define RT_USING_LED                                        //定义该宏开启LED的使用
#define RT_USING_SERIAL                                        //定义该宏开启串口的使用
#define BSP_USING_UART1                                        //定义该宏开启UART1的使用

#endif/* __RTTHREAD_CFG_H__ */




沙发
Fillmore|  楼主 | 2019-1-23 15:53 | 只看该作者
本帖最后由 Fillmore 于 2019-1-23 15:56 编辑

论坛版式不好 开头有全文链接

使用特权

评论回复
板凳
Fillmore|  楼主 | 2019-1-23 15:54 | 只看该作者
五、修改board.c
1、添加系统时钟初始函数,这里使用HAl库将系统初始化为80MHz:

void _Error_Handler(char *file, int line)
{
        /* USER CODE BEGIN Error_Handler_Debug */
          /* User can add his own implementation to report the HAL error return state */
          while(1)
          {
          }
          /* USER CODE END Error_Handler_Debug */
}

/*
  * @brief System Clock Configuration
  * @retval None
*/
void SystemClock_Config(void)
{
        RCC_OscInitTypeDef RCC_OscInitStruct;
          RCC_ClkInitTypeDef RCC_ClkInitStruct;

        __HAL_RCC_PWR_CLK_ENABLE();

    /* Initializes the CPU, AHB and APB busses clocks */
          RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
          RCC_OscInitStruct.HSEState = RCC_HSE_ON;
          RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
          RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
        RCC_OscInitStruct.PLL.PLLM = 1;
          RCC_OscInitStruct.PLL.PLLN = 20;
          RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
          RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
          RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
          if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
          {
            _Error_Handler(__FILE__, __LINE__);
          }

    /* Initializes the CPU, AHB and APB busses clocks */
          RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1| RCC_CLOCKTYPE_PCLK2;
          RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
          RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
          RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
          RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

          if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
          {
            _Error_Handler(__FILE__, __LINE__);
          }

    /* Configure the main internal regulator output voltage */
          if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
          {
            _Error_Handler(__FILE__, __LINE__);
          }
}
2、修改Tick相关函数,初始化SysTick,:

/**
*  HAL adaptation
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
    /* Return function status */
    return HAL_OK;
}

uint32_t HAL_GetTick(void)
{
    return rt_tick_get() * 1000 / RT_TICK_PER_SECOND;
}

void HAL_SuspendTick(void)
{
    return ;
}

void HAL_ResumeTick(void)
{
    return ;
}

void HAL_Delay(__IO uint32_t Delay)
{
    return ;
}

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();
}
3、修改rt_hw_board_init函数,初始化SysTick:

/**
* This function will initial your board.
*/
void rt_hw_board_init()
{       
        /* 使用HAL库,初始化HAL */
        HAL_Init();

        /* 初始化系统时钟和SysTick */
    SystemClock_Config();
        SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);

        /* 硬件 BSP 初始化统统放在这里,比如 LED,串口,LCD 等 */
#ifdef RT_USING_LED
        led_init();
#endif

#ifdef RT_USING_SERIAL
    stm32_hw_usart_init();
#endif


    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
        rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
4、增加RT-Thread堆空间大小,因为finsh需要和其他线程需要,我这里先修改为16K,后期使用具体看MCU的RAM和实际需要调节:

使用特权

评论回复
地板
dirtwillfly| | 2019-1-23 20:22 | 只看该作者
感谢分享。无图无真相阿。文件也可以上传到论坛的下载频道的,那里一次能传50M

使用特权

评论回复
5
Fillmore|  楼主 | 2019-1-25 15:12 | 只看该作者
dirtwillfly 发表于 2019-1-23 20:22
感谢分享。无图无真相阿。文件也可以上传到论坛的下载频道的,那里一次能传50M ...

移植RT-Thread到STM32L475VET6的笔记.pdf (573.61 KB)

使用特权

评论回复
6
Fillmore|  楼主 | 2019-1-25 15:13 | 只看该作者
搞了个PDF

使用特权

评论回复
7
新的我太阳哇| | 2019-1-25 22:15 | 只看该作者
学习一下 以后尝试移植一下

使用特权

评论回复
8
晓伍| | 2019-2-17 13:43 | 只看该作者
我很想学习这个

使用特权

评论回复
9
eredewe3| | 2019-2-17 15:47 | 只看该作者
感谢分享!很好的学习贴。

使用特权

评论回复
10
八层楼| | 2019-2-18 09:28 | 只看该作者
这个是野火那个版本的吗

使用特权

评论回复
11
观海| | 2019-2-18 10:06 | 只看该作者
步骤介绍的比较详细

使用特权

评论回复
12
木木guainv| | 2019-2-18 10:36 | 只看该作者
潘多拉开发板能从哪里下载到呢

使用特权

评论回复
13
xiaoqizi| | 2019-2-18 11:08 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
14
wowu| | 2019-2-18 12:12 | 只看该作者
用在别的开发板上需要修改什么吗

使用特权

评论回复
15
wakayi| | 2019-2-18 12:46 | 只看该作者
去那个连接看比较好看点

使用特权

评论回复
16
Fillmore|  楼主 | 2019-2-18 14:40 | 只看该作者
八层楼 发表于 2019-2-18 09:28
这个是野火那个版本的吗

不是野火那个

使用特权

评论回复
17
Fillmore|  楼主 | 2019-2-18 14:41 | 只看该作者
wakayi 发表于 2019-2-18 12:46
去那个连接看比较好看点

csdn 自己的富文本编辑器 对代码排版友好

使用特权

评论回复
18
Fillmore|  楼主 | 2019-2-18 15:26 | 只看该作者
木木guainv 发表于 2019-2-18 10:36
潘多拉开发板能从哪里下载到呢

iot board 的交流群:884257438

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

64

主题

144

帖子

0

粉丝