rtthread在cortex-m4架构芯片的启动流程

rtthread在cortex-m4架构芯片上的启动流程

startup_pisces.S:

  1. 栈的配置(stack段)
  2. 堆的配置(heap段)
  3. 异常向量的配置(vector段)(暴露__Vectors地址)
  4. Reset_Handler(text段)
    1. 配置栈指针
    2. 把数据从只读的内存复制到RAM中,这里有两种方案(1.复制多个段;2.只复制一个段)(这里采用方案2)从代码看是将__etext段的内容复制到链接脚本中标定的data段
    3. (方案2)然后是将bss段的内容清0
    4. 跳转执行SystemInit(在system_pisces.c中), 这里主要初始化内容如下
      1. 将协处理寄存器CP11和CP10设为Full access,这两个协处理器是用来访问FPU寄存器的,主要是用来处理浮点数的计算。
      2. 将异常向量表的地址赋值到异常基址寄存器中
      3. 配置CACHE
    5. 跳转执行__start
  5. Default_Handler: 就是死循环
  6. 使用宏设置默认的Handler

startup.c: 从汇编代码跳转到c代码,操作系统的初始化
_start:

  1. 关闭中断
  2. 初始化中断,就是配置中断的优先级
  3. 初始化board
  4. 初始化tick
  5. 初始化kernel object
  6. 初始化定时器系统
  7. 初始化heap
  8. 初始化scheduler
  9. 初始化应用
  10. 初始化定时器线程
  11. 初始化idle线程
  12. 启动调度器

cpu上下文切换的实现context_gcc.S

操作的寄存器
  • PRIMASK(Priority Mask Register)
    仅第0位有效,置1的时候,就是屏蔽所有优先级可配置的中断

  • LR(Link Register)
    LR中保存的返回值
    在这里插入图片描述

  • Execution Program Status Register

Cortex-m4提供的一些指令
  • LDR(Load Register) and STR(Store Register)
    与mov指令的区别是:mov指令不能操作cpu寄存器和内存之间的数据交换。这种情况下只能使用ldr和str指令。
    例子:

    LDR R8, [R10]               ; Loads R8 from the address in R10.
    
    LDRNE R2, [R5, #960]!       ; Loads (conditionally) R2 from a word
                                ; 960 bytes above the address in R5, and
                                ; increments R5 by 960
    STR R2, [R9,#const-struc]   ; const-struc is an expression evaluating
                                ; to a constant in the range 0-4095.
    STRH R3, [R4], #4           ; Store R3 as halfword data into address in
                                ; R4, then increment R4 by 4
    LDRD R8, R9, [R3, #0x20]    ; Load R8 from a word 32 bytes above the
                                ; address in R3, and load R9 from a word 36
                                ; bytes above the address in R3
    STRD R0, R1, [R8], #-16     ; Store R0 to address in R8, and store R1 to
                                ; a word 4 bytes above the address in R8,
                                ; and then decrement R8 by 16.
    
  • MSR

    语法:MSR spec_reg, Rn

  • IT(If-Then condition instruction)

    语法:IT{x{y{z}}} cond
    x指定了第二条指令的条件
    y指定了第三条指令的条件开关
    z指定了第四条指令的条件开关
    cond指定了第一条指令的条件开关

    x,y,z可选的值:

    • T Then:应用cond设置的条件
    • E Else:cond不成立的时候

    例子:

    /*
    * if(R4 == R5)
    * {
    *   R7 = R8 + R9;
    *   R7 /= 2;
    * } else
    * {
    *   R7 = R10 + R11;
    *   R7 *= 2;
    * }
    */
    CMP R4, R5
    ITTEE   EQ
    ANDEQ   R7, R8, R9
    ASREQ   R7, R7, #1
    ADDNE   R7, R10, R11
    LSLNE   R7, R7, #1
  • Branch instructions

    语法:

    B   label   ; 
    BL  label
    BX  Rm
    BLX Rm
    

    所有的这些指令都会产生一个跳转,跳转到label或者是寄存器Rm中指示的地址。除此之外:

    1. BL和BLX指令会把下一条指令的地址写入到LR寄存器中
    2. 如果寄存器的第0位为0的话,BX和BLX会触发一个UsageFault

    限制:

    • 不要对PC寄存器使用BLX指令
    • 对于BX和BXL执行,只有当寄存器的第0位为1时才能正常执行,但是真正跳转的地址是将第0位改为0的值。
对外提供的接口
  • rt_hw_interrupt_disable
MRS     r0, PRIMASK     ; 将特殊寄存器RRIMASK寄存器的值写到r0寄存器中 
CPSID   I               ; 将RRIMASK寄存器的第0位置为1
BX      LR              ; 
  • rt_hw_interrupt_enable
MSR     PRIMASK, r0     ; 将r0寄存器的值写入到特殊寄存器PRIMASK中
BX      LR              ;
  • rt_hw_context_switch_interrupt(or rt_hw_context_switch)

    该函数的c语言形式定义为 void rt_hw_switch_interrupt(from, to)

    r0 -> from

    r1 -> to

    逻辑:

    1. 判断flag是否为1,是的话,直接跳转到步骤2,否则将flag值置为1,将from的值赋给rt_interrupt_from_thread,然后跳转到步骤2
    2. 将to的值赋给rt_interrupt_to_thread,执行步骤3
    3. 将0x10000000写入到INT_CTRL寄存器中,触发PendSV异常,执行步骤4
    4. BX LR
  • PendSV_Handler

    r0 -> switch from thread stack

    r1 -> switch to thread stack

    psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
    流程是:

    1. 上下文切换的时候关闭中断
    2. 获取flag值,如果flag为0,跳转到pendsv_exit,反之执行步骤3
    3. 将flag值置为0
    4. 获取rt_interrupt_from_thread的值,如果为0跳转到switch_to_thread,反之执行步骤5
    5. 获取线程栈指针psp,保存在r1寄存器中
    6. 寄存器压栈(r4-r11),栈顶的地址保存在r1寄存器中,然后将rt_interrupt_from_thread的值更新为当前r1寄存器的值
    7. switch_to_thread,加载to_thread的栈指针,保存在r1寄存器中。
    8. 将to_thread的栈中保存的寄存器状态pop出栈,然后更新r1寄存器的值(根据psp寄存器)
    9. pendsv_exit,恢复中断使能状态,返回
  • rt_hw_context_switch_to

  • rt_hw_interrupt_thread_switch

  • HardFault_Handler

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值