打印
[ZLG-ARM]

关于IAP

[复制链接]
2961|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
move|  楼主 | 2007-1-3 11:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在ZLG的书上有一个LPC2131下的例子,是Thumb指令下的,为什么我放在一个用ARM指令的工程就不能了?
源程序如下
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:            main.c
** Last modified Date:  2004-09-16
** Last Version:        1.0
** Descriptions:        The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:            Chenmingji
** Created date:        2004-09-16
** Version:                1.0
** Descriptions:        The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:            Chenxibing
** Modified date:        2005-02-16
** Version:
** Descriptions:
**
*******************************************************************************************************
*/
#include  "config.h"

#define BEEP    (1 << 7)

#define IAP_ENTER_ADR   0x7FFFFFF1  // IAP入口地址定义

/* 定义IAP命令字 */
                                    //   命令           参数
#define     IAP_SELECTOR        50  // 选择扇区     【起始扇区号、结束扇区号】
#define     IAP_RAMTOFLASH      51  // 拷贝数据     【FLASH目标地址、RAM源地址、写入字节数、系统时钟频率】
#define     IAP_ERASESECTOR     52  // 擦除扇区     【起始扇区号、结束扇区号、系统时钟频率】
#define     IAP_BLANKCHK        53  // 查空扇区     【起始扇区号、结束扇区号】
#define     IAP_READPARTID      54  // 读器件ID     【无】
#define     IAP_BOOTCODEID      55  // 读Boot版本号 【无】
#define     IAP_COMPARE         56  // 比较命令     【Flash起始地址、RAM起始地址、需要比较的字节数】

/* 定义IAP返回状态字 */
#define     CMD_SUCCESS          0
#define     INVALID_COMMAND      1
#define     SRC_ADDR_ERROR       2 
#define     DST_ADDR_ERROR       3
#define     SRC_ADDR_NOT_MAPPED  4
#define     DST_ADDR_NOT_MAPPED  5
#define     COUNT_ERROR          6
#define     INVALID_SECTOR       7
#define     SECTOR_NOT_BLANK     8
#define     SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9
#define     COMPARE_ERROR        10
#define     BUSY                 11


/* 定义CCLK值大小,单位为KHz */
#define  IAP_FCCLK            11059

/* 定义函数指针 */
void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);

uint32  paramin[8];                         // IAP入口参数缓冲区
uint32  paramout[8];                        // IAP出口参数缓冲区

/*
*********************************************************************************************************
** 函数名称:SelSector()
** 函数功能:IAP操作扇区选择,命令代码50。
** 入口参数:sec1        起始扇区
**           sec2        终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  SelSector(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_SELECTOR;               // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序
   
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:RamToFlash()
** 函数功能:复制RAM的数据到FLASH,命令代码51。
** 入口参数:dst        目标地址,即FLASH起始地址。以512字节为分界
**           src        源地址,即RAM地址。地址必须字对齐
**           no         复制字节个数,为512/1024/4096/8192
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  RamToFlash(uint32 dst, uint32 src, uint32 no)
{  
    paramin[0] = IAP_RAMTOFLASH;             // 设置命令字
    paramin[1] = dst;                        // 设置参数
    paramin[2] = src;
    paramin[3] = no;
    paramin[4] = IAP_FCCLK;
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序
    
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:EraseSector()
** 函数功能:扇区擦除,命令代码52。
** 入口参数:sec1       起始扇区
**           sec2       终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  EraseSector(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_ERASESECTOR;            // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    paramin[3] = IAP_FCCLK;
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序
   
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:BlankCHK()
** 函数功能:扇区查空,命令代码53。
** 入口参数:sec1       起始扇区
**           sec2       终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  BlankCHK(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_BLANKCHK;               // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:ReadParID()
** 函数功能:扇区查空,命令代码53。
** 入口参数:无
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  ReadParID(void)
{  
    paramin[0] = IAP_READPARTID;             // 设置命令字
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:BootCodeID()
** 函数功能:读取boot代码版本号,命令代码55。
** 入口参数:无
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  BootCodeID(void)
{  
    paramin[0] = IAP_BOOTCODEID;             // 设置命令字
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:Compare()
** 函数功能:校验数据,命令代码56。
** 入口参数:dst        目标地址,即RAM/FLASH起始地址。地址必须字对齐
**           src        源地址,即FLASH/RAM地址。地址必须字对齐
**           no         复制字节个数,必须能被4整除
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  Compare(uint32 dst, uint32 src, uint32 no)
{  
    paramin[0] = IAP_COMPARE;                // 设置命令字
    paramin[1] = dst;                        // 设置参数
    paramin[2] = src;
    paramin[3] = no;
    (*IAP_Entry)(paramin, paramout);         // 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:main()
** 函数功能:IAP函数调用,测试
*******************************************************************************************************
*/
int  main(void)
{  
    uint8 err;
    uint32 i;
    
    PINSEL0 = 0x00000000;            // 管脚连接GPIO
    IO0DIR = BEEP;
    IO0SET = BEEP;
    
    IAP_Entry = (void(*)())IAP_ENTER_ADR;           // 初始化函数指针IAP_Entry
   
    ReadParID();                                    // 读器件ID
    BootCodeID();                                   // 读Boot版本号
   
    SelSector(1,1);                                 // 选择扇区1
    EraseSector(1,1);                               // 擦除扇区1
    BlankCHK(1,1) ;                                 // 查空扇区1
   
    SelSector(1,1);                                 // 选择扇区1
    RamToFlash(0x00001000, 0x40001000, 256);        // 写数据到扇区1 
    err = Compare(0x00001000, 0x40001000, 256);     // 比较数据
   
    if(err == CMD_SUCCESS)
    {    /* 成功,蜂鸣一声 */
        IO0CLR = BEEP;
        for (i=0; i<0x3FFFFF; i++);
        IO0SET = BEEP;
    }
    else
    {    /* 失败,一直蜂鸣 */
        IO0CLR = BEEP;
    }
   
    while(1);
    return(0);
}

相关帖子

沙发
btiger2000| | 2007-1-3 12:40 | 只看该作者

设置如图。

使用特权

评论回复
板凳
move|  楼主 | 2007-1-3 13:12 | 只看该作者

还不成功,请求大侠

你的意思是IAP的子程序用16其它的还用ARM指令,是在原工程下这样设吗?
我试了一下,只要设置一个,别的都跟着变化。

使用特权

评论回复
地板
btiger2000| | 2007-1-3 14:16 | 只看该作者

什么意思?不懂

只要设置一个,别的都跟着变化。

使用特权

评论回复
5
move|  楼主 | 2007-1-3 14:45 | 只看该作者

我的意思是

按您说的对ATPC设置后,再到ARM Assembler中对我的一个子程序进行设置为Thumb指令,别的也跟着设置变化。
我再试下。
请您也再跟我多讲几步,只说一个地方我不明白。谢谢

使用特权

评论回复
6
btiger2000| | 2007-1-4 15:46 | 只看该作者

只需要设置C compiler即可!

另IAP占用堆栈的高32字节,所以要保证不被其它占用

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

13

帖子

0

粉丝