MDK环境下,mini2440(S3C2440) keyled 程序分析

来源:互联网 发布:海陆丰 知乎 编辑:程序博客网 时间:2024/05/02 21:23


 

keyled代码请参考我的博客网址:http://my.csdn.net/wfq0624/code/detail/7645

实验环境

==================================================================================

Keyled实验

开发板:mini2440               仿真器:Wiggler H-JTAG/HJTAG并口下载调试器                     CPU:S3C2440

==================================================================================

Mini2440 Memory 配置:

NAND flash:K9F1208(64M x 8 Bit)                      64MByte                            [0x00000000~0x03FFFFFF]

NOR flash:SST39VF1601(1M x16 Bit)                       2MByte                       [0x0~0x001FFFFF]

SDRAM: HY57V561620 (2pcsX4Banks x 4M x16Bit) 64MByte                            [0x30000000~0x33FFFFFF]

==================================================================================

实验内容

本实验实现对mini2440开发板 led灯和按键点灯的操作。

在Build 工具栏---》Select Target 分别选择下面三种Project Target,即可观测到实验结果

代码完全一样,三种Project Target对应三种不同的分散加载文件

[注意mini2440开发板上启动开关选择Nor Flash启动]

RuninRAM   将程序下载到SDRAM中调试。

Runinnorflash 运行在norflash中

Two Section 将Keyled.c目标文件定位于地址0x1000处,运行时,搬运此代码到SDRAM0x30000100执行

==================================================================================

依次点亮4颗LED,循环3次,然后全灭,等待按键按下,不同的按键点亮不同的灯号。

==================================================================================

[注意] MDK+ Wiggler H-JTAG/HJTAG并口下载调试器的搭配无法直接在MDK环境下调试,必须先将生成的

hex文件,通过H-JTAG代理软件烧写到norflash中,再在MDK环境中,启动调试,即可runinflash单步调试

==================================================================================

实验原理分析

以比较复杂的两段加载域分散加载文件Two Section.sct为例来说明

1.1.1    Two Section.sct分散加载文件解析

可以看出,有两段加载域LR_ROM1和LR_ROM2,其中LR_ROM1是根域。

S3C2440A.o (RESET, +First):表示将中断向量所在的段(段名RESET)放在0x0的位置,并且RESET段在S3C2440A.s文件里。

LR_ROM2装载域表示将keyled.c所生成的目标文件keyled.o的Code/RO data放在Norflash地址0x1000处,运行域地址在SDRAM中0x30000100处。

所以在运行之前,必须将keyled.o的代码从Norflash 0x1000 处copy到SDRAM0x30000100处往后存放,因为本实验程序使用了MDK自带的__main()函数,这部分的copy动作,__main()已经帮忙copy了,所以在程序中,根本看不到显式的copy 代码,请不要感觉到奇怪。

备注:如对上述还不太理解的,请察看我的博客文章,有几篇较为详细的描述.http://blog.csdn.net/wfq0624

;**********************************************************************

; *** Scatter-Loading Description Filegenerated by uVision ***

;**********************************************************************

; Two Section

LR_ROM1 0x00000000        

{  

        ER_ROM10x00000000 0x00200000 

        {

               S3C2440A.o(RESET, +First)

               *(InRoot$$Sections)

               .ANY(+RO)

        }

        RW_RAM10x30050000 0x03000000 

        {

               .ANY(+RW +ZI)

        }

        RW_IRAM10x40000000 0x00001000  {

               .ANY(+RW +ZI)

        }

}

 

LR_ROM2 0x00001000        

{  

        ER_ROM20x30000100 0x00004000 

        {

               keyled.o(+RO)

        }

}

1.1.2    Keyled.bin文件分析

可以看出,使用TwoSection.sct分散加载文件能够生成2个bin文件:ER_ROM1和ER_ROM2,分别对应两个加载区所生成的二进制文件,ER_ROM1二进制文件必须下载到Norflash 起始地址0x0的位置,而ER_ROM2必须下载到Norflash 起始地址0x1000的位置.

不过生成的Hex文件还是只有一个,因为Hex文件本身就是有记录地址信息的。如果将此Hex文件通过H-Converter转化成一个bin文件,你会发现ER_ROM2的内容刚好在0x1000处的位置,毫无疑问ER_ROM1内容在0x0处.


1.1.3    Keyled程序堆栈分析

因为使用了分散加载文件,所以启动代码里一定要使用__user_initial_stackheap()来重新设置堆栈和堆

与堆栈相关的代码如下所示(初始化各种模式下SP相关的代码就不列出来了,请参考源代码即可):

UND_Stack_Size  EQU     0x00000010

SVC_Stack_Size  EQU      0x00000008

ABT_Stack_Size  EQU      0x00000010

FIQ_Stack_Size  EQU       0x00000010

IRQ_Stack_Size  EQU       0x00000080

USR_Stack_Size  EQU      0x00000400

ISR_Stack_Size  EQU       (UND_Stack_Size+ SVC_Stack_Size + ABT_Stack_Size + \

                         FIQ_Stack_Size +IRQ_Stack_Size)

 

                AREA    STACK, NOINIT,READWRITE, ALIGN=3

Stack_Mem          SPACE   USR_Stack_Size

__initial_sp            SPACE  ISR_Stack_Size

Stack_Top            EQU     Stack_Mem + ISR_Stack_Size

Heap_Size            EQU     0x00000100

 

AREA    HEAP, NOINIT,READWRITE, ALIGN=3

Heap_Mem           SPACE   Heap_Size

**********************************************************************************

; User Initial Stack & Heap

                    AREA    |.text|, CODE, READONLY

                             IMPORT __use_two_region_memory 

                        EXPORT  __user_initial_stackheap

__user_initial_stackheap

                LDR     R0, = Heap_Mem

               LDR     R1, =(Stack_Mem + USR_Stack_Size)

                LDR     R2, = (Heap_Mem +      Heap_Size)

                LDR     R3, = Stack_Mem

                BX      LR

使用了IMPORT  __use_two_region_memory,这种方式定义的堆栈和堆分别采用两个不同存储区。堆栈采用向下增长,FD类型。

可以看出堆栈段实际分配了0x4B8(1208)Byte空间,堆段分配了0x100(256)Byte空间。

用map文件来印证上述结论

Image Symbol Table

    Local Symbols

    Symbol Name                                   Value                Ov Type       Size     Object(Section)

HEAP                                        0x30050060      Section       256     s3c2440a.o(HEAP)

    Heap_Mem                                0x30050060       Data           256     s3c2440a.o(HEAP)

    STACK                                  0x30050160      Section       1208   s3c2440a.o(STACK)

    Stack_Mem                                0x30050160       Data           1024     s3c2440a.o(STACK)

    Stack_Top                               0x30050218       Data                  s3c2440a.o(STACK)

 

1.1.4    Keyled.map文件分析

Part1:Section Cross References

S3c2440a.o(STACK) refers (Special) toheapauxi.o(.text) for __use_two_region_memory

比如上面这句话,S3c2440a.o是S3c2440a.s生成的目标文件模块,(STACK)是文件内定义的一个段,链接器把它视为一个Section输入节。它引用了模块heapauxi.o输入节(.text)里面的一个全局符号__use_two_region_memory

s3c2440a.o(RESET) refers to __main.o(!!!main) for __main

__main.o(!!!main) refers to rtentry.o(.ARM.Collect$$rtentry$$00000000)for __rt_entry

rtentry2.o(.ARM.Collect$$rtentry$$0000000D)refers to keyled.o(.text) for main

上面这几个对于程序意义比较重大用户在启动代码s3c2440a.中调用了__main.o模块中的__main函数,__main又调用了rtentry.o中的__rt_entry函数,最后rtentry2.o又调用了用户定义的main主函数。

 

Part2:Adding Veneers to the image

Compiling code for interworking

 

Part3:Image Symbol Table

Local Symbols

       符号表里的局部符号:包括系统库内部的局部符号和用户的局部符号

Global Symbols

符号表里的全局符号:包括系统库内部的全局符号和用户的全局符号

 

Part4:Memory Map of the image

Image Entry point :0x000001a0è也就是__main()函数的地址

  Load Region LR_ROM1 (Base: 0x00000000, Size: 0x000003b4,Max: 0xffffffff, ABSOLUTE)

    Execution Region ER_ROM1 (Base: 0x00000000,Size: 0x000003b4, Max: 0x00200000, ABSOLUTE)

Base Addr      Size                   Type   Attr      Idx      ESection Name       Object

0x00000000  0x000001a0      Code     RO       18       RESET              s3c2440a.o

0x000001a0   0x00000008      Code     RO     29       * !!!main                 c_t.l(__main.o)

0x000001a8   0x0000003c      Code     RO     188   !!!scatter                c_t.l(__scatter.o)

0x000001e40x00000028      Code   RO      190   !!handler_copy          c_t.l(__scatter_copy.o)

0x0000020c  0x0000002c     Code   RO      192    !!handler_zi            c_t.l(__scatter_zi.o)

è可以看出,s3c2440a.o和__main.o都放在该执行域

 

Execution RegionRW_RAM1 (Base: 0x30050000, Size: 0x00000618, Max: 0x03000000, ABSOLUTE)

    Base Addr   Size             Type   Attr        Idx     E Section Name       Object

    0x30050000  0x00000060          Zero   RW       58      .bss                c_t.l(libspace.o)

    0x30050060  0x00000100          Zero   RW       17      HEAP                 s3c2440a.o

    0x30050160  0x000004b8          Zero   RW       16      STACK               s3c2440a.o

è可以看出,ZI和堆栈段都放在此执行域

 

    ExecutionRegion RW_IRAM1 (Base: 0x40000000, Size: 0x00000000, Max: 0x00001000, ABSOLUTE)

    **** No section assigned to this executionregion ****

è内部RAM没有存放任何东西,起始可以再分散加载文件中把它删掉

 

  LoadRegion LR_ROM2 (Base: 0x00001000, Size: 0x00000160, Max: 0xffffffff, ABSOLUTE)

    Execution Region ER_ROM2 (Base: 0x30000100,Size: 0x00000160, Max: 0x00004000, ABSOLUTE)

    Base Addr   Size             Type     Attr    Idx     ESection Name            Object

    0x30000100  0x00000160          Code     RO    1       .text                     keyled.o

è该域放置的是keyled.o文件

 

Part5:Image component sizes

指出各模块文件的大小

Code (inc. data):代码和内联数据                                                   Size:804+464=1268

RO data:只读的数据                                                                        Size:32+0=32

RW data:可读写的数据,存放的是初始化的全局变量和静态变量     Size:0

ZI data:存放的是未被初始化的全局变量和静态变量或是初始化为零的全局变量和静态变量

Size:1464+96=1560

      Code (inc. data)      RO Data   RW Data    ZI Data         Debug       Object Name

       352          12         0              0              0             3031         keyled.o

       452       148    0             0              1464         532            s3c2440a.o

   ----------------------------------------------------------------------

       804             160     32         0                1464       3563        Object Totals

         0      0        32         0             0            0               (incl. Generated)

         0      0       0              0             0           0               (incl. Padding)

   ----------------------------------------------------------------------

      Code (inc. data)   RO Data   RW Data    ZI Data      Debug  Library Member Name

         8      0       0          0          0          68             __main.o

        60     8      0          0          0          0                __scatter.o

        40       0      0          0          0          0                __scatter_copy.o

        44          0        0            0            0            0                 __scatter_zi.o

        12      0      0          0          0          64             exit.o

         6     0      0          0          0           136           heapauxi.o

         0      0       0          0          0          0                indicate_semi.o

        14          0          0          0          0          0  libinit.o

        12          0          0          0          0          0  libinit2.o

        12          0          0          0          0          0  libshutdown.o

         6          0          0          0          0          0  libshutdown2.o

        12          4          0          0         96         68  libspace.o

        12          4          0         0          0         68 rt_fp_status_addr_intlibspace.o

         0          0          0          0          0          0  rtentry.o

        44          4          0          0          0          0  rtentry2.o

         8          0          0          0          0          0  rtentry4.o

        8          0          0          0          0          0  rtexit.o

        12          0          0          0          0          0  rtexit2.o

        20          4          0          0          0         60  sys_exit.o

        96          0         0          0          0         80  sys_stackheap_outer.o

         4          0          0          0          0         68  use_no_semi.o

        28          0          0          0          0         80  fpinit.o

    ----------------------------------------------------------------------

       464        24         0          0        96       692   Library Totals

         6          0          0          0          0          0  (incl. Padding)

    ----------------------------------------------------------------------

==============================================================================

      Code (inc. data)   RO Data   RW Data    ZI Data      Debug  

      1268       184        32          0      1560      3907   Grand Totals

      1268        184         32          0       1560       3907  ELF Image Totals

      1268        184         32          0          0          0  ROM Totals

==============================================================================

    TotalRO  Size (Code + RO Data)                 1300 (  1.27kB)

    Total RW Size (RW Data + ZI Data)               1560(  1.52kB)

    Total ROM Size (Code + RO Data + RWData)       1300 (   1.27kB)

==============================================================================

 

原创粉丝点击