时钟系统初始化代码解析: 关闭PLL输出 设置各PLL的lock time 设置分频系数 设置PLL倍频参数 使能各PLL 时钟系统参数设置完成后,打开各PLL,在lock time之后SoC各模块将按照我们设置的值工作
函数栈帧分析: 1 注意lr和fp的入栈位置 lr是R14,fp是R11,所以入栈后lr在高地址,fp在低地址 2 此次main函数栈中保存了lr 这是因为main函数还要调用func1函数,所以将lr寄存器压栈。即非叶子函数在建立函数栈时,需要将lr入栈保存。 3 超出r0 ~ r3的参数通过主调
注意1:bss段是不需要重定位的,后续的clean_bss过程会将该段内存清空。如果将运行地址处的bss段拷贝到链接地址处,没有实际意义~~ 注意2:清bss段应该在内存初始化之后,此处均使用iRAM,所以没有突出该问题。
由于nuttx中切换到svc模式处理中断,且使用的栈也在svc模式,所以需要恢复2个现场, a. svc中断处理前后的现场(因为切换到svc模式处理中断,这是问题的根源) b. 中断发生前模式现场的恢复 此处借助恢复中断发生前模式现场的时机恢复svc中断处理现场是很巧妙的,核心就是认为切换到目标模式
1 ENTRY(SYMBOL) 将符号SYMBOL的值设置成入口地址,arm-linux-ld 有多种方法设置进程入口地址,按优先级排序如下: 使用arm-linux-ld 的-e 选项 链接脚本中的ENTRY(SYMBOL)命令 如果定义了start 符号,使用start 符号值 如果存在.tex
1 所谓内存初始化就是设置SoC内部的DRAM controller(简称DMC) 2 DMC的主要功能有2点, a. 地址信号转换 程序中的物理地址 --> 地址线上的信号 --> 内存内部的寻址信号 b. 处理内存访问的各种时序(由于时序复杂,所以优先使用内存原厂代码)
注1:非向量中断处理方式中通过软件识别中断源后,再去查表执行ISR 注2:此处读写VICADDRESS寄存器只是为了维护内部优先级模块的状态(但是是必须的~~) 注3:这种非向量用法通常在有操作系统时使用。因为中断处理中使用的很多资源是在SVC模式下运行的,一般会通过软件从IRQ模式切换到SVC模式
5.1 ARM指令集分类 1 数据处理类指令:完成CPU内部的计算(仅涉及寄存器) 2 Load/Store指令:完成CPU与内存/IO外设之间的数据传输 3 跳转指令:完成程序的跳转 4 程序状态寄存器处理指令:完成CPSR的管理 5 协处理器指令:完成CPU扩展功能的实现· 6 异常产生指令:用
BL1的一般任务: 1 环境初始化,尤其是内存初始化。 BL1是由CPU在启动过程中自动从SD卡加载到iRAM中运行,需要为BL2的运行准备环境。 其实BL2有2个运行场所,如果BL2 < 80KB则可以加载到iRAM中运行;如果BL2 > 80KB则只能加载到内存中运行。 虽然S5PV
1 va_start宏中,通过&(A)取得的就是形参fmt变量的地址,在示例中就是栈中的0x100地址 然后在该地址的基础上,就可以计算出可变参数的起始位置,也就是0x104地址 2 va_arg宏则是根据可变参数的类型,逐个遍历可变参数,此时需要格式字符串标识的类型与实际可变参数的类型一致