13199|20

1412

帖子

15

TA的资源

版主

楼主
 

LM3S8962远程升级学习心得 [复制链接]

这几天看了下LM3S8963远程升级的程序,觉得还是蛮有意思的,和大家分享一下。

首先,让我们看一个最基本的概念:

地址:0xE000ED08

为什么要提这个地址呢?翻看8962的参考手册第54页,我们可以看到

   从上表中我们可以看到从0xE000 E0000xE000 EFFF地址段是属于NVIC的,对这个地址段中每个地址详细的解释在ARM Cortex-M3技术手册中,找到该技术手册第164页(8-20),我们看到对0xE000ED08地址单元的解释。简单说来,就是在0xE000ED08地址上存在一个寄存器,该寄存器中的29位表示中断向量表是在RAM中还是ROM中,7-28位表示中断向量表的相对于基地址的偏移。

   通过对该寄存器的修改,我们可以在程序执行的过程中动态的修改中断向量表。

 

 

下面我们就开始对这个程序进行解剖:

StellarisWare\boards\ek-lm3s8962路径下有

四个文件夹,前面两个我认为是启动模板,不用管它。第三个是从网卡升级,我们主要看最后一个,从名字可以看到该工程是从串口升级启动。Boot_serial工程除了调用本目录下的文件外,还会调用StellarisWare\boot_loader下的文件。

 

打开boot_serial工程,在工程窗口找到bl_startup_rvmdk.S文件。很明显,该文件是整个工程的启动文件,上电后整个工程从此处开始运行。通过一系列跳转,程序运行到ProcessorInit函数中,该函数所要完成的功能有三点:

1.  1.   拷贝ROM中的内容到RAM

  movs    r0, #0x00000000

    ldr      r1, =0x20000000   //0x20000000RAM的起始地址

    import  ||Image$$ZI$$Base||   //  ||Image$$ZI$$Base||MDK定义的一个变量,表示ZI段的起始地址(也就是RORW的结束地址),具体可参考网上

    ldr     r2, =||Image$$ZI$$Base||

copy_loop                          //开始循环拷贝,每次32

        ldr     r3, [r0], #4

        str     r3, [r1], #4

        cmp     r1, r2

        blt     copy_loop     

 

    ;

    ; Zero fill the .bss section.

    ;

    movs    r0, #0x00000000     

    import  ||Image$$ZI$$Limit||

    ldr     r2, =||Image$$ZI$$Limit||

zero_loop                            //同理,拷贝ZI

     str     r0, [r1], #4

     cmp     r1, r2

     blt     zero_loop

2.  2..修改中断向量寄存器(就是上面所说的处在0xE000ED08地址的寄存器)指明当前的中断向量表在RAM

    ldr     r0, =0xe000ed08       

    ldr     r1, =0x20000000

    str     r1, [r0]           //更改中断向量寄存器,注意这里的0x2000 0000只是一个值,和RAM的起始地址没关系

3.  3.修改LR寄存器,使程序跳转到RAM中相应的位置执行。

  orr     lr, lr, #0x20000000

因为在此之前ROM中的内容已经全部拷贝到RAM中,所以此处修改LR的内容,使得下一步PC指向RAM中对应的地址。

 

 

 

在执行完ProcessorInit函数后,程序就跳转到CheckForceUpdate函数中运行。该函数的作用很明显,用来确定是否要要对片内的程序升级。该函数bl_check.c文件中。该函数主要完成以下功能(在定义了ENABLE_UPDATE_CHECK宏的情况下):

1.  判断当前ROM中是否有应用程序,如果没有就返回1,表示需要下载应用程序。

 

pulApp = (unsigned long *)APP_START_ADDRESS;

if((pulApp[0] == 0xffffffff) || ((pulApp[0] & 0xfff00000) != 0x20000000) ||

       (pulApp[1] == 0xffffffff) || ((pulApp[1] & 0xfff00001) != 0x00000001))

    {

        return(1);

    }

     那么如何判断当前ROM里面是否有应用程序呢?在上面代码中

APP_START_ADDRESS表示应用程序所处的地址,(unsigned long *)APP_START_ADDRESS表示去取该地址的内容。那么该地址中的内容是什么呢?

对于一个应用程序来说最开始的部分肯定是中断向量表(可以随便找一个程序来看其最开始部分)。在NVIC中,最开始的四个字节存放的是栈地址,紧接着存放的是reset向量。如果在ROMAPP_START_ADDRESS表示的地址中前8个字节有数据且不为0xffffffff或像栈指针和reset向量,则说明存在应用程序,否则就表示用户空间为空,不存在任何应用程序。

什么(pulApp[0] & 0xfff00000) != 0x20000000) 表示不像栈指针?为什么(pulApp[1] & 0xfff00001) != 0x00000001)表示不像reset向量?请教大家,我没想明白

 

2.  如果当前ROM中有应用程序,那么紧接着就判断是否需要执行升级操作,这主要是根据某个引脚上的电平高低来确定的。

3.  如果不需升级则返回0,

执行完CheckForceUpdate函数后,系统执行语句

cbz     r0, CallApplication

来判断是否需要转到应用程序中执行,r0中存放的就是就是上面CheckForceUpdate函数的返回值。如果为0表示转到应用程序中执行。否则就根据预先的宏定义执行升级操作。

 

 

 

我们先看看直接执行应用程序的情况。该段代码比较简单,如下所示,它完成下面功能:

   1.更改中断向量表指针,使得其指向ROM中应用程序开始的地方

    ldr     r0, =_APP_START_ADDRESS

 

    ldr     r1, =0xe000ed08

    str     r0, [r1]

 

2 读取应用程序中断向量表的首4个字节的内容作为栈指针

    ldr     r1, [r0]

mov     sp, r1

 

3 读取应用程序中断向量表次4个字节的内容(即reset后的地址)到R0中,然后跳转。

    ldr     r0, [r0, #4]

bx      r0

 

 

然后,我们看看执行升级操作的情况。

显然,在升级之前需要配置升级的途径,在该程序中通过宏定义来确定到底是用何种方法升级(网卡、CAN、串口等等)。在本例子中,我们采用的是串口升级,所以接下来将会执行ConfigureDevice函数进行串口参数的配置。配置的方法无非就是写寄存器,大家可以参考以前的很多例子,在此不再详述。在配置完串口参数后将执行Updater函数。Updater函数在文件bl_main.c中被实现,从名字可以看出该函数实现的就是具体的升级操作。

Updater函数中根据具体的命令执行不同的操作,这些命令定义在bl_commands.h文件中,整个Updater函数是一个死循环,它根据接收到的命令进行不同的操作。整个函数只有一个出口,即COMMAND_RUN命令下的

((void (*)(void))g_ulTransferAddress)();

语句,该语句的意思是指把g_ulTransferAddress转换为一个指向函数的指针并调用该函数。即跳转到应用程序中执行。

 

 

 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有不对的地方希望大家讨论,下面是cortex-M3参考手册,和整个程序的源码

 

 

另外一种远程升级程序的写法

server_08120421.pdf (957.62 KB, 下载次数: 387)

 

[ 本帖最后由 youki12345 于 2010-8-29 20:39 编辑 ]

cortex_m3_技术参考手册.pdf

2.14 MB, 下载次数: 633

cortex-M3参考手册

StellarisWare.rar

532.38 KB, 下载次数: 313

程序源码

最新回复

受益匪浅  详情 回复 发表于 2011-11-14 11:19
 
点赞 关注(1)
个人签名https://bbs.eeworld.com.cn/thread-471646-1-1.html
欢迎加入我的团队

回复
举报

826

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

你真强大啊!

你真强大啊!
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

板凳
 
 
个人签名我的博客
 
 

回复

802

帖子

23

TA的资源

五彩晶圆(中级)

4
 
:D
 
个人签名生活在激情中 ... 希望 哈哈

https://home.eeworld.com.cn/?80086
 
 

回复

2641

帖子

0

TA的资源

五彩晶圆(中级)

5
 
写得很好,向你学习了,下次我也把学习心得写出来
 
 
 

回复

473

帖子

0

TA的资源

纯净的硅(中级)

6
 
不错 ,支持下
 
个人签名Nicrosystem专业提供freescale、TI和STM32高性价比开发板、解决方案
http://nicrosystem.taobao.com
 
 

回复

602

帖子

0

TA的资源

一粒金砂(中级)

7
 
楼主很专研啊!赞一个!
 
个人签名白天图生存,晚上谋发展!!!
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

8
 

回复 楼主 youki12345 的帖子

如果在ROM中APP_START_ADDRESS表示的地址中前8个字节有数据且不为0xffffffff或不像栈指针和reset向量,则说明存在应用程序,否则就表示用户空间为空,不存在任何应用程序。


    以上说法是不是有点问题啊,应该是: 如果在ROM中APP_START_ADDRESS表示的地址中前8个字节有数据且不为0xffffffff或像栈指针和reset向量,则说明存在应用程序,否则就表示用户空间为空,不存在任何应用程序。
    应该是“像”,而不是“不像”。

赞赏

1

查看全部赞赏

 
 
 

回复

1412

帖子

15

TA的资源

版主

9
 

原帖由 yangxiyuan168 于 2010-8-29 18:20 发表 如果在ROM中APP_START_ADDRESS表示的地址中前8个字节有数据且不为0xffffffff或不像栈指针和reset向量,则说明存在应用程序,否则就表示用户空间为空,不存在任何应用程序。 以上说法是不是有点问题啊,应该 ...

 

 

 

确实,此处是一个笔误,已经更正,感谢yangxiyuan168的细心

 
个人签名https://bbs.eeworld.com.cn/thread-471646-1-1.html
欢迎加入我的团队
 
 

回复

19

帖子

0

TA的资源

一粒金砂(中级)

10
 

回复 楼主 youki12345 的帖子

为什么(pulApp[0] & 0xfff00000) != 0x20000000) 表示不像栈指针?堆栈至少要建立在ram区
为什么(pulApp[1] & 0xfff00001) != 0x00000001)表示不像reset向量?向量表第二项是复位向量 也就是初始pc值 pc最后一位必须为1 否则会进入arm模式 产生fault
大致是这样理解 我想只是其中一部分 再相互交流!

赞赏

1

查看全部赞赏

 
 
 

回复

1412

帖子

15

TA的资源

版主

11
 
明白了,谢谢楼上的。
 
个人签名https://bbs.eeworld.com.cn/thread-471646-1-1.html
欢迎加入我的团队
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

12
 

回复 10楼 ciniao300 的帖子

同意!
 
 
 

回复

2万

帖子

71

TA的资源

管理员

13
 

回复 12楼 yangxiyuan168 的帖子

真切体会到了 人多力量大的道理
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

16

帖子

0

TA的资源

一粒金砂(初级)

14
 
支持一下,学习一下顺便鼓励一下!
 
 
 

回复

18

帖子

0

TA的资源

一粒金砂(初级)

15
 

回复 11楼 youki12345 的帖子

想问问楼主,有没有串口更新应用程序成功?我一直不成功,而且用的程序都是源程序,没改过。
 
 
 

回复

144

帖子

0

TA的资源

一粒金砂(中级)

16
 
谢谢
 
 
 

回复

206

帖子

0

TA的资源

一粒金砂(高级)

17
 

学习了!~

学习了!~学习了!~
 
 
 

回复

102

帖子

0

TA的资源

一粒金砂(中级)

18
 
MARK 下,有时间再看。。
 
 
 

回复

720

帖子

0

TA的资源

纯净的硅(中级)

19
 

回复 10楼 ciniao300 的帖子

((void (*)(void))g_ulTransferAddress)();这个出口是不是只要保证不在自己的boot loader程序范围内且到FLASH范围可以下载应用程序就行,我把这个地址设置为16K,我看源代码设置的为2K,但是现在下载成功后就是启动不了,我把下载到FLASH中的应用程序代码数据全部从FLASH中出来,数据全部正确,但是就是启动不了,现在肯定是这个出口的问题,这个出口写时有什么要求么?
 
 
 

回复

720

帖子

0

TA的资源

纯净的硅(中级)

20
 

回复 楼主 youki12345 的帖子

((void (*)(void))g_ulTransferAddress)();这个出口是不是只要保证不在自己的boot loader程序范围内且到FLASH范围可以下载应用程序就行,我把这个地址设置为16K,我看源代码设置的为2K,但是现在下载成功后就是启动不了,我把下载:carnation: 到FLASH中的应用程序代码数据全部从FLASH中出来,数据全部正确,但是就是启动不了,现在肯定是这个出口的问题,这个出口写时有什么要求么?
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表