首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM32_IAP详解(3)

STM32_IAP详解(3)

首先是iap_set_flag,其响应函数如下

#define APP_CONFIG_ADDR     0X08001FFC //配置地址

#define APP_CONFIG_SET_VALUE    0X5555 //设置值

#define APP_CONFIG_CLEAR_VALUE  0XFFFF //清零值


//设置app固化配置

void iap_set_flag_s(void)

{

    Test_Write(APP_CONFIG_ADDR,APP_CONFIG_SET_VALUE);

    printf("ok\r\n");

}

我们使用0x08000000-0x08003000来存放iap代码,并将0X08001FFC作为存放app固化标志的地方


//清除app固化配置

void iap_clear_flag(void)

{

    Test_Write(APP_CONFIG_ADDR,APP_CONFIG_CLEAR_VALUE);

    printf("ok\r\n");

}

对iap_jump2app命令的响应如下

//跳转到应用程序段

//appxaddr:用户代码起始地址.

void iap_load_app(u32 appxaddr)

{

    if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)  //检查栈顶地址是否合法.0x20000000是sram的起始地址,也是程序的栈顶地址

    {

       printf("ok\r\n");

       Delay_Ms(10);

       jump2app=(iapfun)*(vu32*)(appxaddr+4);    //用户代码区第二个字为程序开始地址(复位地址)      

       MSR_MSP(*(vu32*)appxaddr);                //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)

       jump2app();                               //跳转到APP.

    }

    else

    {

       printf("program in flashis error\r\n");

    }

}


//跳转到app区域运行

void iap_jump_app_s(void)

{

    iap_load_app(FLASH_APP1_ADDR);//跳转到app的复位向量地址

}
接下来就是iap_down,用于下载的核心算法

#define FLASH_APP1_ADDR     0x08002000     //第一个应用程序起始地址(存放在FLASH)

                                       //保留的空间为IAP使用


u16 iapbuf[1024] = {0}; //用于缓存数据的数组

u16 receiveDataCur = 0;  //当前iapbuffer中已经填充的数据长度,一次填充满了之后写入flash并清零

u32 addrCur = FLASH_APP1_ADDR;         //当前系统写入地址,每次写入之后地址增加2048


//开始下载

void iap_down_s(void)

{

    u16 i = 0;

    u16 temp = 0;

    u16 receiveCount;

    printf("begin,wait datadownload\r\n");

    receiveMode = 1;//串口进入下载接收数据模式

    while(1)

    {

       //循环接收数据,每次必须要发128个数据下来,如果没有128,说明这是最后一包数据

       //接收到一包数据之后,返回一个小数点,发送完成,系统编程完成之后返回一个iap_over

       if(serial_Buffer_Length & 0x8000)

       {

           receiveCount =(u8)(serial_Buffer_Length&0x00ff);

           if(receiveCount == 128)//满足一包,填充并查看是否有了1024字节,有了写入闪存

           {

              for(i = 0; i <receiveCount; i+=2)

              {

                  //数据八位融合为16位

                  temp =(((u16)serial_Buffer[i+1])<<8) + ((u16)serial_Buffer);

                  iapbuf[receiveDataCur]= temp;

                  receiveDataCur++;//完成之后receiveDataCur++;

              }

              receiveExpectCount =0;//清除期望接收模式

              serial_Buffer_Length =0;//清除串口满标志

              printf(".");//每次接受一次数据打一个点

              //此时需要检测receiveDataCur的值,要是放满了,就需要写入

              if(receiveDataCur ==1024)

              {

                  //写入flash中

                  STMFLASH_Write(addrCur,iapbuf,1024);

                  //printf("\r\nwriteaddr %x,length 1024\r\n",addrCur);

                  addrCur += 2048;//地址+2048

                  //写完之后receiveDataCur要清零等待下一次传输

                  receiveDataCur = 0;

              }

              else //有可能最后一包有128个数据但是最终没有2048个数据,此时扩展一个指令用于完成最后一个的写入

              {


              }

              //还没放满,等待下一次数据过来

           }

           else   //不满足一包,说明数据传送这是最后一包,写入闪存

           {

              //没有一包也要传送到缓存中

              for(i = 0; i <receiveCount; i+=2)

              {

                  //数据八位融合为16位

                  temp =(((u16)serial_Buffer[i+1])<<8) + ((u16)serial_Buffer);

                  iapbuf[receiveDataCur]= temp;

                  receiveDataCur++;//完成之后receiveDataCur++;

              }

              receiveExpectCount =0;//清除期望接收模式

              serial_Buffer_Length =0;//清除串口满标志

              printf(".");//每次接受一次数据打一个点

              //之后就要将这数据写入到闪存中

              STMFLASH_Write(addrCur,iapbuf,receiveDataCur);//将最后的一些内容字节写进去.

              //printf("\r\nwriteaddr %x,length %d\r\n",addrCur,receiveDataCur);

              //写完之后要把地址恢复到原来的位置

              addrCur =FLASH_APP1_ADDR;

              receiveDataCur = 0;

              //写完之后要退出下载循环并告诉上位机,已经下载完了

              printf("downloadover\r\n");

              //同时,也要退出下载循环模式

              receiveMode = 0;

              return;

           }

    这段代码的核心思想是上位机每次发送128个数据下来,发满了2048个写一次flash,当最后一包数据不是128的时候说明数据发送完成了,这时候退出下载模式,但是当遇到最后一包数据也是128个时候怎么办呢,于是定义了这个指令
继承事业,薪火相传
返回列表