首页 > 编程语言 >关于IAP操作的实战——利用主程序向FLASH里写入数据

关于IAP操作的实战——利用主程序向FLASH里写入数据

时间:2024-09-23 14:24:04浏览次数:3  
标签:主程序 ADDR FLASH 写入 USER Array IAP

#1.前言

什么是IAP:就是能通过我们写入的程序向FLASH里烧录数据,达到断电记录参数的功能。

        列如我所使用的这款芯片SC32M15X ,是M0的内核。支持IAP操作,有个IAP操作寄存器,来控制对FLASH的写入。

我放以下截图,供大家参考

解锁寄存器

#2.如何操作IAP

我们先需要解锁IAP,然后确定想写入的FLASH地址,在地址空间表上有直接的说明,我这选用的是0xE800000地址空间。

写入FLASH其实也就是直接在相应的存空间赋值,比如说要写入一个0x1234的数,两个字节。我们可以*((short*)(0xE800000))=0x1234。这样就将这个地址空间写入数据了,由于这个空间对应的是FLASH,所以我们也就将值写入了FLASH。下次读取的时候去读取该地址就行:咱们先定义一个变量short a;然后用这个变量去读取之前写入0x1234的地址,a=*((short*)(0xE800000))。这时候你去读取a的值也就是0x1234。这样也就是做到了可以在程序中断电保存参数。

注意,在FLASH空间里都是按页存放的(512字节)。而且存放数据前要擦除整页数据,擦除数据我这款MCU是往对应的寄存器的BIT位上置1。稍后给大家看看后续代码

#3.代码实例

大家可以看这个示范代码

void IAP_Program_Function(void)
{
	uint32_t ReadWord = 0;
	uint16_t ReadHalfWord = 0;
	uint8_t ReadByte = 0;
	
	uint32_t Array_WriteWord[3]={0x11223344,0x22334455,0x33445566}, Array_ReadWord[3];
	uint16_t Array_WriteHalfWord[5]={0x1111,0x2222,0x3333,0x4444,0x5555}, Array_ReadHalfWord[5];
	uint8_t Array_WriteByte[5]={0x99,0x88,0x77,0x66,0x55}, Array_ReadByte[5];
    uint8_t Flag_ReadWord = 0, Flag_ReadHalfWord = 0, Flag_ReadByte = 0, i;
	
	IAP_Unlock();	//解锁IAP操作
	IAP_EraseSector((FLASH_USER_ADDR - FLASH_BASE) / 512);	//擦除地址所在扇区,每个扇区大小为512Byte
	IAP_WriteCmd(ENABLE);	//开启写使能
	
/* 单个数据依次写入(注意地址对齐) */
	IAP_ProgramWord(FLASH_USER_ADDR,0x12345678);	//字写入,目标地址FLASH_USER_ADDR
	IAP_ProgramHalfWord(FLASH_USER_ADDR+4,0x6666);  //半字写入,目标地址(FLASH_USER_ADDR+4)
	IAP_ProgramByte(FLASH_USER_ADDR+6,0x99); //字节写入,目标地址((FLASH_USER_ADDR+4)+2)
	
/* 批量数据写入 */
//写入地址请勿重合!写入数据请勿超出扇区范围!
	IAP_ProgramWordArray(FLASH_USER_ADDR+20,Array_WriteWord,3);//批量字写入
	IAP_ProgramHalfWordArray(FLASH_USER_ADDR+40,Array_WriteHalfWord,5);//批量半字写入
	IAP_ProgramByteArray(FLASH_USER_ADDR+60,Array_WriteByte,5);//批量字节写入
	
	IAP_Lock();	//上锁IAP操作,并且复位IAP操作寄存器
	
/* 单个数据依次读取 */
	ReadWord = IAP_ReadWord(FLASH_USER_ADDR); //字读,目标地址(0x803FE00)
	ReadHalfWord = IAP_ReadHalfWord(FLASH_USER_ADDR+4); //半字读,目标地址(0x803FE00+4=0x803FE04)
	ReadByte = IAP_ReadByte(FLASH_USER_ADDR+6); //字节读,目标地址(0x803FE04+2=0x803FE06)
	
/* 批量数据读取 */
    Flag_ReadWord = IAP_ReadWordArray(FLASH_USER_ADDR+20,Array_ReadWord,3);//批量字读,返回值为读取成功数据大小
	Flag_ReadHalfWord = IAP_ReadHalfWordArray(FLASH_USER_ADDR+40,Array_ReadHalfWord,5);//批量半字读,返回值为读取成功数据大小
	Flag_ReadByte = IAP_ReadByteArray(FLASH_USER_ADDR+60,Array_ReadByte,5);//批量字节读,返回值为读取成功数据大小

	if(ReadWord == 0x12345678 && ReadHalfWord == 0x6666 && ReadByte == 0x99)//单个数据读写判断
	{
		if(Flag_ReadWord == 3 && Flag_ReadHalfWord == 5 && Flag_ReadByte == 5)//批量写入成功个数判断
		{
		  IAP_Flag = 1;	
		}
	}

一开始先解锁IAP寄存器,按照不同芯片的说明书去解锁,然后写入单个字节和多个字节,我给大家贴一下源码。

单字节写入

boolType IAP_ProgramWord(uint32_t Address, uint32_t Data)
{
	assert_param(IS_IAP_ADDRESS(Address));

  *(__IO uint32_t*)Address = Data;
  if(Data == *(__IO uint32_t*)Address)
    return TRUE;
  else
    return FALSE;


}

多字节写入

uint8_t IAP_ProgramWordArray(uint32_t Address, uint32_t* ByteArray, uint8_t ArraySize)
{
	assert_param(IS_IAP_ADDRESS(Address));

	uint8_t tmpCnt = 0;

	if((Address&0x03)==0)
	{
		do
		{
			*(__IO uint32_t*)Address = ByteArray[tmpCnt];

			if(ByteArray[tmpCnt] != *(__IO uint32_t*)Address)
				break;
			
			Address = Address + 4;
			
		}while(++tmpCnt < ArraySize);
  }
  return tmpCnt;

}

大家看完之后应该也能触类旁通,就是用不同类型指针去访问该地址,如果要写入一个数组也就是需要加个for循环去多次写入.

#4.总结

IAP就是让FLASH在内存地址的映射能够直接写访问。让我们的程序也能对FLASH进行烧录,存放需要被记忆的参数。

因此我认为我们还可以围绕这个功能做更多的应用,比如让程序烧录更新程序,实现程序更新,而不需要使用烧录器进行更新。将这个FLASH空间进行划分,一部分是程序入口地址那部分放入主程序,然后划分一部分空间来接收更新程序。然后更新完后让cpu从更新程序那边开始进行,如此实现程序更新迭代。

目前我这个程序内部更新还是一个想法,还没有实现。希望各位前辈同仁能不吝赐教。在此拜谢

标签:主程序,ADDR,FLASH,写入,USER,Array,IAP
From: https://blog.csdn.net/xc_mt/article/details/142455042

相关文章