STM32-+-RT-Thread-OS--学习笔记

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

STM32+RTThreadOS1/92STM32+RTThreadOS学习笔记mostone@hotmail.com前言学习的最好办法是实践,所以,第一步是如何让程序跑起来,再去分析代码运行机制。因此,本文稿的主要目的是怎么最快让程序跑起来。关于RT-Thread版本GUI之前的RT-ThreadOS版本是1.1.0,GUI开始,使用的版本是1.1.1。RT-Thread当前在持续更新中,后续版本可能与这里所述不同,这是正常现象。当前官网的PDF文件就是一个很好的证明,很多函数,实现方法已经变更了。STM32+RTThreadOS2/92开发环境操作系统:WindowsXPIDE:KeilMDK4.71a开发板:奋斗V3(STM32F103VET6)+4.3”LCD(SSD1963,480X272)1.安装KeilMDK2.安装Python2.73.安装Scons2.0.1第一项,是集成开发环境,第三项是项目构建软件,第二项是第三项依赖的运行环境。安装Scons的目的是自动生成KeilMDK的Project文件,项目初始化。Scons的下载地址:://请使用此指定版本,最新版本可能无法运行项目生成脚本。注:具体安装使用说明请参考=%E9%85%8D%E7%BD%AErt-thread%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83STM32+RTThreadOS3/92参考资源:主要有三个参考资源:1.官方PDF说明文档2.官方Wiki百科STM32+RTThreadOS4/923.下载的源代码包中doxygen生成的帮助文档STM32+RTThreadOS5/92第一个例程1.运行Scons脚本,生成MDKProject文件打开WindowsCommand命令行窗口,将工作目录cd到c:\mcu\RT-Thread1.1.0\bsp\stm32f10x目录下。输入脚本命令:C:\Python27\scripts\scons--target=mdk4-s(注:以上请使用实际安装路径)执行完毕后,在bsp目录下生成一个Project.uvproj文件STM32+RTThreadOS6/92Project.uvproj这个文件,是复制template.uvproj,并在里面添加指定组件文件。可以比较一下这两个文件:STM32+RTThreadOS7/922.打开项目文件3.修改LED定义将29行~35行的定义改为奋斗板V3中的实际管脚。STM32+RTThreadOS8/924.修改Device在Option中(按Alt+F7),将Device改为STM32F103VE5.修改Utilities使用J-Link,要将Options中的Utilities改为J-LINK/J-TraceCortexSTM32+RTThreadOS9/926.添加JLinkDevice点击上图中的Settings,添加Device在下面图中,按“Add”按钮,在弹出的画面中选择“STM32F10xHigh-densityFlash”7.编译STM32+RTThreadOS10/928.下载下载完成后,Reset一下,可以看到开发板上的V6在闪烁。修改application.c中的led_thread_entry(),加两句代码,实现两个LED灯交替闪烁。增加的代码:L65,L73重新编译;在下载前,我们改一下J-Link设置,勾选ResetandRun,这样下载完成后就直接运行,不要手工去Reset。STM32+RTThreadOS11/92完毕以上是在自动生成的项目基础上,完成简单的LED灯闪烁例程。STM32+RTThreadOS12/92串口通讯例程通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作。例程实现步骤1.目标需求:开机打开串口1,侦听上位机(我们使用电脑串口测试软件)发送的信息,然后原样输送到串口1。2.创建项目a)禁用Finsh和consoleb)默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1。因此,在运行scons命令生成项目文件之前,修改rtconfig.h,禁用这两项。(下图L65,L70)c)生成项目文件运行scons--target=mdk4–s打开生成的项目文件,可以看到,文件组finsh已经不再被包含进来了。STM32+RTThreadOS13/92d)创建echo.c新建一个C文件echo.c,编写RT_Thread任务入口,COM1侦听,以及初始化函数。示例代码如下:#includeecho.hstructrx_msg{rt_device_tdev;rt_size_tsize;};staticstructrt_messagequeuerx_mq;staticcharuart_rx_buffer[64];staticcharmsg_pool[2048];//串口侦听回调函数rt_err_tuart_input(rt_device_tdev,rt_size_tsize){structrx_msgmsg;msg.dev=dev;msg.size=size;//将接收内容放入消息队列rt_mq_send(&rx_mq,&msg,sizeof(structrx_msg));returnRT_EOK;}//任务入口函数voidusr_echo_thread_entry(void*parameter){structrx_msgmsg;rt_device_tdevice;rt_err_tresult=RT_EOK;//从RT系统中获取串口设device=rt_device_find(uart1);if(device!=RT_NULL){//指定接收串口内容的回调函数rt_device_set_rx_indicate(device,uart_input);//以读写方式打开设备rt_device_open(device,RT_DEVICE_OFLAG_RDWR);}STM32+RTThreadOS14/92while(1){//从消息队列中获取被回调函数放入消息队列中的内容result=rt_mq_recv(&rx_mq,&msg,sizeof(structrx_msg),50);if(result==-RT_ETIMEOUT){//timeout,donothing}if(result==RT_EOK){rt_uint32_trx_length;rx_length=(sizeof(uart_rx_buffer)-1)msg.size?msg.size:sizeof(uart_rx_buffer)-1;rx_length=rt_device_read(msg.dev,0,&uart_rx_buffer[0],rx_length);uart_rx_buffer[rx_length]='\0';//将内容写回到串口rt_device_write(device,0,&uart_rx_buffer[0],rx_length);}}}//串口例程初始化函数voidusr_echo_init(){rt_thread_tthread;rt_err_tresult;//创建消息队列,分配队列存储空间result=rt_mq_init(&rx_mq,mqt,&msg_pool[0],128-sizeof(void*),sizeof(msg_pool),RT_IPC_FLAG_FIFO);if(result!=RT_EOK){rt_kprintf(initmessagequeuefailed.\n);return;}//创建任务线程thread=rt_thread_create(devt,usr_echo_thread_entry,RT_NULL,1024,25,7);//启动任务线程if(thread!=RT_NULL)rt_thread_startup(thread);}STM32+RTThreadOS15/92在application.c中加入初始化代码(echo.h略)L189:usr_echo_init();在开始编译前,还要修改board.c,注释掉第183行,不然将报错。因为我们禁用了console,所以不需要设置console输出设备。STM32+RTThreadOS16/92e)测试编译,下载,测试。STM32+RTThreadOS17/92程序分析a)内存分布查看编译生成的obj/rtthread-stm32.map文件,可以看到代码及常量,被下载到芯片的0x8000000地址段,最前面的是中断矢量表,第一个中断地址是RESET,矢量表共0x130个字节。STM32+RTThreadOS18/92有初始值的变量定义,从地址段0x20000000开始对应的Stm32内存映射表,代码和常量被下载到Flash,已初始化变量定位到SRAM(可能是下载到Flash,开机初始化后复制到RAM,而不是直接下载到RAM,不然下次运行,初始值可能已被修改)STM32+RTThreadOS19/92这是MDK中芯片内存区域的地址分配这是J-Link对芯片的定义,内存是512K,类型是On-chipFlash,地址空间从0x08000000到0x0807FFFFSTM32+RTThreadOS20/92b)程序运行流程开机后,从Flash0x080000000处的中断矢量表,取得RESET中断的处理函数入口地址,跳转到入口函数开始执行RESET中断服务,如下图,RESET中断服务函数定义在startup_stm32f10x_hd.s中,先执行了stm32类库中的SystemInit(),再然后转到main()函数。SystemInit()主要是对芯片的基本设置,如时钟频率。RT-Thread中,在BSP目录下提供了startup.c,包含了main()函数,它调用了同文件中的rtthread_startup(),再然后rtthread_startup()调用了rt_application_init(),rt_application_init()则在application.c中定义,用户代码就从这里开始。另外还有一个重要文件是stm32f10x_it.c,这里面定义了中断服务例程,中断矢量表中的地址指向这个文件中相应的服务函数入口地址。比如,我们的串口1收到上位机的消息后,会产生USART1_IRQ,这时芯片就会在0x08000000开始的中断向量表中找到USART1_IRQHandler()STM32+RTThreadOS21/92的入口地址,跳转后开始执行中断服务函数USART1_IRQHandler()。当然,要产生中断,需要在初始化代码中开启中断。echo.c上面贴出了这个文件的源代码,除了uart_input(),其它都比较直观。在RTT系统中,uart_input()只是USART1_IRQHandler()的一部分,在echo.c的初始化代码中,被注册为uart1这个device(RTT封装对象)的回调函数:L34:rt_device_set_rx_indicate(device,uart_input);STM32+RTThreadOS22/92流程参照下图:标题startup_stm32f10x_hd.sstm32F103VEstm32f10x_it.cserial.cecho.c阶段产生中断USART1_IRQ查找中断向

1 / 92
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功