总结
这边简单讲讲,代码上电后从0开始发生了什么,为什么要重定位把代码复制到sdram,
bin文件前面几条跳转函数都跳转去哪 中断产生后发生什么
重定位问题
1.为什么需要重定位
把程序从一个位置移到另一个位置 叫重定位
可以只重定位部分段的数据 也可以把所有的都重定位到sdram中
一个程序有代码段,数据段,只读数据段,和bss段
整个程序开始能在 norflash上 运行的时候代码段从norflash上0位置开始运行
但是对于数据段 必须在sdram里面运行 因为norflash不支持简单的读写 和速度需求
我们的程序使用bin没有带地址(elf这种文件) 直接烧录 所以需要在bin文件中自己写重定位代码
对重定位 链接脚本 或者 elf 或者bin的知识忘了 就去查看 用幼儿园的话说链接脚本的文章
代码跑动流程
当时用norflash启动的时候,整个cpu通过内存控制器控制地址如下
1.cpu从0开始运行,也就是norflash上面开始运行,我们把bin文件烧在norflash上面
在bin文件前面的代码中也就需要把整个程序复制到sdram中
2.在链接脚本里面 指定runtime_addr(运行时地址) 变成sdram的地址 0x03000000
3.中断属于异常的一种,arm芯片有7种模式 通过cpu寄存器CPSR寄存器,表面自己目前处于哪种状态
在每种状态都有着专属的cpu寄存器(r0~PC15)能方便更快处理异常状态,当进入异常的时候,就会发送硬件行为,主动的跳到
异常向量表,这也就是为什么0地址,4地址,8地址等等等用来存放一些跳转地址,用来配置硬件的跳转
根据架构上的设定,在开发裸机的初始化程序,按照上面出来的设定有了如下的结构
编译出来的bin文件烧录到norflash后存储如下(注意:arm32位 一条指令占4位)
cpu从norflash的0地址开始运行 直接跳转到复位程序的地址,开始进行初始化跑动
初始化一般需要做重定位操作,把整个程序从nor_flash复制到sdram中,再从nor_flash跳到sdram继续运行,继续完成初始化操作
如果这时候突然发生了异常或者中断,会按照中断向量表的产生硬件行为,直接跳回nor_flash中 根据异常的不同进行 进行异常程序的跳转
用中断来举个例子
有很多种中断 什么软件中断 未识别指令异常中断
说到按键中断
1.初始化 设置中断,让它能发生中断(按键设置为中断引脚,定时器,网络数据这种硬件)
1.设置gpio为中断引脚
2.设置中断触发方式 中断方式为双边沿书触发
3.使能中断
4.读eintpend寄存器,分辨是哪个中断产生了
2.设置中断控制器,让中断控制器能发送中断给cpu
1.看起来外部中断4~7合用一条中断source通知中断控制器,也就是为什么上面的引脚设置中断还要读eintpend寄存器知道是哪条中断
2设置SRCPEND寄存器,知道是哪个中断产生了,同时执行完后需要清除对应位(bit0=外部中断0,bit2=外部中断2,bit5=外部中断8_23
如果bit5置1,还要读刚刚的eintpend寄存器,看是哪个中断产生了
3.设置是否要屏蔽这个中断(就算置为1,也不告诉cpu)
4.可能有多个中断产生,此时SRCPEND多个位设置为1,经过PRIORITY优先级寄存器,只有一个到cpu
5.最后优先级最高的被cpu处理,读取INTPND寄存器就知道哪个被cpu处理
3.设置cpu里面的寄存器cpsr寄存器,里面有个i位中断总开关,设置它使能中断
把cpu寄存器的CPSR第7位置0,这是中断总开关,bit7设置为1,cpu无法响应任何中断
4.中断发生,硬件处理
中断发生直接跳中断向量表的IRQ地址 ,再从这个地址跳去处理中断的函数地址
根据图中中断发生,此时硬件直接跳转到 0x18地址,在这个地址我们写的汇编为
b irq_handle 让cpu专门跳到我们写的中断处理函数地址,对中断进行识别和处理
5.跳过去的地址为我们自己写的中断处理函数,里面包含
1.程序先保存cpu寄存器地址,保存现场
cpu的lr_irq寄存器保存被中断时候,要处理的下一条地址
进入irq模式的时候会修改cpu寄存器的r0~r12所以要先保存
lr是处理完异常后的返回地址也要保存,处理完后把lr的值给cpu的PC寄存器就能返回上一次的地方
cpu寄存器SPSR_irq 保存被中断时候的 CPSR(区分cpu模式的cpu寄存器)
cpu寄存器CPSR M4~M0位置为10010,说明现在在中断模式
硬件主动跳到 0x18 中断向量表的IRQ地址 ,再从这个地址跳去处理中断的地址
2.程序处理异常
分辨中断源
读取INTPND寄存器就知道哪个中断被cpu处理
根据中断类型选择这个中断对应的中断函数
清理中断
3.恢复现场
把cpu寄存器的CPSR第7位清零,这是中断总开关,bit7设置为1,cpu无法响应任何中断
定时器怎么使用
定时器和pmw 只有先设置好定时器,才能初始化pwm
定时器设置
1.有个时钟进入定时器,每来个时钟 tcnt寄存器-1
2.当tcnt寄存器减少到 等于 tcnt_cmp寄存器的值 产生一个中断,也可以让对应的PMW引脚反转
3.tcnt寄存器继续减1,当tcnt寄存器等于0的时候,也能产生一个中断,pmw引脚也能翻转
4.当上面两个寄存器等于0的时候,可以选择从TCMPBN和TCNTBN里面把数值放入刚刚两个寄存器
上面就是定时器会触发中断 和 根pwm的关系文章来源:https://www.toymoban.com/news/detail-430999.html
怎么使用定时器呢 也有个图
1,设置时钟
从PCLK(低速时钟)过来设置PREschar预分频寄存器
2.设置初值
3.加载初值, 启动时钟
4.设置为自动加载初始化值
5,上面的中断程序怎么产生的
去中断那一章找到和定时器有关的中断
和上面一样触发了中断后 看是哪个中断源产生的中断
如果是INT_TIMER0 调用定时器的中断函数文章来源地址https://www.toymoban.com/news/detail-430999.html
到了这里,关于05_从0运行,重定位,初始化,中断再到定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!