本移植过程基于学习营给出的第0个basic例程,硬件平台为STM32H743。
basic工程是面向stm32l4的,首先把工程里关于l4的文件换了吧(唉,尽干了些苦力活)。
换了相关文件之后,就是这幅样子。当然,除了替换相关文件之外,还修改了里头的时钟配置(不修改编译都编过不去),还有里头本来就有的串口初始化函数。
编译是没错,但有用没用呢,试一下,把USART和LED部分改一改,看能不能出效果
唉,看样子没啥大问题,LED在闪,串口也在打印。
在rt_hw_board_init()函数中把系统时钟开了HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/RT_TICK_PER_SECOND);
加上系统时钟中断服务函数
使用HAL库时,还需要完善HAL_Delay函数,RT-Thread操作系统中是直接填入rt_thread_delay()
个人见解:这个函数这样处理会存在一些隐患,RT-Thread是默认自动初始化外设及系统组件的,HAL_Delay这个函数常见与HAL库的各个角落,也包括外设初始化函数中;外设初始化的时候RT-Thread系统并没有运行起来,rt_thread_delay()这个函数实质是把线程挂起休眠,初始化阶段哪来的线程,自然而然就会陷入RT_ASSERT判断,从而执行死循环。
查阅RT-Thread的编程手册,发现手册里面给了一个高精度延时的例程,或许融合起来会更安全一下
RT-Thread在初始化过程中会打印logo和系统版本,现在已经调试出了串口,但是到现在都没打出系统logo
RT-Thread在没有打开RT_USING_DEVICE的情况下,有一种替补操作用于控制台打印信息。
深究rt_kprintf
函数会发现一些东西
在没有打开RT_USING_DEVICE
宏定义的状态下,rt_kprintf
函数会使用rt_hw_console_output
函数进行输出。
但是这个函数并没有进行定义,而且用了weak进行弱化,那就可以在外部进行定义,程序自然会进行调用,但是怎么写这个函数呢,在rt_kprintf中所有要输出的内容都用rt_vsnprintf函数进行了格式化,所以rt_hw_console_output函数只需要实现字符串输出即可。
RT-Thread实现了优秀的内存管理算法,但移植到现在都没有实现,或许该试试实现内存管理了。
板卡并没有外挂多大的RAM,所以只要实现RTT中的小内存管理就行了。
仔细研读RT-Thread的代码可以发现,RTT并没有固定HEAP的起始地址,而是借助了代码的存储结构和分布装载描述文件来实现的(我也不知道我理解的对不对,ImageRW_IRAM1ZILimit
这玩意查了很久),在board.h文件中HEAP_BEGIN定义为(ImageRW_IRAM1ZILimit)
取地址。
在board.c中调用rt_system_heap_init
函数进行堆初始化好像成功了,程序并没有死,但是还有待进一步测试。
哎,好使!
RT-Thread还有一大组件就是Finsh,命令行功能强大,怎么能不去实现呢。
Finsh的实现需要有字符设备支持
将Finsh组件加入工程….
呃,basic这个工程没有相关文件,那就从憋出考过来,例如第四个工程finsh
将components文件夹拷贝到rt-thread文件夹下,再添加进工程。
需要打开如下宏定义,否则会报一大堆错误
编译之后发现还是有错误
这是因为缺少了文件
从chapter11\4-finsh t-thread\src
文件夹中将device.c拷贝到0-basic t-thread\src
文件夹中,并加入工程,编译,零错误,零警告。
这就行了吗??
并不是,刚才添加的是device.c
,负责像上层提供统一的接口,现在的工程还缺少一份硬件驱动代码。
常用的硬件驱动代码,rtt已经做的非常完善,并不需要再重新写一遍。
从chapter11\4-finsh\drivers
文件夹中将usart.c和usart.h文件拷贝至0-basic\drivers
文件夹,并加入工程
这份驱动代码已经支持USART1~USART5,只需要打开相应的宏,并检查引脚是否匹配即可。
如需自动初始化并进行设备注册,在文件结尾加上INIT_BOARD_EXPORT(stm32_hw_usart_init);
即可。
什么?下载进去没有用??
没用就对了,因为还没进行初始化呀
在rt_hw_board_init
函数中加上rt_components_board_init
进行初始化,
加上rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
进行设备绑定,然后就如下图了。
输入命令试试
完成!!!