27641|41

4997

帖子

19

TA的资源

裸片初长成(初级)

楼主
 

NXP ARM Cortex M0/M3 IAP应用 [复制链接]

 

最近的项目都差不多要使用IAP功能,在使用中遇到了不少问题。本人也把遇到的问题分别发了不同的帖子:

 

1.LPC1100处理器通过SD卡实现IAP功能:https://bbs.eeworld.com.cn/thread-314294-1-1.html

 

2.LPC1700 IAP编程注意事项:https://bbs.eeworld.com.cn/thread-321345-1-1.html

 

3.LPC IAP应用开发与仿真:https://bbs.eeworld.com.cn/thread-324007-1-1.html

 

这三贴中分别描述了本人的开发成果,但是不是很完善。本帖将把这些问题和最近又遇到的心问题一起整理后写在本贴中。

 

        在第1贴中有网友说必须重新处理中断向量重映射,否则中断不能使用,本人经过验证确实如此,由于本人在这个例程重没有使用中断,所以例程是,没有问题的,如果要使用中断就必须进行中断向量重映射。

 

        简单是说,不过是什么芯片,如果使用了IAP+APP的方式编写程序,那么中断向量就必须重映射。原因很简单,默认情况下中断向量都是指向0x00000000地址的,而用IAP+APP的方式进行编程时,APP已经不指向0x00000000了,所以如果应用程序产生中断了,却找不到中断服务函数的入口地址,没办法处理中断。

此帖出自NXP MCU论坛

最新回复

大神你好,询问一下 调试的iap写入数据也正常(写入后断电再上点用Jlink读取数据后对比数据也正常),但是就是复位后程序无法运行 ,把读取出来的文件用jtag写入后再断电上点也是运行正常,好奇怪的问题?  详情 回复 发表于 2017-3-28 18:01

点评

不知道你这样试过没? 下面的代码 是运行在flash的第一个段 作用只是根据标志区地址来跳转到不同的区域 int main(void) { if(IAP_ProCur == PROGRAM_LOW) { UserProgram = (void (*)()) (PROGRAM  详情 回复 发表于 2013-11-10 15:34
点赞 关注(6)
个人签名我的博客
 

回复
举报

4997

帖子

19

TA的资源

裸片初长成(初级)

沙发
 

可能有部分网友并不明白什么是中断向量重映射?为什么要重映射?

 

下面我们先简单介绍一下这个问题,我们学过51单片机的网友都知道,在51单片机的前面一段(从0x0000开始的一段地址),都固定为中断入口地址,如下图:

 

 

 

当产生中断时,CUP会自动根据中断的类型跳转的相应的入口地址,调用相应的中断服务函数进行处理。而对于ARM来说,中断的类型比51多多了,并且把这些中断入口地址在ARM中叫住中断向量表。而且这些表是可以通过寄存器进行重新映射的。所谓的映射简单的理解就是CPU的有一套自己的读写地址,默认的情况下CPU的这套地址与0x00000000对应的,但是我们改变了应用程序的其实地址后,就必须改变CUP读写地址与实际地址的对应关系,这是就不是0x00000000,而是应用程序的实际地址,这样的重新对应关系的就是重映射。

 

下面我们就以LPC1114的中断向量来说明:

1.默认情况

2.使用IAP+APP时

 

3.对于有Flash重映射功能的芯片来说,直接重新映射到上图的地址就可以了,但是由于LPC1100系列芯片是没有Flash重映射功能,使用这样做也是没有实际意义的。所以必须把中断向量表重映射到RAM中。

 

 

LPC1100中断向量向量重映射寄存器描述

 

[ 本帖最后由 zhaojun_xf 于 2012-5-6 09:24 编辑 ]
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

板凳
 

通过以上对中断向量重映射的介绍,我想网友应该明白为什么要重映射以及重映射的方法了吧。其实不同芯片其方法是不一样的,下面我们就介绍两大系列芯片的实现方法:

 

1.LPC1100系列芯片的重映射。

 

重上面的介绍我们知道,由于LPC1100系列芯片没有Flash重映射的功能,使用必须通过RAM实现中断向量的重映射功能。那么这个映射应该在IAP中实现还是APP中实现呢?

 

在读下面的答应之前网友可以先思考一下,应该在哪里实现?

 

既然是没有重映射中断向量就不能实现中断,但非中断代码是可以使用的。所以应该是在应用代码一开始执行就把应用代码中的中断向量表复制到RAM中,并把异常向量表重映射到RAM,代码很简单,就是直接把应用程序中最前面的192(0xC0)字节复制到RAM中的最前面192字节,之后映射到RAM即可:

 

 

不过需要注意:在映射后会导致SystemCoreClock发生变化,所以,在调用这个RAM映射函数后必须调用时钟函数:void SystemCoreClockUpdate (void) 保证CPU时钟的正确性。

 

2.LPC1700系列芯片的重映射。

 

由于LPC1700系列芯片有Flash重映射功能,所以使用起来非常方便,只需要设置一下寄存器SCB->VTOR,此寄存器在IAP代码中实现,在跳转到应用程序之前设置即可了,代码如下:

 

SCB->VTOR = AC_CODE_START_ADDR & 0x1FFFFF80;          // 重映射

 

 

总结需要特别注意,这两种芯片实现重映射的方法是不同的,而且也不是在同样的代码中,LPC1100是在APP中实现RAM重映射,而LPC1700是通过IAP中设置VTOR寄存器实现Flash重映射的。

[ 本帖最后由 zhaojun_xf 于 2012-5-6 10:21 编辑 ]
此帖出自NXP MCU论坛

点评

我在LPC11C12中应用IAP时把中断向量表映射到RAM后程序跑飞,在单步调试时执行SYSMEMREMAP = 0x1;后可以看到0x10000000起始的地址中写入了原本保存在FLASH中的异常向量表信息,但是再单步时发现0x10000000起始的地址  详情 回复 发表于 2013-1-4 13:31
 
个人签名我的博客
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

4
 

很多人在使用IAP时总是出现问题,但却不知道去怎么找问题,下面总结一下一般在使用IAP时会出现的问题和解决方法。

 

1.通过IAP编程问题?

 

    很多人在第一次使用IAP时都容易怀疑这个问题,因为没有经验,所以对自己没有信心。其实IAP代码都是芯片厂商固化大ROM中的,所以只要按照正确的方法调用,一般是不会出现问题的。不过需要注意几个问题:

 

a. 时钟参数一定按照当前系统的实际运行时钟传递;

b. 注意返回值是否则正确;

c. 编程扇区大小一定要注意,并不少每个芯片的每个扇区的大小都是一样的大的,一定要看芯片手册了解扇区大小;

d. 编程字节,对于LPC系列芯片来说支持4096,2048,1024,512,256等多种字节的写入,但是绝不能写不支持是字节数。特别是最后一次写入时,大家都容易只写实际字节数(本人就犯过这样的错误,最后一次写入只有240字节时,就写入240字节),这种情况下代码是没法运行的。必须按照256字节方式写入,当然你可以可以按照4096或其他方式写入。

 

2.APP代码错误?

 

    如果犯了上面的第4中错误,是很难找的问题的,应就算你从芯片中读取编程的代码与原代码进行比较也是正确的,所以一定要特别注意。如果编写没有错误,那么还是不可以正确运行时,我们可以考虑把编程后的代码读取出来,与源代码进行比较,保证代码不在下载过程中出现错误。不过IAP并不支持读扇区的函数,没有不要紧,我们可以通过直接读取直接地址来读取芯片中的代码内容。

 

3.IAP跳转到APP问题?

 

    在以上两个问题都是正确的时候,最后可能出现的问题就是跳转是否正确。是否跳转到正确的地址上去了,要解决这个问题,最简单的方法就是用仿真的方法实现。为了保证以上两个问题的正确性,我们可以使用JLINK或ULINK等工具先把APP代码编写到高地址上,再通过仿真代码仿真IAP,看是否可以跳转的APP。当然也可以先把IAP编写到底地址,在通过仿真工具仿真看代码是否可以进入main函数。如果能进入,所以IAP的跳转是没有问题的,否则跳转可能出现问题了。

 

一般情况下,只要保证以上几个问题不出现就不会有问题的。不过有很多人出现以下特别奇怪的问题:

 

用串口中断接收APP代码,在IAP把APP代码编写进芯片后,APP中调用串口中断就出现问题了,不进中断。

 

对于这个问题,有不少人出现,不过本人没有出现这个问题,所以不知道为什么会这样。当遇到这个问题,一般的解决方法是,IAP编程成功后不直接跳转到APP,而是是IAP代码出现看门狗复位,重启后直接跳转到APP就可以了。。。

此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

5
 

我们在使用IAP+APP模式时往往都是把APP代码放入一个外部存储器或通过外部接口实现代码存储或下载的,所以一般情况下我们都是把APP编译成为二进制文件。可以能部分网友并不知道二进制文件和十六进制文件究竟有什么区别,下面我们简单说明一下:

 

1.二进制文件

 

编译器编译的二进制文件,里边只有应用程序代码内容,不包含其他任何内容。如果使用编程软件打开二进制文件时就会叫你设置起始地址。所以要把这些代码放在什么地方(起始地址),是编写芯片的人员必须了解的,如果写错地址将无法运行。所以我们通过串口或外部存储的方式下载应用程序时,我们必须知道编程的起始地址。

 

2.十六进制文件

 

编译器编译的十六进制文件,里边已经包含了所有编程信息和应用程序代码内容。所有我们用编程软件打开十六进制文件时不需要设置地址,软件自己就可以正确的读取代码的存放以及编程信息。

 

总结:我们在使用JLINK、ULINK等仿真下载工具编写芯片时我们一般都使用十六进制比较方便;而我们通过IAP来升级编程时一般都使用二进制文件,因为我们的IAP代码一般都没有解析十六进制文件的功能,其次一般我们的外部存储空间有限,而用外部接口时文件太大也很麻烦。因为同样的应用程序一般十六进制文件比二进制文件大一倍。

此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

623

帖子

0

TA的资源

纯净的硅(高级)

6
 
谢谢版主分享~~~
正在看lpc1114系列的IAP……
此帖出自NXP MCU论坛
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(高级)

7
 
学习了,有时间一定试试
此帖出自NXP MCU论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

8
 
相当的牛叉
此帖出自NXP MCU论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

9
 
请教下版主:

1.IAP跳转到APP 需要 初始化堆栈吗?
2.像LPC1100需要重映射,会使用0x10000000~0x100000BF的内存地址

   需要在target 里设置RAM  Start 0x100000C0起来 Size是 0x10002000- 0xc0吗?
此帖出自NXP MCU论坛

点评

LPC1100需要复制中断向量,而LPC1700有重映射寄存器,不需要复制。RAM不需要更改。。。。。。  详情 回复 发表于 2012-11-24 14:13
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

10
 

回复 9楼 lmy_asi 的帖子

LPC1100需要复制中断向量,而LPC1700有重映射寄存器,不需要复制。RAM不需要更改。。。。。。
此帖出自NXP MCU论坛

点评

中断向量是做了,不过需要初始化堆栈吗? 现象:两个相同的程序一个做BOOT(0x0000地址),一个做APP,就可以正常起来,不同的就不行。  详情 回复 发表于 2012-11-26 09:33
 
个人签名我的博客
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

11
 

回复 10楼 zhaojun_xf 的帖子

中断向量是做了,不过需要初始化堆栈吗?

现象:两个相同的程序一个做BOOT(0x0000地址),一个做APP,就可以正常起来,不同的就不行。
此帖出自NXP MCU论坛

点评

不需要初始化堆栈的,你仿真看看问题在哪里?  详情 回复 发表于 2012-11-26 13:24
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

12
 

回复 11楼 lmy_asi 的帖子

不需要初始化堆栈的,你仿真看看问题在哪里?
此帖出自NXP MCU论坛

点评

IAP程序和应用程序是两个独立的程序,他们的堆栈初始化(大小,位置),都是在各自startup.s文件中执行的。中断向量表的第一个字(四个bytes)保存栈顶地址,第二个字是resetHandler的地址。程序跳转,实际是跳转到了  详情 回复 发表于 2013-11-20 22:51
 
个人签名我的博客
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

13
 

回复 板凳 zhaojun_xf 的帖子

我在LPC11C12中应用IAP时把中断向量表映射到RAM后程序跑飞,在单步调试时执行SYSMEMREMAP = 0x1;后可以看到0x10000000起始的地址中写入了原本保存在FLASH中的异常向量表信息,但是再单步时发现0x10000000起始的地址中的数据被改变了,程序也跑飞。我也查了相关资料,比如LPC2114的例子,
http://hi.baidu.com/stm32/item/d65c47dc445983e0795daaad,他也是把向量表映射到RAM中的,但是就没我这个问题。
我的加载文件是这样的:
LR_IROM1 0x00000000   {    ; load region size_region
  ER_IROM1 0x00000000   {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   *.o (+RO)
  }
  RW_IRAM1 0x10000100   {  ; RW data
        .ANY (+RW +ZI)
  }
}
我想把FLASH中的向量异常表重映射到RAM,也是就是把0x00000000起始的向量表拷贝到0x10000000中,执行了VectorRemap函数
void VectorRemap(uint32_t userCodeAddr)
{
        uint8_t i;
        volatile uint32_t  *pUser,*PRam;

        pUser = (uint32_t *)userCodeAddr;
        PRam = (uint32_t *) 0x10000000;
        for(i=0;i<48;i++)
                *PRam++ = *pUser++;

        SYSMEMREMAP = 0x1;
}
但是在实际调试时执行完SYSMEMREMAP = 0x1;也就是把中断向量映射到RAM后,程序报废,请教楼主,这会是什么原因呢
此帖出自NXP MCU论坛

点评

是不是没写黑体部分的原因? LPC_SYSCON->SYSMEMREMAP=0x01;  详情 回复 发表于 2013-1-8 22:55
参照一下此贴:https://bbs.eeworld.com.cn/thread-314294-1-1.html 帖子中没有中断向量重映射,不用中断是可以的,用中断有问题,你添加一下中断向量重映射就可以了。  详情 回复 发表于 2013-1-4 16:44
我在做在线升级时,没有使用分散加载文件,但需要拷贝中断向量,也没有发现任何问题,认真看看芯片资料,我们暂时没有使用过带C的芯片,只使用过LPC1114。  详情 回复 发表于 2013-1-4 16:38
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

14
 

回复 13楼 Alex_li615 的帖子

我在做在线升级时,没有使用分散加载文件,但需要拷贝中断向量,也没有发现任何问题,认真看看芯片资料,我们暂时没有使用过带C的芯片,只使用过LPC1114。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

15
 

回复 13楼 Alex_li615 的帖子

参照一下此贴:https://bbs.eeworld.com.cn/thread-314294-1-1.html
帖子中没有中断向量重映射,不用中断是可以的,用中断有问题,你添加一下中断向量重映射就可以了。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

1

帖子

0

TA的资源

一粒金砂(中级)

16
 

回复 13楼 Alex_li615 的帖子

是不是没写黑体部分的原因?
LPC_SYSCON->SYSMEMREMAP=0x01;
此帖出自NXP MCU论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

17
 

回复 楼主zhaojun_xf 的帖子

不知道你这样试过没?

下面的代码 是运行在flash的第一个段 作用只是根据标志区地址来跳转到不同的区域

int main(void)

{

        if(IAP_ProCur == PROGRAM_LOW)
        {
                UserProgram = (void (*)()) (PROGRAM_LOW + 1);
                __disable_irq();
                (*UserProgram)();
        }
       

        if(IAP_ProCur == PROGRAM_HIGH)
        {
                UserProgram = (void (*)()) (PROGRAM_HIGH + 1);
                __disable_irq();
                (*UserProgram)();       
        }
}


现在的问题是,我同一个程序 通过 Target 设置IROM 地址0x1000 (PROGRAM_LOW,即为低区首地址) 编译后下载程序后能跳转也能很好运行;
但是,当 Target 设置IROM 地址0x4000 ( PROGRAM_HIGH,即为高区首地址 ) 编译后下载程序无法跳转,更不用说运行高区的程序;
当然了 对程序都进行了中断重映射!
调试后发现当IAP_ProCur  为 PROGRAM_HIGH 时运行到    (*UserProgram)();        这一句时直接进入HardFault_Handler中断死掉了,
查看flash区内,高区和低区数据,除了固定偏移地址不同外其他全是一样,不明白,

这样怎么解决问题呢?不知道解决问题的方向
此帖出自NXP MCU论坛

点评

HardFault_Handler错误一般都是堆栈空间实现的,好好检查一下,应该是内存空间问题。  详情 回复 发表于 2013-11-11 11:56
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

18
 

回复 17楼rainsy 的帖子

HardFault_Handler错误一般都是堆栈空间实现的,好好检查一下,应该是内存空间问题。
此帖出自NXP MCU论坛
 
个人签名我的博客
 
 

回复

26

帖子

0

TA的资源

一粒金砂(中级)

19
 
有个疑惑是,引导程序中的RAM中的数据在跳转到应用程序后并没有消失,怎样除去RAM中的变量数据?
此帖出自NXP MCU论坛
 
 
 

回复

26

帖子

0

TA的资源

一粒金砂(中级)

20
 

回复 12楼zhaojun_xf 的帖子

IAP程序和应用程序是两个独立的程序,他们的堆栈初始化(大小,位置),都是在各自startup.s文件中执行的。中断向量表的第一个字(四个bytes)保存栈顶地址,第二个字是resetHandler的地址。程序跳转,实际是跳转到了ResetHandler这个地方,这是LPC1768的跳转,在之前已经设置重映射了中断向量表
__asm void boot_jump(uint32_t address) {
   LDR SP, [R0]         ; Load new stack pointer address
   LDR PC, [R0, #4]  ; Load new program counter address
}
此帖出自NXP MCU论坛

点评

哥们,能给我个QQ号码吗??请教点问题:victory:  详情 回复 发表于 2013-11-30 10:28
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表