你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【RT-Thread内核实现与应用开发实战指南】读书笔记

[复制链接]
andeyqi 发布时间:2018-11-29 11:49
本帖最后由 andeyqi 于 2018-11-29 11:47 编辑

很荣祥在社区,【野火助力,书香醉人—第三轮书籍申请】活动中申请到《RT-Thread内核实现与应用开发实战指南》图书,上网一查火哥已经发布了电子版的图书,迫不及待的下载看了电子版阅读先读为快,但还是喜欢纸质版的图书放在书包或者床头随时翻阅。阅读完电子版对RT-Thread这几年的发展变化点赞,待拿到纸质版图书慢慢消化细度体会其中的细节,整理笔记如下。

***********************************闲话至此,以下为读书的感悟笔记**************************

该书对RT-Thread(以下简称rtt)内核的系统调度,内存管理,IPC通信部分都进行了详细的描述,相信大家阅读完会对系统有了个系统的了解,其中的细节还是需要阅读源码并配合书籍理解消化,不要指望一口就吃成大胖子。

获取最新版本的rtt代码: http://github.com/RT-Thread/rt-thread/ 下载的最新的master版本为3.1.1,最新的4.0版本应该还没有放出来。

1 软件平台:
编译环境支持MDK,IAR,gcc,本文使用的开发环境linux+arm-none-eabi-gcc,另外需要依赖python和scons,软件版本如下。
①arm-none-eabi-gcc(5.4.1)
Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/home/book/andey/arm-none-eabi/gcc-arm-none-eabi-5_4-2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/work/GCC-5-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-5-build/install-native --libexecdir=/home/build/work/GCC-5-build/install-native/lib --infodir=/home/build/work/GCC-5-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-5-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-5-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-5-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-5-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-5-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r,armv8-m.base,armv8-m.main
Thread model: single
gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496] (GNU Tools for ARM Embedded Processors)

②SCons(v2.2.0)
SCons by Steven Knight et al.:
        script: v2.2.0.issue-2856:2676:d23b7a2f45e8[MODIFIED], 2012/08/05 15:38:28, by garyo on oberbrunner-dev
        engine: v2.2.0.issue-2856:2676:d23b7a2f45e8[MODIFIED], 2012/08/05 15:38:28, by garyo on oberbrunner-dev
        engine path: ['/usr/local/lib/scons-2.2.0/SCons']
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 The SCons Foundation
scons是一个Python写的自动化构建工具,从构建这个角度说,它跟GNU make是同一类的工具,是一种改进,并跨平台的gnu make替代工具,其集成功能类似于autoconf/automake 。scons是一个更简便,更可靠,更高效的编译软件。

③Python(2.7.14

2 代码编译
所谓的移植系统,只是找到RTT bsp类似的board进行修改编译,并配置所需要的组件即可,本实验直接采用的默认配置。
rtt 官方的代码库中已经包含大量bsp支持包,M0~M7的设备都已经全部覆盖了,移植使用的开发板为stm32l476-nucleo,发布版本的BSP已经支持了
该款开发板,只需要编译既可以在开发板上跑起来rtt。

①配置工程
scons --menuconfig 保存默认配置会在当前路径下生成一个.config的配置文件,并根据这个文件生成rtt配置文件rtconfig.h,编译的时候会根据这个文件的配置来编译代码。
menuconfig.PNG
内核的配置选项就不一一详细叙说,本实验最关心的就是console使用的设备,搜索发现console使用的是usrt2,默认的配置usart2已经开启了,如果不开启控制台会没有log输出。
console.PNG

使用过程中还遇到一个坑,如果使用stm32l476-nucleo开发板的朋友可以注意了,使用串口2把串口接到串口2上没有log输出,最后查看原理图发现串口2接到了STlink的虚拟串口上了,串口使用STLINK的串口2就有输出了。
uart2.PNG

②设置环境变量
一种方式可以通过export RTT_EXEC_PATH=[GCC路径]设置,还可以修改~/bsp/stm32l476-nucleo/rtconfig.py文件中EXEC_PATH值。
③编译程序
scons -j4 编译成功后,~/bsp/stm32l476-nucleo/目录下生成的rtthread.bin 即为可执行的二进制程序。

3 运行体验上电运行后串口会输出如下的信息,从输出信息可以看出rtt的版本信息,默认的shell使用的msh,输入help命令会列出系统的命令列表及帮助信息,项目开发过程中shell对调试及检测系统运行状态会有很大帮助。

rtt.PNG

rtt支持两种shell模式,根据上图的help帮助命令输出,msh模式下输入exit即进入finsh模式,finsh模式下输入msh()切换回msh模式。

shell.PNG


4 pinctrl 驱动框架rtt提供了一套简单的 I/O 设备管理框架,它把 I/O 设备分成了三层进行处理: 应用层、 I/O设备管理层、硬件驱动层。 应用程序通过 RT-Thread 的备操作接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。 rtt 提供给上层应用的是一个抽象的设备操作接口,给下层设备提供的是底层驱动框架。 对于通用 GPIO 设备, 应用程序既可以通过设备操作接口访问,又可以直接通过通用 GPIO 设备驱动来访问。
pinctr.PNG

  1. stm32l476-nucleo gpio驱动在~\rt-thread-master\bsp\stm32l476-nucleo\drivers\drv_gpio.c文件中,驱动的入口函数为int bsp_hw_pin_init(void)主要调用流程如下
  2. bsp_hw_pin_init()
  3.         ==》rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL);/* 向上注册驱动服务函数 */
  4. rt_device_pin_register("pin", &_stm32_pin_ops, RT_NULL)核心为_stm32_pin_ops数据结构,包含了gpio操作的相关函数,用户态调用设备的读写函数实际上调用的,驱动入口函数向上注册的函数,函数如下。
  5. const static struct rt_pin_ops _stm32_pin_ops =
  6. {
  7.     stm32_pin_mode,
  8.     stm32_pin_write,
  9.     stm32_pin_read,
  10.     stm32_pin_attach_irq,
  11.     stm32_pin_detach_irq,
  12.     stm32_pin_irq_enable,
  13. };
复制代码

程序结构.PNG

结构如上,对于简单的点灯灭灯程序,用户态主要调用rt_pin_mode配置为输出,调用rt_pin_write设置高低电平就可以控制LED了,rtt驱动将gpio抽象为相应index,用index来代表相应的gpio,通过一张表完成映射。

  1. #if (STM32L476_PIN_NUMBERS == 64)
  2.     __STM32_PIN_DEFAULT,
  3.     __STM32_PIN_DEFAULT,
  4.     __STM32_PIN(2, C, 13),
  5.     __STM32_PIN(3, C, 14),
  6.     __STM32_PIN(4, C, 15),
  7.     __STM32_PIN(5, D, 0),
  8.     __STM32_PIN(6, D, 1),
  9.     __STM32_PIN_DEFAULT,
  10.     __STM32_PIN(8, C, 0),
  11.     __STM32_PIN(9, C, 1),
  12.     __STM32_PIN(10, C, 2),
  13.     __STM32_PIN(11, C, 3),
  14.     __STM32_PIN_DEFAULT,
  15.     __STM32_PIN_DEFAULT,
  16.     __STM32_PIN(14, A, 0),
  17.     __STM32_PIN(15, A, 1),
  18.     __STM32_PIN(16, A, 2),
  19.     __STM32_PIN(17, A, 3),
  20.     __STM32_PIN_DEFAULT,
  21.     __STM32_PIN_DEFAULT,
  22.     __STM32_PIN(20, A, 4),
  23.     __STM32_PIN(21, A, 5),
  24.     __STM32_PIN(22, A, 6),
  25.     __STM32_PIN(23, A, 7),
  26.     __STM32_PIN(24, C, 4),
  27.     __STM32_PIN(25, C, 5),
  28.     __STM32_PIN(26, B, 0),
  29.     __STM32_PIN(27, B, 1),
  30.     __STM32_PIN(28, B, 2),
  31.     __STM32_PIN(29, B, 10),
  32.     __STM32_PIN(30, B, 11),
  33.     __STM32_PIN_DEFAULT,
  34.     __STM32_PIN_DEFAULT,
  35.     __STM32_PIN(33, B, 12),
  36.     __STM32_PIN(34, B, 13),
  37.     __STM32_PIN(35, B, 14),
  38.     __STM32_PIN(36, B, 15),
  39.     __STM32_PIN(37, C, 6),
  40.     __STM32_PIN(38, C, 7),
  41.     __STM32_PIN(39, C, 8),
  42.     __STM32_PIN(40, C, 9),
  43.     __STM32_PIN(41, A, 8),
  44.     __STM32_PIN(42, A, 9),
  45.     __STM32_PIN(43, A, 10),
  46.     __STM32_PIN(44, A, 11),
  47.     __STM32_PIN(45, A, 12),
  48.     __STM32_PIN(46, A, 13),
  49.     __STM32_PIN_DEFAULT,
  50.     __STM32_PIN_DEFAULT,
  51.     __STM32_PIN(49, A, 14),
  52.     __STM32_PIN(50, A, 15),
  53.     __STM32_PIN(51, C, 10),
  54.     __STM32_PIN(52, C, 11),
  55.     __STM32_PIN(53, C, 12),
  56.     __STM32_PIN(54, D, 2),
  57.     __STM32_PIN(55, B, 3),
  58.     __STM32_PIN(56, B, 4),
  59.     __STM32_PIN(57, B, 5),
  60.     __STM32_PIN(58, B, 6),
  61.     __STM32_PIN(59, B, 7),
  62.     __STM32_PIN_DEFAULT,
  63.     __STM32_PIN(61, B, 8),
  64.     __STM32_PIN(62, B, 9),
  65.     __STM32_PIN_DEFAULT,
  66.     __STM32_PIN_DEFAULT,
  67. #endif
复制代码
开发板ledl连接的是GPIOA5引脚,根据上表__STM32_PIN(21, A, 5)可知对应的index为21,操作的时候index直接传入21就可以。



5 添加名命令rtt系统支持的命令默认写在这个文件中xxx\rt-thread-master\components\finsh\cmd.c,添加一个命令可以在这个文件中添加或者在别的文件中添加,我添加的命令直接添加在cmd.c文件中。
在rtt中添加一个shell命令是很简单的,FINSH_FUNCTION_EXPORT(l);MSH_CMD_EXPORT(l);这两个宏就会将命令代码放到相应的secition中,控制台输入相关的命令对应的函数就会被调用,下面只是将上上述的pinctrl代码写入,写入到执行函数中就可以控制板子上的led,下面的edon,ledoff就会控制板子上的led亮和灭。
  1. #include "drivers/pin.h"
  2. static int is_led_init = 1;

  3. long ledon(void)
  4. {
  5.     rt_kprintf("led on!\n");
  6.     if(is_led_init)
  7.     {
  8.         is_led_init--;
  9.         rt_pin_mode(21,PIN_MODE_OUTPUT);
  10.     }
  11.     rt_pin_write(21,1);
  12.     return 0;
  13. }
  14. FINSH_FUNCTION_EXPORT(ledon, set led on);
  15. MSH_CMD_EXPORT(ledon, set led on);

  16. long ledoff(void)
  17. {
  18.     rt_kprintf("led off!\n");
  19.     if(is_led_init)
  20.     {
  21.         is_led_init--;
  22.         rt_pin_mode(21,PIN_MODE_OUTPUT);
  23.     }
  24.     rt_pin_write(21,0);
  25.     return 0;
  26. }
  27. FINSH_FUNCTION_EXPORT(ledoff, set led off);
  28. MSH_CMD_EXPORT(ledoff, set led off);
复制代码
添加代码重新编译后串口输入ledon,ledoff,代码中相应的rt_kprintf("led on!\n");rt_kprintf("led off!\n");会在串口上输出,并且led也能点亮熄灭,说明命令已经添加成功,rtt上添加一个命令还是很容易的吧。
led.PNG

led_on.jpg


led_off.jpg











评分

参与人数 1 ST金币 +20 收起 理由
STMCU + 20 赞一个!

查看全部评分

收藏 评论2 发布时间:2018-11-29 11:49

举报

2个回答
哈佛祖安智 回答时间:2018-11-29 20:56:59
赞。gpio隐射表实际上是和stm32芯片管脚的排列一致的
andeyqi 回答时间:2018-11-29 21:06:53
哈佛祖安智 发表于 2018-11-29 20:56
赞。gpio隐射表实际上是和stm32芯片管脚的排列一致的

嗯,之前我也是这么猜测的,一直没确认下,刚才看了下手册确实是这样的。

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版