Embedded 重置后嵌入式代码如何执行

Embedded 重置后嵌入式代码如何执行,embedded,runtime,microcontroller,execution,Embedded,Runtime,Microcontroller,Execution,我不熟悉控制器编码。请任何人帮助我理解以下几点 代码如何在控制器中执行 如果我们将代码转储到控制器,它将保存在闪存中。重置后,代码将如何从内存中提取 在控制器中执行的所有过程是什么 我知道,在运行时,代码将被复制到RAM内存(?),并从RAM执行。这个说法正确吗?如果是,闪存代码何时移动到RAM? 5.如果代码将从闪存复制到RAM,则将使用RAM空间。那么大量的RAM字节被占用了,所以堆栈和堆需要在这个内存之后使用吗 我真搞不懂它是怎么工作的。你说的控制器是指微控制器吗 微控制器被设计成芯片上的

我不熟悉控制器编码。请任何人帮助我理解以下几点

  • 代码如何在控制器中执行
  • 如果我们将代码转储到控制器,它将保存在闪存中。重置后,代码将如何从内存中提取
  • 在控制器中执行的所有过程是什么
  • 我知道,在运行时,代码将被复制到RAM内存(?),并从RAM执行。这个说法正确吗?如果是,闪存代码何时移动到RAM? 5.如果代码将从闪存复制到RAM,则将使用RAM空间。那么大量的RAM字节被占用了,所以堆栈和堆需要在这个内存之后使用吗

  • 我真搞不懂它是怎么工作的。

    你说的控制器是指微控制器吗

    微控制器被设计成芯片上的系统,这包括程序所在的非易失性存储器。即闪存或其他形式的rom。就像在x86台式机/笔记本电脑/服务器上一样,在处理器用于引导的地址处,处理器的地址空间中有一些rom/flash。您没有指定微控制器,因此具体地址和这些细节取决于您正在谈论的微控制器,但这并不重要,一般来说,它们都倾向于以相同的方式工作

    因此,有一些闪存可用作映射到处理器地址空间、复位/中断向量表或起始地址或架构要求的任何内容的通用术语,加上您的程序/应用程序在地址空间的闪存中。同样,内存也有一定的数量,通常你不会像在笔记本电脑/台式机/服务器上那样从内存运行你的程序,内存往往相对较小,闪存是用来让你的程序运行的。也有例外情况,例如性能,有时闪存在等待状态下运行,而且sram通常可以以cpu速率运行,因此您可能希望将一些对执行时间敏感的例程复制到要运行的ram中。但一般来说不是这样

    当然也有例外,这些情况包括逻辑理想情况下,但有时芯片中有一个半机密rom,带有引导加载程序,但您的程序从芯片外部加载到ram中,然后运行。有时,出于某种原因,您可能希望以这种方式设计应用程序,并且具有引导加载程序并不少见,许多微控制器在单独的闪存空间中有一个芯片供应商提供的引导加载程序,您可能无法替换,这允许您对闪存进行开发或电路编程

    微控制器包含一个处理器,就像你的台式机/笔记本电脑/服务器或电话或其他类似的东西。它是一个芯片上的系统,而不是分散在一块板上,所以你有处理器本身,你有一些非易失性存储器,如上所述,你有ram和外设都在同一个芯片上。因此,就像任何其他处理器一样,它的引导和运行有逻辑/设计定义的规则(使用地址向量表或使用众所周知的入口点地址),但除此之外,执行的只是机器代码指令。没什么特别的。所有运行的进程都是您编写并告诉它运行的进程,它运行的是您编写的软件,而最终只是机器代码。进程、函数、线程、任务、过程等等这些都是试图管理软件开发的人类术语,您可以选择语言(尽管绝大多数是用C语言编写的,只需少量汇编)和软件设计,只要它符合系统的约束

    编辑

    假设我有一个arm微控制器,闪存从地址0x00000000开始,ram从地址0x20000000开始。假设有一个较老的arm,比如微控制器中使用的ARM7TDMI(其中一些仍然可以购买)。因此,处理器引导的方式是,存在已知的地址,执行开始时会重置、中断和未定义的异常等。重置地址为0x00000000,因此在重置后,处理器在地址0x00000000处开始执行,它首先读取该指令并运行它。下一个异常处理程序在地址0x00000004处开始执行,以此类推,处理几个可能的异常,因此您将看到我们必须从这个异常表中分支出来。作为我们做的第一件事

    下面是一个示例程序,它可以运行,但没有做任何有趣的事情,只是演示了一些事情

    向量

    .globl _start
    _start:
        b reset
        b hang
        b hang
        b hang
        b hang
        b hang
        b hang
        b hang
    
    reset:
        mov sp,#0x20000000
        orr sp,sp,0x8000
        bl one
    hang: b hang
    
    一、c

    二、c

    memmap(链接器脚本)

    然后我建造它

    arm-none-eabi-as --warn --fatal-warnings vectors.s -o vectors.o
    arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c one.c -o one.o
    arm-none-eabi-gcc -Wall -Werror -O2 -nostdlib -nostartfiles -ffreestanding -c two.c -o two.o
    arm-none-eabi-ld vectors.o one.o two.o -T memmap -o so.elf
    arm-none-eabi-objdump -D so.elf > so.list
    
    在查看链接输出之前,我们可以查看各个部分

    arm-none-eabi-objdump -D vectors.o
    
    vectors.o:     file format elf32-littlearm
    
    
    Disassembly of section .text:
    
    00000000 <_start>:
       0:   ea000006    b   20 <reset>
       4:   ea000008    b   2c <hang>
       8:   ea000007    b   2c <hang>
       c:   ea000006    b   2c <hang>
      10:   ea000005    b   2c <hang>
      14:   ea000004    b   2c <hang>
      18:   ea000003    b   2c <hang>
      1c:   ea000002    b   2c <hang>
    
    00000020 <reset>:
      20:   e3a0d202    mov sp, #536870912  ; 0x20000000
      24:   e38dd902    orr sp, sp, #32768  ; 0x8000
      28:   ebfffffe    bl  0 <one>
    
    0000002c <hang>:
      2c:   eafffffe    b   2c <hang>
    
    请注意,所有地址都是从零开始的,它们尚未链接

    如果你自己看的话,这两者是相似的

    链接器脚本告诉链接器我们想要.text程序,机器代码为0x00000000,而.bss为0x20000000。bss是全局的东西,没有像

    unsigned int this:
    
    .这里我不处理的数据如下

    unsigned int this=5;
    
    全局初始化的东西,.bss被程序员假定为零,但我在这里作弊,没有将.bss内存空间归零,你会看到,相反,我初始化了程序中的变量,而不是预先初始化它们,并且不得不做不同的工作

    reset:
        mov sp,#0x20000000
        orr sp,sp,#0x8000
        bl one
    hang: b hang
    
    通常,像上面这样的引导程序需要根据需要处理堆栈(当然是在这种裸金属微控制器代码的情况下)以及zero.bss和copy.data到ram。它需要更多的链接器和编译器来放置初始化变量

    unsigned int like_this=7;
    
    在flash中,我们需要记住的是,值为7的变量引导和ram是不稳定的,在断电后无法生存。因此,为了支持.data,您必须告诉链接器它想要住在0x2000xxxx中,但将其放在flash中的某个位置,我将复制它。我没有在这里证明这一点

       c:   e59f402c    ldr r4, [pc, #44]   ; 40 <one+0x40>
      10:   e59f502c    ldr r5, [pc, #44]   ; 44 <one+0x44>
    
      18:   e5853000    str r3, [r5]
      1c:   e5842000    str r2, [r4]
    
    hello=5;
    world=6;
    
    unsigned int this:
    
    unsigned int this=5;
    
    reset:
        mov sp,#0x20000000
        orr sp,sp,#0x8000
        bl one
    hang: b hang
    
    unsigned int like_this=7;
    
    Disassembly of section .text:
    
    00000000 <_start>:
       0:   ea000006    b   20 <reset>
       4:   ea000008    b   2c <hang>
       8:   ea000007    b   2c <hang>
       c:   ea000006    b   2c <hang>
      10:   ea000005    b   2c <hang>
      14:   ea000004    b   2c <hang>
      18:   ea000003    b   2c <hang>
      1c:   ea000002    b   2c <hang>
    
    00000020 <reset>:
      20:   e3a0d202    mov sp, #536870912  ; 0x20000000
      24:   e38dd902    orr sp, sp, #32768  ; 0x8000
      28:   eb000000    bl  30 <one>
    
    0000002c <hang>:
      2c:   eafffffe    b   2c <hang>
    
    00000030 <one>:
      30:   e3a03005    mov r3, #5
      34:   e3a02006    mov r2, #6
      38:   e92d4070    push    {r4, r5, r6, lr}
      3c:   e59f402c    ldr r4, [pc, #44]   ; 70 <one+0x40>
      40:   e59f502c    ldr r5, [pc, #44]   ; 74 <one+0x44>
      44:   e1a00003    mov r0, r3
      48:   e5853000    str r3, [r5]
      4c:   e5842000    str r2, [r4]
      50:   eb000008    bl  78 <two>
      54:   e5943000    ldr r3, [r4]
      58:   e5952000    ldr r2, [r5]
      5c:   e0800003    add r0, r0, r3
      60:   e5840000    str r0, [r4]
      64:   e0800002    add r0, r0, r2
      68:   e8bd4070    pop {r4, r5, r6, lr}
      6c:   e12fff1e    bx  lr
      70:   20000004    andcs   r0, r0, r4
      74:   20000000    andcs   r0, r0, r0
    
    00000078 <two>:
      78:   e59fc02c    ldr r12, [pc, #44]  ; ac <two+0x34>
      7c:   e59f102c    ldr r1, [pc, #44]   ; b0 <two+0x38>
      80:   e59c2000    ldr r2, [r12]
      84:   e5913000    ldr r3, [r1]
      88:   e2822001    add r2, r2, #1
      8c:   e2833002    add r3, r3, #2
      90:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
      94:   e082e003    add lr, r2, r3
      98:   e08e0000    add r0, lr, r0
      9c:   e58c2000    str r2, [r12]
      a0:   e5813000    str r3, [r1]
      a4:   e49de004    pop {lr}        ; (ldr lr, [sp], #4)
      a8:   e12fff1e    bx  lr
      ac:   20000000    andcs   r0, r0, r0
      b0:   20000004    andcs   r0, r0, r4
    
    Disassembly of section .bss:
    
    20000000 <hello>:
    20000000:   00000000    andeq   r0, r0, r0
    
    20000004 <world>:
    20000004:   00000000    andeq   r0, r0, r0
    
      28:   eb000000    bl  30 <one>
    
      50:   eb000008    bl  78 <two>
    
    20000000 <hello>:
    20000000:   00000000    andeq   r0, r0, r0
    
    20000004 <world>:
    20000004:   00000000    andeq   r0, r0, r0
    
      78:   e59fc02c    ldr r12, [pc, #44]  ; ac <two+0x34>
      7c:   e59f102c    ldr r1, [pc, #44]   ; b0 <two+0x38>
      80:   e59c2000    ldr r2, [r12]
      84:   e5913000    ldr r3, [r1]
    
    
      ac:   20000000    andcs   r0, r0, r0
      b0:   20000004    andcs   r0, r0, r4
    
    arm-none-eaby-objcopy so.elf -O binary so.bin
    
    arm-none-eabi-objcopy so.elf -O binary so.bin
    calvin so # hexdump so.bin
    0000000 0006 ea00 0008 ea00 0007 ea00 0006 ea00
    0000010 0005 ea00 0004 ea00 0003 ea00 0002 ea00
    0000020 d202 e3a0 d902 e38d 0000 eb00 fffe eaff
    0000030 3005 e3a0 2006 e3a0 4070 e92d 402c e59f
    0000040 502c e59f 0003 e1a0 3000 e585 2000 e584
    0000050 0008 eb00 3000 e594 2000 e595 0003 e080
    0000060 0000 e584 0002 e080 4070 e8bd ff1e e12f
    0000070 0004 2000 0000 2000 c02c e59f 102c e59f
    0000080 2000 e59c 3000 e591 2001 e282 3002 e283
    0000090 e004 e52d e003 e082 0000 e08e 2000 e58c
    00000a0 3000 e581 e004 e49d ff1e e12f 0000 2000
    00000b0 0004 2000                              
    00000b4
    
    0000000 0006 ea00 0008 ea00 0007 ea00 0006 ea00
    
    00000000 <_start>:
       0:   ea000006    b   20 <reset>
       4:   ea000008    b   2c <hang>
       8:   ea000007    b   2c <hang>