STM32F0:SD卡升级

前文说过,在STM32F0xx系列芯片上进行IAP升级,使用串口方式进行IAP升级确实简单。但是实际操作中并不方便:因为需要串口线,电脑,外加电脑端的UI,而且操作繁琐不便于远程升级。

串口IAP链接:

https://blog.csdn.net/triv2009/article/details/78706013

也有GPRS方式IAP的,但是硬件成本高,开发难度大,维护时间长,只适合车辆网用途而已。

而本次推荐的是使用SD/TF卡方式进行IAP升级,操作更为简单些,只需要提供*.bin文件即可插卡升级。

当然SD卡升级的方式需要硬件上增加SD/TF卡座,需要SPI接口(3线,SCK,SDI,SDO),不过算起来这增加的硬件成本也不高,一个SD/TF卡座的硬件成本也就0.5RMB以内,唯一缺点是占用PCB空间较大。


然后说说软件该怎么改,由于读写SD/TF卡需要文件系统,特别是"读文件"操作比较占用FLASH空间,所以IAP段占用的地址空间就特别大,一般都要0x3000的空间,就算经过中等优化,也得0x2200。IAP段要占用12K空间,对于STM32F0xxF4之类只有16K FLASH来说,这确实够呛,所以至少需要32K或以上的FLASH空间才适合使用SD/TF卡的升级方式。

//------------------------------------------------------------------------------------------------------------------

SPI初始化:

//使能APB2上相关时钟
//使能SPI时钟,使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 ,ENABLE );
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5|GPIO_PinSource6|GPIO_PinSource7, GPIO_AF_0);

GPIO_InitStructure.GPIO_Pin = PA5_SPI1_SCK  |  PA7_SPI_MOSI | PA6_SPI1_MISO; 
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;     //输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //速度
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //PP推挽、OD开漏输出,只对输出模式起作用
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;  //UP上拉、DOWN下拉、NOPULL无
GPIO_Init(GPIOA,&GPIO_InitStructure);

//自定义SPI结构体
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; 
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;        
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;      
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;         //MSS 端口软件控制,实际没有使用
SPI_InitStructure.SPI_BaudRatePrescaler = BaudRatePrescaler; 
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; 
SPI_InitStructure.SPI_CRCPolynomial = 7;//
SPI_Init(SPI1, &SPI_InitStructure);
SPI_SSOutputCmd(SPI1,ENABLE);//把使能SPI口的SS输出功能
SPI_Cmd(SPI1, ENABLE); 

//然后最最最重要的是读BIN文件用的函数:

rc = f_open(&fil, "CANBUS.BIN", FA_READ);//打开指定的BIN文件,文件名自定义,但是定义好了就不能改,否则读不出来

rc = f_read(&fil, buff, MCU_BIN_UPGRADE_BUFF_MAX, &br);//读这个文件

这两个函数原型是酱紫的:

FRESULT  f_open (
FIL *fp, /* Pointer to the blank file object */
const TCHAR *path,/* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)

FRESULT f_read (
FIL *fp, /* Pointer to the file object */
void *buff, /* Pointer to data buffer */
UINT btr, /* Number of bytes to read */
UINT *br /* Pointer to number of bytes read */
)

就整个IAP代码来说,这两个函数及其需要的资源占用了非常多的FLASH空间,几乎占了80%。

后面怎么写FLASH就不详细说了,因为和其他的IAP没有两样,都是使用 FLASH_ErasePage+FLASH_ProgramWord方式的。

跳转方式也是一样的,需要更改APP的地址为0x08003000.

还要特别说明一下,为了防止读写BIN文件出现错误,最好增加一个校验文件,读取文件之后再计算校验结果,然后与校验文件进行对比,校验方式的算法自由定义即可。


猜你喜欢

转载自blog.csdn.net/triv2009/article/details/80202647