STM32串口IAP(YModem)

2019-06-14来源: eefocus关键字:STM32  串口IAP  YModem

在之前的《STM32串口IAP》一文中,通过传输数据流来升级程序,但是这种"裸"数据的传输方式存在这许多的问题,比如它没有容错机制,不能保证数据的正确传输,还比如说它无法获知升级文件的信息,导致它在判断何时停止接收数据上“犹豫不决”。正式为了解决上面的问题,才引进了YModem协议。

在《YModem协议简介》一文中,已经详细介绍了YModem的协议,这里就不再赘述,这篇文章就来讲讲如何将YModem协议转换成代码,并应用到串口升级的功能中。

还是以我自己的规范工程为例,讲讲走YModem协议的IAP工程的的实现。

1、工程的修改

1)串口升级当然需要用到USART与FLASH了,我的原工程已经添加了串口的库文件stm32f10x_usart.c与stm32f10x_flash.c,所以就不需要在添加这两个文件了。

2)新建IAP.c和IAP.h两个文件分别保存到BSP文件夹下的src与inc两个文件中。并将IAP.c文件添加到BSP工程组中。

3)新建YMoem.c和YMoem.h两个文件分别保存到BSP文件夹下的src与inc两个文件中。并将YModem.c文件添加到BSP工程组中。

4)新建Download.c和Download.h两个文件分别保存到BSP文件夹下的src与inc两个文件中。并将Download.c文件添加到BSP工程组中。

5)新建Upload.c和Upload.h两个文件分别保存到BSP文件夹下的src与inc两个文件中。并将Upload.c文件添加到BSP工程组中。

也就是说在BSP的工程组中有:BSP.c、IAP.c、YModem.c、Download.c、Upload.c这几个文件,如下:

STM32串口IAP(YModem) - ziye334 - ziye334的博客

 

2、IAP.c与IAP.h的编写

这个文件与之前在《STM32串口IAP》一文中的IAP.c与IAP.h文件代码相似,只是做了细微的一些调整,不过这里还是仔细讲述下。

同样的考虑到开发板资源,我采用串口1作为升级的通道,所以原先在规范工程中作为调试接口的串口1的相关代码需要从BSP.c与BSP.h两个文件中完全删除掉,出现此之外还要打开stm32f10x_it.c文件中将串口中断服务程序的相关代码删除掉。

与完成一样,IAP.c中第一个函数就是IAP_Init(),在这个函数中,配置串口相关的代码,如配置串口引脚,串口时钟,串口属性,串口中断等,具体的代码如下:

/*************************************************************  Function   : IAP_Init   Description: IAP初始化函数,初始化串口1  Input      : none          return     : none    *************************************************************/void IAP_Init(void){	GPIO_InitTypeDef GPIO_InitStructure;	USART_InitTypeDef USART_InitStructure;	RCC_APB2PeriphClockCmd(COM1_RCC, ENABLE);//使能 USART2 时钟	RCC_APB2PeriphClockCmd(COM1_GPIO_RCC, ENABLE);//使能串口2引脚时钟	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//配置 USART2 的Tx 引脚类型为推挽式的	GPIO_InitStructure.GPIO_Pin = COM1_TX_PIN;        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	GPIO_Init(COM1_GPIO_PORT, &GPIO_InitStructure);        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//配置 USART2 的Rx 为输入悬空        GPIO_InitStructure.GPIO_Pin = COM1_RX_PIN;        GPIO_Init(COM1_GPIO_PORT, &GPIO_InitStructure);	USART_InitStructure.USART_BaudRate = 115200;//设置波特率为115200	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//设置数据位为8位	USART_InitStructure.USART_StopBits = USART_StopBits_1;//设置停止位为1位	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验    	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //没有硬件流控	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送与接收	USART_Init(COM1,&USART_InitStructure);//串口2相关寄存器的配置	USART_Cmd(COM1,ENABLE);//使能串口2	}

上面的代码中可以看出,这次我没有打开串口中断,而是使用查询法来接收串口数据。

接下去在编写串口的发送接收程序,代码如下:

/*************************************************************  Function   : IAP_SerialSendByte   Description: 串口发送字节  Input      : c-要发送的字节          return     : none    *************************************************************/void IAP_SerialSendByte(u8 c){	USART_SendData(COM1, c);	while (USART_GetFlagStatus(COM1, USART_FLAG_TXE) == RESET) {}}/*************************************************************  Function   : IAP_SerialSendStr   Description: 串口发送字符串  Input      : none          return     : none    *************************************************************/void IAP_SerialSendStr(u8 *s){	while(*s != '')	{		IAP_SerialSendByte(*s);		s++;	}}/*************************************************************  Function   : IAP_SerialGetByte   Description: 接收一个字节数据  Input      : none          return     : 返回结果值,0-没有接收到数据;1-接收到数据    *************************************************************/u8 IAP_SerialGetByte(u8 *c){	if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)	{		*c = USART_ReceiveData(USART1);		return 1;	}  	return 0;}

可以看到串口接收函数IAP_SerialGetByte()仅仅是查询下是否有数据接收到,但无论是否接收到数据,程序都不会在这个函数上阻塞。所以为了实现阻塞的效果,还需要稍微做下文章,下面就提前讲讲如何在IAP_SerialGetByte()的基础上修改成阻塞的功能,如下获取一个用户输入键值的函数:

/*************************************************************  Function   : IAP_GetKey   Description: 获取键入值  Input      : none          return     : 返回键值    *************************************************************/u8 IAP_GetKey(void){	u8 data;	while(!IAP_SerialGetByte(&data)){ }	return data;}

然后再设计Bootload的界面,更《STM32串口IAP》一文给出的界面基本上一样,如下:

/*************************************************************  Function   : IAP_ShowMenu   Description: 显示菜单界面  Input      : none          return     : none    *************************************************************/void IAP_ShowMenu(void){	IAP_SerialSendStr("rn+================(C) COPYRIGHT 2014 Ziye334 ================+");	IAP_SerialSendStr("rn|    In-Application Programing Application (Version 1.0)    |");	IAP_SerialSendStr("rn+----command----+-----------------function------------------+");	IAP_SerialSendStr("rn|  1: FWUPDATA  | Update the firmware to flash by YModem    |");	IAP_SerialSendStr("rn|  2: FWDWLOAD  | Download the firmware from Flash by YModem|");	IAP_SerialSendStr("rn|  3: FWERASE   | Erase the current firmware                |");	IAP_SerialSendStr("rn|  4: BOOT      | Excute the current firmware               |");	IAP_SerialSendStr("rn|  5:REBOOT    | Reboot                                    |");	IAP_SerialSendStr("rn|  ?: HELP      | Display this help                         |");	IAP_SerialSendStr("rn+===========================================================+");	IAP_SerialSendStr("rnrn");	IAP_SerialSendStr("STM32-IAP>>");}

界面与之前相比,唯一的区别在于多了一个FWDWLOAD的选项,提供用户从STM32上下载升

[1] [2] [3] [4] [5] [6] [7] [8]

关键字:STM32  串口IAP  YModem

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic464672.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm32 Bootloader设计(YModem协议)
下一篇:STM32定时器的预装寄存器以及影子寄存器话题

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

第38章 I2S—音频播放与录音输入—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》及《I2S BUS》。若对I2S通讯协议不了解,可先阅读《I2S BUS》文档的内容学习。关于音频编译码器WM8978,请参考其规格书《WM8978_v4.5》来了解。38.1 I2S简介Inter-IC Sount Bus(I2S)是飞利浦半导体公司(现为恩智浦半导体公司)针对数字音频设备之间的音频数据传输而制定的一种总线标准。在飞利浦公司的I2S标准中,既规定了硬件接口规范,也规定了数字音频数据的格式。38.1.1 数字音频技术现实生活中的声音是通过一定介质传播
发表于 2019-09-19
第38章 I2S—音频播放与录音输入—零死角玩转STM32-F429系列

第50章 读写内部FLASH—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、库说明文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。50.1 STM32的内部FLASH简介在STM32芯片内部有一个FLASH存储器,它主要用于存储代码,我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部FLASH中,由于FLASH存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部FLASH中加载代码并运行,见图 501。图 501 STM32的内部框架图除了使用外部的工具(如下载器)读写内部FLASH外,STM32芯片在运行的时候,也能对自身的内部FLASH进行读写
发表于 2019-09-19
第50章 读写内部FLASH—零死角玩转STM32-F429系列

第49章 在SRAM中调试代码—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、《Cortex-M3权威指南》、《Cortex-M4 Technical Reference Manual》(跟M3大部分是相同的,读英文不习惯可先参考《Cortex-M3权威指南》)。学习本章时,配合《STM32F4xx 中文参考手册》"存储器和总线结构"及"嵌入式FLASH接口"章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。49.1 在RAM中调试代码一般情况下,我们在MDK中编写工程应用后,调试时都是把程序下载到芯片的内部FLASH运行测试的,代码的CODE及RW-data的内容被写入
发表于 2019-09-19
第49章 在SRAM中调试代码—零死角玩转STM32-F429系列

第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429

本章参考资料:MDK的帮助手册《ARM Development Tools》,点击MDK界面的"help->uVision Help"菜单可打开该文件。关于ELF文件格式,参考配套资料里的《ELF文件格式》文件。在本章中讲解了非常多的文件类型,学习时请跟着教程的节奏,打开实际工程中的文件来了解。相信您已经非常熟练地使用MDK创建应用程序了,平时使用MDK编写源代码,然后编译生成机器码,再把机器码下载到STM32芯片上运行,但是这个编译、下载的过程MDK究竟做了什么工作?它编译后生成的各种文件又有什么作用?本章节将对这些过程进行讲解,了解编译及下载过程有助于理解芯片的工作原理,这些知识对制作IAP
发表于 2019-09-19
第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429

第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。关于开发板配套的OV5640摄像头参数可查阅《ov5640datasheet》配套资料获知。STM32F4芯片具有浮点运算单元,适合对图像信息使用DSP进行基本的图像处理,其处理速度比传统的8、16位机快得多,而且它还具有与摄像头通讯的专用DCMI接口,所以使用它驱动摄像头采集图像信息并进行基本的加工处理非常适合。本章讲解如何使用二维码识别库进行二维码的识别。47.1 二维码简介二维码,又称二维条码或二维条形码,二维条码是用某种特定的几何图形按一定规律在平面(二维方向
发表于 2019-09-19
第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

第44章 MPU6050传感器—姿态检测—零死角玩转STM32-F429系列

本章参考数据:《STM32F4xx参考手册》、《STM32F4xx规格书》、库说明文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。关于MPU6050的参考资料:《MPU-60X0寄存器》、《MPU6050数据手册》以及官方驱动《motion_driver_6.12》。本章讲解的内容跨领域的知识较多,若您感兴趣,请自行查阅各方面的资料,对比学习。44.1 姿态检测1.    基本认识在飞行器中,飞行姿态是非常重要的参数,见图 441,以飞机自身的中心建立坐标系,当飞机绕坐标轴旋转的时候,会分别影响偏航角、横滚角及俯仰角。图 441 表示飞机姿态的偏航角、横滚角及俯仰角假如我们知道飞机
发表于 2019-09-19
第44章 MPU6050传感器—姿态检测—零死角玩转STM32-F429系列

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved