文章目录
本人STM32开发过程中的一些心得及总结。
比较好的文章
加密
- STM32MCU加密原理与方法 (很详细)
驱动开发
使用CCMRAM内存
CCMRAM 为仅CPU可直接访问的内存,外设不能访问,所以像ADC、USB这些外设是不能使用的,CCMRAM的使用方法大概如下:
取消勾选 Keil --> Options for Target XXX --> Linker --> Use Memory Layout from Target Dialog
,并自定义散列文件:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
;LR_IROM1 0x08000000 0x00080000 { ; load region size_region
;ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
LR_IROM1 0x08010000 0x00080000 { ; load region size_region
ER_IROM1 0x08010000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data
.ANY (+RW +ZI)
}
RW_IRAM2 0x10000000 0x00010000 {
.ANY (CCMRAM)
}
}
在程序中,直接使用:CCMRAM a[10]={0};
串口
USART 单字节传输
USART DMA 传输
网口
注意事项:
- PHY芯片地址
- PHY上电需复位
- 上传间隔不能太小,否则影响传输速度
- 中断组及优先级
比较好用,性能稳定的调试助手 sokit , 注意,发送数据时要选中连接。
- lwip_periodic_handle()函数中的TCP定时器由250ms改为2ms,速度提高了很多,但还是只有0.05M的样子
- 例程里面我们把发送函数放到了LWIP的轮训函数中,那个轮训函数是定时调用的,所以速度不会块,你可以把发送函数单独拿出来调用,这样速度就会快
USB虚拟串口
USB虚拟串口,单字节传输。
需要注意更改设备描述符,本人在开发过程中,遇到一个现象,ST官网提供得PC虚拟串口驱动,只能Win10使用,Win7上仅个别电脑可用,其它电脑出现黄色叹号,最终通过更改设备描述符后正常,如下面代码,将 bDeviceClass
从 0x00
改成 0x02
后正常。
/* USB Standard Device Descriptor */
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
0x00, /*bcdUSB */
0x02,
// 0x00, /*bDeviceClass*/
0x02, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_OTG_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID), /*idVendor*/
HIBYTE(USBD_PID), /*idVendor*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_CFG_MAX_NUM /*bNumConfigurations*/
} ; /* USB_DeviceDescriptor */
在线升级
官方资源
在 ST 官网搜索 IAP,可找到如下 资源
- STSW-STM32067 : STM32F4 in-application programming (IAP) using the USART (AN3965)
- STSW-STM32069 : STM32F4x7 in-application programming (IAP) over Ethernet based on LwIP TCP/IP stack (AN3968)
- X-CUBE-IAP-USART: STM32Cube in-application programming using the USART embedded software (AN4657)
博客资源
- STM32 IAP在线升级教学
- stm32 在线升级的惨痛经历
- WiFi物联中的OTA固件升级设计原理
- ISP与IAP的区别
- 单片机三种烧录方式ISP、IAP和ICP的区别详解
- IAR环境下STM32+IAP方案的实现(转)
- stm32通过485接串口做IAP :USART半双工
- 关于STM32的IAP与APP互相跳转
推荐资源
###重要总结
IAP的升级,需要编写两个程序,一个是bootloader程序,用于启动和升级系统,这里称为IAP程序;另一个是Application应用程序,是你实际要运行的程序,这里称为APP程序。
流程大概是这样:上电后,先启动IAP程序,在IAP程序中判断是否升级标志,若是,则接收更新文件,然后进行校验无误后,写入APP地址区域(FLASH中),然后更改升级标志为否,跳转到APP执行;若否,则直接跳转到APP程序区域执行;在APP程序运行中,也可以根据接收的命令,判断是否进行升级,若升级,更改升级标志,并跳转到IAP程序。
需要注意的是,在跳转前(IAP --> APP,APP --> IAP)必须关闭所有使用的外设和中断,如网口、USB虚拟串口、ADC、DAC等等,防止升级过程中外部中断触发导致升级失败。否则,当在另一程序中开启中断时,MCU会处理之前触发的中断。ARM MDK中提供了如下两个接口来禁用(__disable_irq()
)和开启(__enable_irq()
)总中断。但使用时需注意:
__disable_irq()
只是禁止CPU去响应中断,没有真正的去屏蔽中断的触发,中断发生后,相应的寄存器会将中断标志置位,在__enable_irq()
开启中断后,由于相应的中断标志没有清空,因而还会触发中断。所以要想禁止所有中断,必须对逐个模块的中断进行Disable操作,由于每个模块中断源有很多,对逐个中断Disable的话比较复杂,较为简单的方法是通过XXX_ClearITPendingBit()
清除中断标志或者直接通过XXX_DeInit()
来清除寄存器的状态。这样在__enable_irq()
开启总中断后,MCU就不会响应之前触发的中断了。
在做IAP升级开发时,可以先实现IAP到APP的跳转功能,此时,对于IAP和APP分别需要进行以下设置:
首先分配FLASH的内存,大小和地址任意,但不能重叠:
- IAP
- 加入
JumpToAPP()
跳转程序;
- 加入
- APP
- 设置APP程序地址:
Keil --> Options for Target XXX --> Target --> IROM1
如0x8010000
,并确保Keil --> Options for Target XXX --> Linker --> Use Memory Layout from Target Dialog
勾选,如果不勾选,需要自己定义散列文件(Scatter File .sct),并在散列文件中设置; - 设置中断向量表偏移地址:在APP程序起始处
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000);
; - 打开中断:紧接着上一步
__enable_irq();
- 添加升级协议及APP到IAP跳转程序。
- 设置APP程序地址:
然后,分别下载两个程序到板子即可。
Keil使用
生成bin文件
这里的Output目录与下面的目录一致
问题分析与解决
JTAG与串口
接上JTAG,串口发数正常,拔掉串口发数异常,帧与帧之间会多好些 FF
,网上有很多说法,有种说法是把JTAG与板子断开,而不是只拔USB。
JTAG下载程序
一次烧写程序,错将CPU上的JTAG几个引脚中的一个引脚配成其它的引脚,导致下载时提示,不能与CPU连接,于是断电重试n次,问题依旧。后来灵机一动,在点下载程序按钮的同时上电,而不是在下载程序前上电,成功!!!