小灯程序引发的思考
来源:互联网 发布:cad绘图软件 编辑:程序博客网 时间:2024/06/10 07:43
前段时间写了两篇文章,讲了关于GPIO方面的知识,之后继续学习裸机,当然跟刚开始学习编程一样要写helloword,嵌入式方面的话当然要点亮小灯了,哈哈
- 首先看关于小灯原理图
从原理图可以看到, nLEDx作为输出,且为低电平时,小灯会亮,对应关系为
nLED_1→GPF4
nLED_2→GPF5
nLED_4→GPF6
其次看下按键原理图
由于开发板上露出的三个按键标示的是 EINT0, EINT2, EINT11,所以在原理图上搜索这三个关键词,
关于按键方面的原理图主要分布在3个页面中
sh1:按键
sh2 : 描述中断引脚的图
sh3: 描述地址线,数据线引脚的图
从图中可以看到按键对应的关系
S2→GPF0
S3→GPF2
S4→GPG3(注意是GPGx, 非GPFx)
可能上面的图比较乱,初学者不知道切确的连接方法,下图给出了就按键S2的连接方法(原理图换了种方式)
从上面原理图分析可知, 按键,小灯与GPIO口的对应关系, 接下来,编码需要完成的一个功能是, 按键按下,小灯亮,松开,小灯灭,其控制关系为:
S2控制nLED_1–>(GPF0↔GPF4)
S3控制nLED_2–>(GPF2↔GPF5)
S4控制nLED_4–>(GPG3↔GPF6)查看数据手册,配置GPIO
从原理图来看,以S2控制nLED_1–>(GPF0↔GPF4) 来说明, S2按下(GPIO配置为输入, 检测到低电平, 即获得输入值判断为低电平, 那么灯亮, 即GPF4配置为输出,输出电平, 那么灯就亮),接下来必须通过数据手册来获得
1.如何配置输入输出
2.如何取GPIO状态, 从GPIO发送高低电平
由上面的关系可以看到, 控制的是GPFx 与GPGx 族, 就以GPFx说明
第9章 I/O PORTS中
上面介绍得知 GPF共有8个口, GPF0->GPF7
GPFCON 控制寄存器, 用来配置管脚的输入输出,如上图所示, 比如, GPF0 对应GPFCON寄存器的第0,1位
向0x56000050写00,即配置为输入功能, 写01即为输出功能
GPFDAT即状态寄存器, 比如GPF0为输入, 那么外接电路进来的是高电平, GPFDAT的第0位是1
GPF0若为输出,那么如果要向外接电路输出高电平, 那么向GPFDAT的第0位写1
对于GPFUP来讲,是配置芯片GPIO内部上拉电阻用,zj2440在GPIO的外围电路已经配置了上拉电阻,所以对这个寄存器配不配置其实无所谓
知道了如何配置寄存器后,直接贴出代码(参考的韦东山老师的例子,裸机的例子韦老师写的好啊)
- 例子分析
例子由三部分组成:
汇编->程序的入口
c文件->执行的函数
Mafile
1.crt0.S
1.1位置无关代码,位置相关代码
这个其实是 系统与编译器之间的暧昧关系,他们两者形成了一个默契,达成了一致
板子里运行的是linux系统, 而运行的程序是编译器生成的,所以OS与gcc 一拍脑袋,得了,运行的程序就以0x08048290开始运行吧,我们暂且将这个地址简称为地址A
对于OS: 来一个app让我运行, 我就把它放在我所管理的地址A上运行
对于gcc:对这个app进行编译,得指定运行地址啊(链接地址),我就运行地址设置为地址A,
这样OS运行这个app就能正确的运行
有人会问,那什么是位置无关代码呢?
答: gcc在编译app这个程序时,app所写的代码根本没有到地址A的信息,既然没有地址信息,也就是说放在系统哪个地方运行的结果应该是一样的, 比如说,app里就写个 a=1, b=2; c =a+b;
像这种代码,放在哪里都是一个结果。。所谓位置无关
那什么又是位置相关呢?
答:还是刚才的例子, gcc在编译这个app的时候, app的代码用到了地址!!!, 既然用到了地址,gcc就必须要提供正确的地址,当然,对于OS来说, gcc早已知道OS是从地址A开始运行的,所以链接地址从地址A开始,这样,app中用到地址的代码就能被正确的使用,对于位置相关, ldr pc, =main给出了很好的例子
我们知道, 裸机ram地址是从0开始运行,就是说我们要编译出的代码应该从0开始运行,所以考虑到可能存在位置相关的代码,所以在编译的时候需要指定一下链接地址是从0开始的,这样app中凡是用到地址的地方都能正确的被应用
我们先来看个正确的(指定链接地址从0开始)
对于ldr pc ,=main 来说, gcc在编译的时候 由于指定了从0地址开始编译, 所以用到地址的代码部分, 即ldr pc, =main翻译成了 两句话, 注意到cpu当执行到第10行的时候, pc被赋值成了0x0000018(编译时指定的),发生跳转,cpu就会跳转到0x0000018这个地址上, 即main的位置
假设在编译的时候不指定从0开始呢?
如果是这种情况,当我们把程序down到板子中会使板子,崩溃,如下图
我们把程序down到板子里运行, 电路逻辑会把代码搬运到sram中执行, cpu从sram的0地址开始执行程序,当执行到ldr pc时, 代码逻辑会将pc的值赋值成很大的数,cpu从而就跳飞了..
这个很大的数是编译链接造成的,如果链接时指定从0地址开始编译, 那么程序就正确了,所以这个ldr pc, =main这条指令,它依赖于地址, 所以位置有关.. 应用时一定要注意!
1.2关于流水线, ARM9是三级流水,至于什么是流水线就不多说了,网上可以找到很多的答案
疑问:
回答:
之后就是main函数了,下面的代码部分没什么好说的,网上都能下载到
- 小灯程序引发的思考
- 由一个小程序引发对 size_type类型的思考
- 写程序引发的思考
- 几个小例子引发的思考
- c#几个小例子引发的思考
- 程序人生----JavaScript引发的思考
- 一个双色球模拟程序引发的思考
- 链表程序引发的指针思考
- 小实验、小思考(一)------List添加对象引发的小思考
- CSDN小bug引发的思考,求赐教!
- 由简单小问题引发的思考和推理
- PHP:由一些小问题引发的思考
- 由lintcode 655题引发的小思考
- 一个十几行简单的C程序引发的思考
- 一个C++程序编译失败引发的思考
- 由一段程序引发关于对象的思考
- Yaffs引发的思考
- LPCSTR引发的思考
- 对象切片
- UE4 地形无碰撞解决方案
- 单例设计模式多种实现方式
- 使用LVS+DR搭建集群实现负载均衡
- HTTP长连接和短连接
- 小灯程序引发的思考
- 字符串操作
- 12
- 排列组合问题1
- 解析JSON
- 算法面试题
- Tensorflow一些常用基本概念与函数
- kmp模板
- 前端单选按钮radio的显示隐藏以及JS重置功能