ARM 3

ARM RO RW ZI 说明 3转帖
2009/08/29 22:47

示例二:

    “iap.o”定义在“Exec_RAM1”中运行,所以设置“PI”属性;

    在调用“iap.c”中函数之前应该将其从“Load$$Exec_IAP$$Base”复制到指定的“Exec_RAM1”区域;

Load_region1 0x00000000 0x1fc

{

    EXEC_ROM1 0

    {

        Startup.o (vectors, FIRST)

        irq.o ( RO)

    }

}

Load_region2 0x00000200 0x3e600

{

    EXEC_ROM2 0

    {

        * ( RO)

    }

    Exec_IAP   0 PI               // 可能引起链接器未使用该属性警告,忽略

    {

        iap.o ( RO)

    }

    Exec_RAM1 0x40000000 0x4000

    {

        * ( RW, ZI)

    }

    Exec_Sram 0x80000000 0x40000

    {

        * (SRAM)

    }

}

// 移动“IAP.o”中的所有函数到“ImageExecIAPBase”加载区,并调用其中的函数

extern unsigned char Load$$Exec_IAP$$Base;

extern unsigned char Image$$Exec_IAP$$Length;

#define ImageExecIAPBase (0x40000000 0x1000)   // 加载区首址

void MoveIAPRO(void)

{

unsigned char * psrc, *pdst;

unsigned int count;

count = (unsigned int)   &Image$$Exec_IAP$$Length;

psrc = (unsigned char *)&Load$$Exec_IAP$$Base;

pdst = (unsigned char *)ImageExecIAPBase;

while (count--) {

*pdst = *psrc ;

}

}

// 调用“IAP.O”中的某函数

{

void (* pfnIAPWrite)(unsigned long, int);

pfnIAPWrite = (void (*)(unsigned long, int))

   (ImageExecIAPBase

   (unsigned int)IAPWrite -                        // 被调用函数名

   (unsigned int)&Load$$Exec_IAP$$Base);

pfnIAPWrite((int)((CUPDATA *)CODESTARTADDR)->data,

     ((CUPDATA *)CODESTARTADDR)->length);

    }

 

 

 

 

//————————————————————————————————————————————————————————————
ARM编译程序参考
介绍ARM编译程序的ARM特有方面,包括:
Pragmas                                     编译指示
Function keywords                    函数关键字
Variable declaration keywords 变量声明关键字

Pragmas
ARM编译程序可识别一下格式的编译指示:
#pragma [no_] feature-name
编译指示优于相关的命令行选项。
能识别的编译选项如下:


Pragma name
       
Default
       
Reference
arm section
       
Off
       
Pragmas controlling code generation
check_printf_formats
       
Off
       
Pragmas controlling printf and scanf argument checking
check_scanf_formats
       
Off
       
Pragmas controlling printf and scanf argument checking
check_stack
       
On
       
Pragmas controlling code generation
debug
       
On
       
Pragmas controlling debugging
import
       

       
code generation
Ospace
       

       
optimization
Otime
       

       
optimization
Onum
       

       
optimization
softfp_linkage
       
Off
       
code generation

 

    * check_printf_formats

该编译指示标记类似于printf的函数,如果存在文字格式串,则对照进行类型检查。
#pragma check_printf_formats
extern void myprintf(const char *format, …);
#pragma no_check_printf_formats

    * check_scanf_formats

该编译指示对声明为类似于scanf的函数做标记,以便对照文字格式串检查自变量的格式。
#pragma check_scanf_formats
extern void myformat(const char *format, …);
#pragma no_check_scanf_formats

    * debug 该编译指示可打开或关闭调试表生成, 如果指定#pragma no_debug,则不会为随后的声明和函数生成调试信息表条目,直到下一个#pragma debug出现。
    * Pragmas controlling optimization

Ospace
Otime
Onum

    * Pragmas controlling code generation
          o check_stack 如果已经使用了#pragma no_check_stack和-apcs/swst命令行选项禁止栈检查,则该编译指示可使的检查是否违反了栈限制的函数入口代码的重新生成。
          o once             同#ifndef …#endif效果相类似,用于头文件。但一般推荐使用#ifndef…#define。
          o softfp_linkage   该编译指示指定了至下一个#pragma no_softfp_linkage之间的所有函数声明描述了使用软件浮点链接的函数。__softfp关键字与该编译指示的效果相同
          o import(symbol_name) 该编译指示生成对symbol_name的导入引用。同如下汇编语言相同:IMPORT symbol_name。符号名作为外部符号放在映像的符号表中。
          o arm section section_sort_list This pragma specifies the code or data section name that used for subsequent function or objects.This include definitions of anonymous objects the compiler creates for initializations.该编译指示可指定代码或数据段的名称用于随后的函数或对象。包括编译程序为初始化而创建的匿名对象的定义。该选项对一下情况没有影响:

内联函数(及其局部静态变量)
模板实例(及其局部静态变量)
消除未使用的变量和函数
将定义写入目标文件中的顺序
                        该编译指示完整语法为:
                                #pragma arm section [sort_type[[=]“name”]][,sort_type=
“name”]
                        此处name用于段名称,sort_type可为如下之一code, rwdata, rodata
                        和zidata。若指定sort_type,没有指定name,则sort_type的段名被
                        重新设置为默认值。单独输入#pragma arm section,则所以对象段的
                         恢复为其默认值
int x1 = 5;                     // in .data (default)
    int y1[100];                    // in .bss (default)
    int const z1[3] = {1,2,3};      // in .constdata (default)
#pragma arm section rwdata = "foo", rodata = "bar"

int x2 = 5;                     // in foo (data part of region)
int y2[100];                    // in .bss
     int const z2[3] ={1,2,3};      // in bar
char *s2 = "abc";               // s2 in foo, "abc" in bar
#pragma arm section rodata
int x3 = 5;                     // in foo
int y3[100];                    // in .bss
      int const z3[3] ={1,2,3};      // in .constdata
char *s3 = "abc";               // s3 in foo, "abc" in .constdata
#pragma arm section code = "foo"
   int add1(int x)                   // in foo (code part of region)
      {
        return x 1;
      }
    #pragma arm section code


使用分散加载描述文件和链接程序,以控制将命名段放置在存储器中
                         的特定地址。
·          Function keywords
一些关键字指示编译程序对其某个函数进行特殊处理。包括函数内的声明,函数限定符及函数存储类限定符。即Declarations inside function, Function qualifiers and Function storage.
      __asm{assembler-code} 指示编译程序该语句是用汇编语言编写的。
      __irq      This enables a C or C function to be used as an interrupt routine called by the IRQ, or FIQ vectors. All corrupted registers except floating-point registers are preserved, not only those that are normally preserved under the ATPCS. The default ATPCS mode must be used. The function exits by setting the pc to lr-4 and the CPSR to the value in SPSR. It is not available in tcc or tcpp. No arguments or return values can be used with __irq functions.
      __pure      指明函数声明为纯的。纯函数没有了公共子表达式。默认情况下,函数假定是不纯的(产生副作用)。纯函数需要满足:其结果仅取决于其自变量的值;没有副作用,其不能调用非纯函数。不能使用全局变量或废弃指针,同一参数两次调用纯函数,返回应该相同
一般而言,一个程序包括只读的代码段和可读写的数据段。在ARM的集成开发环境中,只读的代码段和常量被称作RO段(ReadOnly);可读写的全局变量和静态变量被称作RW段(ReadWrite);RW段中要被初始化为零的变量被称为ZI段(ZeroInit)。对于嵌入式系统而言,程序映象都是存储在Flash存储器等一些非易失性器件中的,而在运行时,程序中的RW段必须重新装载到可读写的RAM中。这就涉及到程序的加载时域和运行时域。简单来说,程序的加载时域就是指程序烧入Flash中的状态,运行时域是指程序执行时的状态。对于比较简单的情况,可以在ADS集成开发环境的ARM LINKER选项中指定RO BASE和RW BASE,告知连接器RO和RW的连接基地址。对于复杂情况,如RO段被分成几部分并映射到存储空间的多个地方时,需要创建一个称为“分布装载描述文件”的文本文件,通知连接器把程序的某一部分连接在存储器的某个地址空间。需要指出的是,分布装载描述文件中的定义要按照系统重定向后的存储器分布情况进行。在引导程序完成初始化的任务后,应该把主程序转移到RAM中去运行,以加快系统的运行速度。
            什么是arm的映像文件,arm映像文件其实就是可执行文件,包括bin或hex两种格式,可以直接烧到rom里执行。在axd调试过程中,我们调试的是axf文件,其实这也是一种映像文件,它只是在bin文件中加了一个文件头和一些调试信息。映像文件一般由域组成,域最多由三个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处在的区域,它又分为加载域和运行域。加载域就是映像文件被静态存放的工作区域,一般来说flash里的 整个bin文件所在的地址空间就是加载域,当然在程序一般都不会放在 flash里执行,一般都会搬到sdram里运行工作,它们在被搬到sdram里工作所处的地址空间就是运行域。我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中ro段和rw段,还有所谓的zi段,这就是输出段。对于加载域中的输出段,一般来说ro段后面紧跟着rw段,rw段后面紧跟着zi段。在运行域中这些输出段并不连续,但rw和zi一定是连着的。zi段和rw段中的数据其实可以是rw属性。
                | Image$$RO$$Base| |Image$$RO$$Limit| |Image$$RW$$Base| |Image$$ZI$$Base| |Image$$ZI$$Limit|这几个变量是编译器通知的,我们在 makefile文件中可以看到它们的值。它们指示了在运行域中各个输出段所处的地址空间| Image$$RO$$Base| 就是ro段在运行域中的起始地址,|Image$$RO$$Limit| 是ro段在运行域中的截止地址。其它依次类推。我们可以在linker的output中指定,在 simple模式中,ro base对应的就是| Image$$RO$$Base|,rw base 对应的是|Image$$RW$$Base|,由于rw和zi相连,|Image$$ZI$$Base| 就等于|Image$$ZI$$limit| .其它的值都是编译器自动计算出来的。
                 下面是2410启动代码的搬运部分,我给出注释
            BaseOfROM DCD |Image$$RO$$Base|
            TopOfROM DCD |Image$$RO$$Limit|
            BaseOfBSS DCD |Image$$RW$$Base|
            BaseOfZero DCD |Image$$ZI$$Base|
            EndOfBSS DCD |Image$$ZI$$Limit|
            adr r0, ResetEntry;    ResetEntry是复位运行时域的起始地址,在boot
            nand中一般是0
            ldr r2, BaseOfROM;
            cmp r0, r2
            ldreq r0, TopOfROM;TopOfROM=0x30001de0,代码段地址的结束
            beq InitRam
            ldr r3, TopOfROM
            ;part 1,通过比较,将ro搬到sdram里,搬到的目的地址从 | Image$$RO$$Base| 开始,到|Image$$RO$$Limit|结束
           
            0
            ldmia r0!, {r4-r7}
            stmia r2!, {r4-r7}
            cmp r2, r3
            bcc %B0;
           
            ;part 2,搬rw段到sdram,目的地址从|Image$$RW$$Base| 开始,到|Image$$ZI$$Base|结束
            sub r2, r2, r3;r2=0
            sub r0, r0, r2   
            InitRam ;carry rw to baseofBSS
            ldr r2, BaseOfBSS ;TopOfROM=0x30001de0,baseofrw
            ldr r3, BaseOfZero ;BaseOfZero=0x30001de0
            0
            cmp r2, r3
            ldrcc r1, [r0], #4
            strcc r1, [r2], #4
            bcc %B0
            ;part 3,将sdram zi初始化为0,地址从|Image$$ZI$$Base|到|Image$$ZI$$Limit|
            mov r0, #0;init 0
            ldr r3, EndOfBSS;EndOfBSS=30001e40
            1
            cmp r2, r3
            strcc r0, [r2], #4
            bcc %B1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ARM M3核是一种基于ARM Cortex-M3内核的微处理器,它具有高效性、低功耗和高性能等优点,适用于各种应用领域,包括汽车、医疗、家电、航空航天等。ARM M3核的源代码是指它的软件开发工具链和开发环境,开发人员可以利用这些工具编写、调试和测试程序代码,以满足其应用需求。 ARM M3核源码包括许多组成部分,如编译器、调试器、IDE等,其中编译器是最重要的一部分,用于将源代码转换为可执行二进制代码。调试器则用于测试和优化程序,提高其性能和可靠性。IDE则是一个集成开发环境,用于开发人员编写代码、调试程序和管理项目。 ARM M3核源代码的开发需要具备专业的知识和技能,包括C语言编程、嵌入式系统设计、硬件和软件的调试等。开发人员还需要熟悉ARM架构,熟练掌握ARM指令集和寄存器的使用。 总之,ARM M3核源代码是一个有着广泛应用的软件开发工具链和环境,开发人员可利用它实现高效、低功耗和高性能的嵌入式系统。 ### 回答2: ARM M3核源码是指ARM公司所推出的一种嵌入式CPU芯片的软件源代码,它是一个基于32位RISC架构的处理器核心,适用于低功耗、高性能的应用领域。在嵌入式设备中,M3核可用于控制和驱动外部设备,执行实时处理和通信任务等。 M3核的源码是一种对软件开发者友好的编程环境,开发者可以充分利用ARM的工具链(Keil、IAR)进行开发,从而为嵌入式设备的应用开发提供更好的支持。这种源码可以帮助开发者在实现各种功能的过程中快速定位和解决程序出现的问题,提高软件开发的效率和质量。 M3核的源码囊括了控制器的周边模块,包括外设和中断控制器等,同时还提供了许多常见的应用程序范例,如通信、控制等,开发者可以进行二次开发以适应自己的具体应用需求。此外,ARM M3核源码还提供了一些最佳实践和设计建议,帮助开发者尽可能优化其编写的程序。 总之,ARM M3核源码富有可扩展性和可定制性,可用于各种低功耗嵌入式平台的应用程序开发,是支持嵌入式设备在功能、性能和功耗方面全面提升的重要组成部分。 ### 回答3: ARM M3核源码是指ARM Cortex-M3处理器的源代码。Cortex-M3是一个高性能、低功耗的32位处理器,是ARM公司在ARMv7-M架构中的一款主流产品。它具有高效的指令集,具有较快的运行速度和低功耗的特性,被广泛应用于嵌入式系统、汽车电子、智能家居、医疗等多个领域。 ARM M3核的源码可以在ARM公司官网上下载,开发者可以通过阅读和理解源码来更好地控制M3处理器的各种功能。通常情况下,开发者需要掌握汇编语言、C语言和嵌入式系统的基础知识才能够有效地进行源码分析和开发。同时,掌握M3 Cortex内部的寄存器、中断、时钟等操作原理也是必要条件。 虽然ARM M3核源码在嵌入式开发领域中非常重要,但是因为涉及到商业机密和专利问题,ARM公司严加保护其知识产权。因此,ARM M3核源码的获取和使用需要遵守ARM公司的许可和合同约定,未经许可和授权的使用可能会导致法律纠纷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值