历史上的今天
今天是:2024年11月02日(星期六)
2020年11月02日 | STM32, Flash DFU芯片,内部flash,代码升级
2020-11-02 来源:eefocus
这次要讲讲如何用USB升级单片机代码。以前曾经做过串口升级,网络升级,升级的基本原理都类似,只不过升级的工具不同罢了,串口升级当然是用串口了,网络升级用的是TCP/IP,USB升级当然用的是USB了。下面就来讲讲USB升级的实现。
修改部分部分都在USB_User组里:
STM32 Internal Flash DFU芯片内部flash代码升级 - ziye334 - ziye334的博客我们一个一个文件讲过来。
首先讲讲hw_config.c,这个文件跟之前工程差不多。由于演示的需要,我们在这个文件里初始化一个按键引脚,并定义按键读取函数,该按键决定代码是否升级,如果程序一开始,该按键按下,则进入升级模式,否则跳转到升级程序代码处:
/*******************************************************************************
* Function Name : DFU_Button_Config.
* Description : 配置DFU模式选择按键.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_Button_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DFU, ENABLE);
/* 配置DFU按键*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = DFU_ENTER_PIN;
GPIO_Init(DFU_ENTER, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : DFU_Button_Read.
* Description : 读取DFU按键是否按下
* Input : None.
* Output : None.
* Return : 返回0:按键按下;1:按键没有按下
*******************************************************************************/
uint8_t DFU_Button_Read (void)
{
return GPIO_ReadInputDataBit(DFU_ENTER, DFU_ENTER_PIN);
}
usb_desc.c这个文件自然要修改的,USB的功能属性等全在这里定义。首先必须关注下设备描述度符,这里有一点需要强调,就是厂商ID域的值必须为0483,否则电脑不识别USB,产品ID可以自定义。
/* USB标准设备描述符*/
uint8_t DFU_DeviceDescriptor[DFU_SIZ_DEVICE_DESC] =
{
0x12, /*bLength:长度,设备描述符的长度为18字节*/
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType:类型,设备描述符的编号是0x01*/
0x00, /*bcdUSB:所使用的USB版本为2.0*/
0x02,
0x00, /*bDeviceClass:设备所使用的类代码*/
0x00, /*bDeviceSubClass:设备所使用的子类代码*/
0x00, /*bDeviceProtocol:设备所使用的协议*/
0x40, /*bMaxPacketSize:最大包长度为64字节*/
0x83, /*idVendor:厂商ID为0x1234*/
0x04,
0x11, /*idProduct:产品ID为0x1010*/
0xDF,
0x00, /*bcdDevice:设备的版本号为2.00*/
0x02,
1, /*iManufacturer:厂商字符串的索引*/
2, /*iProduct:产品字符串的索引*/
3, /*iSerialNumber:设备的序列号字符串索引*/
0x01 /*bNumConfiguration:设备有1种配置*/
}; /* DFU设备描述符 */
接下去是配置描述符集合,配置描述符不需要修改。但之后的接口描述符的 bNumEndpoints域(该接口所使用的端点数)需要设置成0,因为USB DFU值需要端点0,不不需要其他的端点;接口描述符的bInterfaceClass(该接口所使用的类)域的值为0xFE,表示使用DFU类接口;接口描述符的bInterfaceSubClass(该接口所用的子类)设置成0x01,表示boot用途;接口描述符的nInterfaceProtocol设置成0x2,即DFU模式;最后还要设置接口字符串描述符的索引值为4。接下去是DFU功能描述符,这里设置bmAttribute域USB的属性为0x0B(具体意义看下面代码);DetachTimeOut(超时时间)设置成0XFF,表示超时时间为255ms;接下去设置TransferSize:(传输的长度)为0x400,注意这里是用两字节小端模式表示。
/* USB配置描述符集合(配置、接口、端点、类、厂商)(Configuration, Interface, Endpoint, Class, Vendor */
uint8_t DFU_ConfigDescriptor[DFU_SIZ_CONFIG_DESC] =
{
0x09, /*bLength:长度,设备字符串的长度为9字节*/
USB_CONFIGURATION_DESCRIPTOR_TYPE, /*bDescriptorType:类型,配置描述符的类型编号为0x2*/
DFU_SIZ_CONFIG_DESC, /*wTotalLength:配置描述符的总长度为41字节*/
0x00,
0x01, /*bNumInterfaces:配置所支持的接口数量1个*/
0x01, /*bConfigurationValue:该配置的值*/
0x00, /*iConfiguration:该配置的字符串的索引值,该值为0表示没有字符串*/
0xC0, /* bmAttributes:设备的一些特性,0xc0表示自供电,不支持远程唤醒
D7:保留必须为1,D6:是否自供电,D5:是否支持远程唤醒,D4~D0:保留设置为0*/
0x32, /*从总线上获得的最大电流为100mA */
// 0x96, /*MaxPower:设备需要从总线上获取多少电流,单位为2mA,0x96表示300mA*/
/****** Descriptor of DFU interface 0 Alternate setting 0***********/
0x09, /*bLength:长度,接口描述符的长度为9字节 */
USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType:接口描述符的类型为0x4 */
0x00, /*bInterfaceNumber:该接口的编号*/
0x00, /*bAlternateSetting:该接口的备用编号 */
0x00, /*bNumEndpoints:该接口所使用的端点数*/
0xFE, /*bInterfaceClass该接口所使用的类为 DFU*/
0x01, /*bInterfaceSubClass:该接口所用的子类 1=BOOT, 0=no boot */
0x02, /*nInterfaceProtocol :DFU模式*/
4, /* iInterface:接口字符串描述符的索引 */
/******************** DFU功能描述符********************/
0x09, /*blength:DFU描述符的长度为9字节*/
0x21, /*功能描述符的类型为0x21*/
0x0B, /*bmAttribute
bitCanDnload = 1 (bit 0) 下载性能
bitCanUpload = 1 (bit 1) 上传性能
bitManifestationTolerant = 0 (bit 2) 设备在心事阶段后是否可通过USB通讯
bitWillDetach = 1 (bit 3) 接收到DFU_DETACH命令时会进行总线detach-attac
Reserved (bit4-6) 保留
bitAcceleratedST = 0 (bit 7) 该为置1,设备将会上传速度增加到4096字节/命令*/
0xFF, /*DetachTimeOut:超时时间 255 ms*/
0x00,
wTransferSizeB0,
wTransferSizeB1, /* TransferSize:传输的长度为1024 Byte*/
0x1A, /* bcdDFUVersion:DFU协议版本*/
0x01
};
接下去的语言字符串描述符、厂商字符串描述符、产品字符串描述符、序列号字符串描述符都不详细介绍了。
/* 语言ID描述符 */
uint8_t DFU_StringLangId[DFU_SIZ_STRING_LANGID] =
{
DFU_SIZ_STRING_LANGID, /*bLength:本描述符的长度为4字节*/
USB_STRING_DESCRIPTOR_TYPE, /*bDescriptorType:字符串描述符的类型为0x03*/
0x09, /*bString:语言ID为0x0409,表示美式英语*/
0x04
}; /* LangID = 0x0409: U.S. English*/
/*厂商字符串描述符*/
uint8_t DFU_StringVendor[DFU_SIZ_STRING_VENDOR] =
{
DFU_SIZ_STRING_VENDOR, /*bLength:厂商字符串描述符的长度*/
USB_STRING_DESCRIPTOR_TYPE, /*bDescriptorType:字符串描述符的类型为0x03*/
'B' , 0, 'y', 0, ':' , 0, 'z' , 0, 'i', 0, 'y', 0,'e', 0,'3', 0, '3', 0, '4', 0 /*自定义*/
};
/*产品的字符串描述符*/
uint8_t DFU_StringProduct[DFU_SIZ_STRING_PRODUCT] =
{
DFU_SIZ_STRING_PRODUCT, /* bLength:产品的字符串描述符*/
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType:字符串描述符的类型为0x03*/
'z', 0, 'i', 0, 'y', 0, 'e', 0, '3', 0, '3', 0 ,'4',0/*自定义*/
};
/*产品序列号的字符串描述符*/
uint8_t DFU_StringSerial[DFU_SIZ_STRING_SERIAL] =
{
DFU_SIZ_STRING_SERIAL, /* bLength:产品序列号*/
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType:字符串描述符的类型为0x03*/
'1', 0, '2', 0, '3', 0,'4', 0,'5', 0, '6', 0, '7', 0 /*自定义*/
};
重点介绍的是接口字符串描述符,这个字符串描述符定义了升级的硬件信息,如下是我们的接口描述符:
/*接口字符串描述符*/
uint8_t DFU_StringInterface0[DFU_SIZ_STRING_INTERFACE0] =
{
DFU_SIZ_STRING_INTERFACE0,
0x03,
// Interface 0: "@Internal Flash /0x08000000/12*001Ka,500*001Kg"
'@', 0, 'I', 0, 'n', 0, 't', 0, 'e', 0, 'r', 0, 'n', 0, 'a', 0, 'l', 0, /* 18 */
' ', 0, 'F', 0, 'l', 0, 'a', 0, 's', 0, 'h', 0, ' ', 0, ' ', 0, /* 16 */
上一篇:STM32 USB工程的文件分析
史海拾趣
|
功能强劲的程序编辑器SourceInsight-v3.50.0050 功能强劲的程序编辑器SourceInsight-v3.50.0050 Source Insight是一个功能强劲的程序编辑器,他内置对C/C++,Java和x86汇编语言程序的解析;有自己的动态数据库在你编程时提供有用的文本提示,包括有关的函数,宏,参数等! 如今最好用的语言编辑 ...… 查看全部问答> |
|
SQL Mobile 在Wince5.0 Arm下的安装问题 (SQL CE 3.0) 我在WinCE5.0 ARM的系统安装SQL Mobile 安装过程如下: 复制 * NETCFv2.wce5.armv4i.cab * sqlce30.wce5.armv4i.CAB * sqlce30.dev.ENU.wce5.armv4i.CAB * sqlce30.repl.wce5.armv4i.CAB 到WinCE5.0中,然后分别安装,都提示安装成功。 安 ...… 查看全部问答> |
|
在TI E2E社区中发现了几篇不错的文章,特意翻译过来分享给大家,其中Bruce Trump系列关于放大器有很好的见解,特此供大家学习和参考。 此篇是连载文章,欲知更多精彩内容,请查看我的其他分享! 摘要:鉴于反馈通路中相移(或者称作延迟)引起 ...… 查看全部问答> |
|
本帖最后由 shower.xu 于 2015-3-24 00:05 编辑 几经破折,今天板子才拿到手,结果发现不是之前的那块板子,只有重新搜集资料。 找了半天,基本是大家的各种吐槽,算了吧万事总有开头,花了一晚上时间测量了几个外设的脚位接口,修改了之前板子 ...… 查看全部问答> |




