使用STM32G030进行IAP远程升级

网上有一篇F系列的远程升级,移植过来的时候可以用,但是缺芯得换成G系列的,使用的方法也不一样,所以移植的时候难免有些坑,所以来记录一下

不同之处

1.对于flash的操作

HAL库里,F系列的G系列的flash的操作不太一样,我了解的有以下几点:
①.F系列支持最小单字节写入,而G系列最小写入单位是64位或者双32位快速编程。
所以在写入的时候,如果是单字节类型,需要转换为64位类型的数组,还要注意的是stm是小端模式,在写入的时候需要把高低字节转换一下,还有经过我实验得到,用keil烧录程序的时候,也是按照64位来写入的,所以就不用担心在远程升级的时候,4字节写入还要自己再转换一下,下面是我写的flash写入函数
参数:地址必须能被8整除;传入的是单字节的数组;长度是传入数组的长度

//写flash
//参数:addr:写入地址;buff:单字节数组;word_size:写入数组长度
uint64_t flash64_buf[30];
void MyWrite_Flash(uint32_t addr, unsigned char * buff, int word_size)
{	
	/* 1/4解锁FLASH*/
	uint8_t len,i,j;
	HAL_FLASH_Unlock();

	if(word_size%8)
  {
     len=word_size/8+1;
  } 
  else
  {
    len=word_size/8;
  } 
	
	for(i=0;i<len;i++)//这个是要转多少组
	{
			for(j=0;j<8;j++)//这个是转8个字节
			{
				flash64_buf[i]|=(uint64_t)buff[j+i*8]<<(j*8);
			}	
	}
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);//清除标志位
	for(int i = 0; i < len; i++)	
	{
		/* 3/4对FLASH烧写*/
		//g030是64位双字编程或以32个双字为单位的快速行编程
		//HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)(uint64_t *)addr + 8 * i, *(uint64_t *)&flash_buf[i*2]);	//地址要求8字节对齐,地址递增是8的倍数
		HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)(uint64_t *)addr + (8 * i), flash64_buf[i]);
	}
	//flash64_buf清0
	for(i=0;i<=29;i++)
	{
		flash64_buf[i]=0;
	}
	/* 4/4锁住FLASH*/
	HAL_FLASH_Lock();
}

②.不一样的是擦除的结构体,F系列是自定义位置擦除,而G系列擦除flash的结构体的三个成员是:擦除方法;从第几页擦除;擦除多少页
F系列每页1K,而G0是每页2K,我用的是G030,一共64k,所以是32页
下面是我的擦除函数

int MyErase_page(uint32_t pageaddr, uint32_t num)
{
	uint32_t PageError = 0;
	HAL_FLASH_Unlock();
	
	/* 擦除FLASH*/
	FLASH_EraseInitTypeDef FlashSet;

	FlashSet.TypeErase = FLASH_TYPEERASE_PAGES;//页编辑
	FlashSet.NbPages = num;//擦除页数
	FlashSet.Page=pageaddr;//从哪一页开始
	 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);//清除标志位
	/*设置PageError,调用擦除函数*/
	
	HAL_FLASHEx_Erase(&FlashSet, &PageError);
	
	HAL_FLASH_Lock();
	return 1;
}

读的话没有什么限制,就是自己想读多少读多少,可以一次读单字节也可以一次读四字节,下面是我的读函数

//读4字节
static void MyRead32Flash(uint32_t addr, uint32_t * buff, uint16_t word_size)
{
	for(int i =0; i < word_size; i++)
	{
		buff[i] = *(__IO uint32_t*)(addr + 8 * i);
	}
	return;
}

2.升级方法不同

①原先参考的思路是,划分三个区域,一个boot loader,一个APP1,一个APP2,boot loader负责引导程序启动,APP1存放运行的代码,APP2存放升级的代码,这样就很浪费内存,改变为:
由boot loader来接收代码,一次接收240个字节,接到进行校验,正确的话直接写到flash,这样就能有很多空间用来挥霍了
②升级的协议不一样。参考的代码是用ymodem协议来做的,这个方法比较稳重,但是为了配合4G模块厂家,还是直接用他们给的协议,解析包头包尾和累加校验。其实我觉得都差不多,目的都是为了接到正确的数据帧,就看校验的方法好不好
③升级用到的串口通信方法不同。众所周知,串口通信的方式一般有三种,中断,超时,还有空闲中断,然后一般新手入门的时候,在用串口总会面对一个问题,就是接收不定长数据,解决这个的方法我知道的有两个,一个就是空闲中断,另一个方法就是用定时器自己写一个空闲中断,这样的话接收一帧数据的时间就能自己控制,这个在用于modbus非常的友好。参考的程序是用空闲中断,而我用的是中断加定时器

遇到的坑

遇到的坑还是挺多的,俗话说的好:_________________。

1.不能打断点

做远程升级的,肯定都知道bootloader,写boot loader的,肯定都知道跳转函数__asm void MSR_MSP,也不知道为什么,我加了这个之后,debug的时候,添加有这个函数的源文件里的函数,都不能打断点了,解决方法就是把这个汇编函数和跳转函数放到其他源文件

2.进不到for循环

这个问题非常的奇怪,程序一步步的执行下去,什么都没有问题,就是进不去,后来在网上找了很久,发现了这个,优化等级,只要把这个改为0,就能执行进去了
在这里插入图片描述

3.4G模块Air724UG接收不到正常的数据

对于一个刚出来的新手,硬件知识还比较薄弱,对于一些模块就是拿来就用,不会有什么怀疑。在用4G接收第一帧升级文件的时候,总是接不到正常的数据,一直以为是代码的问题,然后用串口直连发现也收不到正确的数据,但是用模块自带的USB来供电的时候就正常,然后请软硬件两个大佬来救场,用示波器看在接收数据的时候电平不正常,判断是在接收的时候电平被拉低了,原因是模块上的两组串口同时共用一个CH340芯片,导致使用的时候电压不够,然后把模块上的CH340芯片挑下来,就能正常接收了。看模块的手册感觉在单片机和模块的串口之间接一个电阻可能也可以,但是还没试过。以后得多补补硬件的知识。

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要下载STM32G0固件库,需要按照以下步骤进行操作。 首先,前往STMicroelectronics官方网站(www.st.com)。 然后,在页面的顶端,找到“产品”菜单,并将鼠标悬停在上面。 接下来,在下拉菜单中,选择“微控制器”子菜单。 然后,在新页面的左侧,您会看到一系列的微控制器系列,找到并点击“STM32G0系列”。 接下来,您将进入该系列的页面。在该页面上,找到“软件和工具”标签,并点击它。 然后,在“软件和工具”页面上,您会看到内容的左侧有一个菜单栏。在菜单栏中,选择“固件”选项。 接下来,在“固件”页面上,您将看到可用的固件库。找到适合您的需要的版本,并点击它。 然后,您将看到固件库的详细信息页面,包括版本号和可下载文件的列表。在该页面上,您可以找到“下载”按钮并点击它。 接下来,您将被引导到一个新页面,要求您同意STMicroelectronics的使用条款。仔细阅读条款,并如果同意,请在提示处勾选“接受”选项,然后点击“下载”按钮。 然后,文件将开始下载到您的计算机。请耐心等待下载完成。 最后,一旦下载完成,您就可以使用下载的STM32G0固件库进行开发和编程了。 总结来说,下载STM32G0固件库需要前往STMicroelectronics官方网站,浏览到STM32G0系列的页面,并进入“软件和工具”选项卡下的“固件”页面。从可用的固件库中选择适合您的版本,同意使用条款后进行下载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值