|
ARM仿真程序进入了IAP后便再也没有出来,烦了两个多月了,求高手帮助!!!
这个程序搞了我两个多月了,该做的我都做了,始终没有搞定
又或者谁有硬件帮我检验一下,看到底哪里出现问题,麻烦大家了。
IAP程序是参考周公的,主程序在下面,还有proteus附件
首先说明的是用keil 4软仿的话程序能正常跳出IAP并继续运行,但是最后RamToFlash之后复制过去的数据很大一部分都是错误的
用proteus仿真时每当调用固件函数(*IAP_Entry)(paramin, paramout)时,程序就死掉了,
请高手检查一下,到底是KEIL出错还是proteus出错,还是启动代码的问题,总之修改到对为止,又或者能提供一个正确的IAP 和proteus LPC仿真的程序就最好了
#include "LPC2294.h"
/****************************************************************************
* 文件名:IAPTEST.C
* 功能:LPC2100的IAP功能测试。
* 说明:调用IAP服务程序,完成FLASH编程操作。
* 将paramout添加到Watch窗口,观察返回值。
****************************************************************************/
#include "config.h"
#include <string.h>
/* 定义IAP命令字 */
#define IAP_SELSECTOR 50
#define IAP_RAMTOFLASH 51
#define IAP_ERASESECTOR 52
#define IAP_BLANKCHK 53
#define IAP_READPARTID 54
#define IAP_BOOTCODEID 55
#define IAP_COMPARE 56
/* 定义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
#define PARAM_ERROR 12 /* Insufficient number of parameters */
#define ADDR_ERROR 13 /* Address not on word boundary */
#define ADDR_NOT_MAPPED 14
#define CMD_LOCKED 15 /* Command is locked */
#define INVALID_CODE 16 /* Unlock code is invalid */
#define INVALID_BAUD_RATE 17
#define INVALID_STOP_BIT 18
#define KEY1 0x00010000 /* P0.16引脚连接KEY1 */
uint32 paramin[8]; // IAP入口参数缓冲区
uint32 paramout[8]; // IAP出口参数缓冲区
void delay(uint32 i)
{
while(i--);
}
void dffd ()
{
IOCLR=(7<<20);
IOCLR=(7<<20);
IOCLR=(7<<20);
IOCLR=(7<<20);
IOCLR=(7<<20);
}
void ledlight(void) //闪烁灯LED1测试
{
while(1)
{
delay(10000);
IOCLR=(7<<12);
delay(10000);
IOSET=(7<<12);
}
}
void ledlight2(void) //闪烁灯LED2测试
{
// while(1)
{
delay(10000);
IOCLR=(7<<3);
delay(10000);
IOSET=(7<<3);
}
}
void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);
/****************************************************************************
* 名称:SelSector()
* 功能:IAP操作扇区选择,命令代码50。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void SelSector(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_SELSECTOR; // 设置命令字
paramin[1] = sec1; // 设置参数
paramin[2] = sec2;
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
//ledlight();
}
/****************************************************************************
* 名称:RamToFlash()
* 功能:复制RAM的数据到FLASH,命令代码51。
* 入口参数:dst 目标地址,即FLASH起始地址。以512字节为分界
* src 源地址,即RAM地址。地址必须字对齐
* no 复制字节个数,为256/512/1024/4096/8192
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void RamToFlash(uint32 dst, uint8*src, uint32 no)
{ paramin[0] = IAP_RAMTOFLASH; // 设置命令字
paramin[1] = dst; // 设置参数
paramin[2] = (uint32)src;
paramin[3] = no;
paramin[4] = Fosc/1000; // 当不使用PLL功能时,Fcclk=Fosc
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
}
/****************************************************************************
* 名称:EraseSector()
* 功能:扇区擦除,命令代码52。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void EraseSector(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_ERASESECTOR; // 设置命令字
paramin[1] = sec1; // 设置参数
paramin[2] = sec2;
paramin[3] = Fosc/1000; // 当不使用PLL功能时,Fcclk=Fosc
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
}
/****************************************************************************
* 名称:BlankCHK()
* 功能:扇区查空,命令代码53。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void BlankCHK(uint8 sec1, uint8 sec2)
{ paramin[0] = IAP_BLANKCHK; // 设置命令字
paramin[1] = sec1; // 设置参数
paramin[2] = sec2;
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
}
/****************************************************************************
* 名称:ReadParID()
* 功能:扇区查空,命令代码53。
* 入口参数:无
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
uint32 ReadParID(void)
{
paramin[0] = IAP_READPARTID; // 设置命令字
// (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
iap(paramin, paramout);
//ledlight();
return(paramout[1]);
}
/****************************************************************************
* 名称:BootCodeID()
* 功能:读取boot代码版本号,命令代码55。
* 入口参数:无
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void BootCodeID(void)
{ paramin[0] = IAP_BOOTCODEID; // 设置命令字
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
}
/****************************************************************************
* 名称:Compare()
* 功能:校验数据,命令代码56。
* 入口参数:dst 目标地址,即RAM/FLASH起始地址。地址必须字对齐
* src 源地址,即FLASH/RAM地址。地址必须字对齐
* no 复制字节个数,必须能被4整除
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void Compare(uint32 dst, uint32 *src, uint32 no)
{ paramin[0] = IAP_COMPARE; // 设置命令字
paramin[1] = dst; // 设置参数
paramin[2] = (uint32)src;
paramin[3] = no;
(*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
}
/****************************************************************************
* 名称:main()
* 功能:IAP函数调用,测试。通过观察IAP出口参数来判断操作是否成功。
* 说明:程序没有进行出错处理。
* 要设置编译参数-apcs /interwork,因为IAP为Thumb指令。
* 使用IAP功能时,片内RAM的顶端的32字节保留给IAP操作使用,所以在STARTUP.S文件中
* 初始化系统模式堆栈为StackUsr-20*4,以保证IAP正常操作。
****************************************************************************/
int main(void)
{
uint8 databuff [512];
uint8 databuff1 [512];
uint32 *addr[1];
uint32 *addr1;
uint16 i;
MAMCR = 0; // 关闭MAM
PLLCON = 0; // 关闭PLL
PLLFEED = 0xaa;
PLLFEED = 0x55;
IO1DIR=0xffffffff;
IO0DIR = 0xfffffffc;
PINSEL0 = 0x00000000; // 设置所有管脚连接GPIO
PINSEL1 = 0x00000000;
IAP_Entry = (void(*)())0x7FFFFFF1; // 初始化函数指针IAP_Entry
while(1)
{
delay(10000);
IOCLR=(7<<3); //LED2灭
delay(10000);
IOSET=(7<<3);//LED2亮
// ledlight();//注释这句后程序便跑飞了
//((void (*)())(0x00000000))(paramin,paramout);//程序跳到复位处
//((void (*)())(ledlight2))(paramin,paramout);
paramin[0] = IAP_BOOTCODEID; // 设置命令字
(*IAP_Entry)(paramin, paramout); //跳不过,程序停在这里了,为什么?
ledlight(); // LED1灯闪烁程序,死循环,用来跟踪程序是否正常
// ReadParID(); //跳不过?
BootCodeID();
//SelSector(8,8);
//EraseSector(8,8);
//BlankCHK(8,8);
Compare(0x00008000,*addr,512);
}
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|