电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

现场升级方案:采用U盘方式进行IAP功能的实现(二)

现场升级方案:采用U盘方式进行IAP功能的实现(一)

下面分别概括一下实现IAP命令的函数,IAP功能命令有准备编程扇区,复制RAM到FLASH,擦除扇区,扇区查空,读器件ID,读BOOT代码版本,比较等指令。程序要进行IAP升级,必须要先选择扇区擦除扇区之后才能写进Flash。先需要定义系统时钟,参数和一些变量。

#define     IAP_FCCLK       48000 

uint32_t    paramin[8];                                             
uint32_t    paramout[8];                                              
unsigned long command[5];
unsigned long result[5];
typedef void (*IAP) (unsigned int [ ] , unsigned int [ ]);      

写数据之前,必须要选择需要写入的扇区,选择扇区部分代码:

 uint32_t    SelSector(uint8_t    sec1,uint8_t    sec2)
{
    paramin[0] = IAP_SELECTOR;                                         
    paramin[1] = sec1;                                                 
    paramin[2] = sec2;
    (*(void(*)())IAP_LOCATION)(paramin,paramout);                     
    return(paramout[0]);                                               
}

选中扇区之后,要检查该扇区是否已经有数据,所以要擦除扇区,附代码:

uint32_t    EraseSector(uint32_t sec1, uint32_t sec2)
{
    paramin[0] = IAP_ERASESECTOR;                                      
    paramin[1] = sec1;                                                 
    paramin[2] = sec2;
    paramin[3] = IAP_FCCLK;
    (*(void(*)())IAP_LOCATION)(paramin,paramout);                     
    return(paramout[0]);                                               
}

下来就是向flash写入数据,flash起始地址必须以256字节为分界,调用函数

uint32_t    RamToFlash(uint32_t dst, uint32_t src, uint32_t  no)
{
    paramin[0] = IAP_RAMTOFLASH;                                       
    paramin[1] = dst;                                                  
    paramin[2] = src;
    paramin[3] = no;
    paramin[4] = IAP_FCCLK;
    (*(void(*)())IAP_LOCATION)(paramin,paramout);                     
    return(paramout[0]);                                               

写完之后要进行比较,将RAM读出来的数据和写入到flash的数据进行比较,注意flash起始地址必须字对齐,字节个数必须能被4整除,当源或目标地址包含从地址 0 开始的前 64 个字节中的任意一个地址时, 比较的结果可能不准确。因为前 64 个字节可被重新映射到 RAM:

uint32_t    Compare(uint32_t    dst, uint32_t    src, uint32_t    no)
{
    paramin[0] = IAP_COMPARE;                                          
    paramin[1] = dst;                                                  
    paramin[2] = src;
    paramin[3] = no;
    (*(void(*)())IAP_LOCATION)(paramin,paramout);                     
    return(paramout[0]);                                               

还有ExceuteApplication()部分的代码,程序写入flash之后,要重新映射向量表,从bootloader跳转到APP执行,这就要获取程序的入口地址和SP堆栈的值。如下:

__asm void ExceuteApplication(void)
{
  ldr r0, =0x00A000
  ldr r0, [r0]
  mov sp, r0
  ldr r0, =0x00A004
  ldr r0, [r0]
        BX  r0
}

最后关闭文件系统,main里面最主要读取bin文件调用IAP功能的Bin_Read()函数说完了。最后说一下APP程序产生bin文件的配置。
KEIL中Target Options配置:
1.将程序入口定位到App即用户程序的入口地址;2.User选项:Run #1填写产生bin文件路径:C:\Keil\ARM\ARMCC\bin\fromelf.exe--bin --output output\FLASH\test.bin output\FLASH\LPC177x_8x.axf;3.C/c++选项:Optimization选择高优先级:Level3;4.Asm选项:Define填NO_CRP;不产生空文件夹5.Linker选项:勾选Use Memory layout from Target Dialog.整个工程就算建立起来了。附两个版本的代码,仅限参考:

裸机版:http://download.csdn.net/download/u012246376/8453395 

带操作系统UCOS版本:http://download.csdn.net/download/u012246376/8453349
 

博主
阳光守望者
阳光&守望者
单片机/嵌入式软硬件开发
点击跳转