【arm学习】我的第一个裸板程序
初学ARM感觉写个裸板程序还真的不容易,可能是没有用到ADS,keil之类的开发平台的缘故吧。编译,链接过程在linux平台上完成,这样学起来更有实感,还能顺便熟悉linux环境,以及命令,何乐而不为呢?
为此得准备一些必要的基础知识,前几篇博客总结一些汇编的指令,以及makefile的总结。有兴趣的同学可以去看看。
汇编引导程序:

这段汇编代码做了3件事情:
1、关看门狗。
2、设置栈。
3、调用main函数。
这里想说明的就是,设置站。写C函数必须先设置栈,因为需要用栈来存放函数的参数值,局部变量的值等。
我用的2440的内部ram是4K,这里sp就指向了ram地址最大的地方,这是因为ARM-Thumb过程调用标准和ARM、Thumb C/C++ 编译器总是使用Full descending 类型堆栈。即栈首部是高地址,堆栈向低地址增长。
每次压栈(向栈里写数据),sp会先递减,再向地址中写数据,每次弹栈(把栈里数据读出),会先读出sp所指地址的数据,然后再将sp递增:用一张图来加强记忆:

想象每个内存都是一个装水的鱼缸,鱼缸的左上方有一个注水口,SP就是一个可以注水,也可以抽水的的水管。那么注水就是压栈过程,抽水就是弹栈过程。每次想注水时,先将sp向上一格到注水口处,再注水。每次抽水时,将水抽空之后,sp就向下移动一格。
感觉这样对比之后,整个过程就很容易理解和记忆了。
//---------------------拓展阅读---------------------
栈的增长方式有两种:向上 和 向下
为什么栈会有两种增长方式?
一般程序的变量都是从RAM的低地址开始分配的,变量从低地址开始分配的原因是很明显的,它可以在RAM容量增大时不用从新编译程序。早期的计算机系统的内存容量有限,将堆栈设计成从高地址向低地址增长,可以有限地利用所有的内存容量;同时在变量数目改变的时候,可以保持堆栈的起始地址不变。
现今内存容量变得越来越大,上述的安排就变得逐渐失去了意义;今天即使可以使用从低地址向高地址增长的堆栈,但应该很少会有人用,人们已经习惯成自然了。
Makefile:

又见这段makefile了,之前再上一篇博客《makefile学习总结》已经见到过了。
今天从第5行开始分析:arm-linux-ld 中的-Ttest选项,用来指定代码段的起始地址,在汇编引导程序的第6行的”.text”就表示该处是代码段的其实位置。-Ttest 0x0000,就是把该位置地址设置为0x00000。并且将编译后的文件链接起来,输出led_elf文件。到此就完成了编译,和链接工作。
但是事情并没有结束。对于ARM芯片来说,它不认识led_elf文件因为格式不对,我们需要生成arm认识的bin文件。
于是就用到第六行这条命令arm-linux-objcopy (被用来复制一个目标文件的内容到另一个文件中,可用于不同源文件的之间的格式转换),选项-O(大写)表示指定某个格式输出,-O binary,就表示已二进制格式输出。-S表示: 不从源文件中复制重定位信息和符号信息到目标文件中。这条命令执行玩了之后,就生成了bin文件,可以下载到arm中执行了。
如果还想看看反汇编文件,就可以用接下来这个命令:arm-linux-objdump(常用来显示二进制文件信息,常用来查看反汇编代码)-D表示反汇编所有段(-d表示反汇编可执行段); -m arm表示指定目标文件使用arm架构进行反汇编。 ‘>’表示把命令结果输出到文本文件中去。
C程序,如下就没什么好说的了~~

总结:一个裸板程序,我们用到了3个文件。
汇编引导程序:主要作用是设置栈,以及调用main函数。
C源程序:实现具体功能。
makefile:编译,链接以上文件,生成arm可执行的bin文件。
以上程序是运行在2440的内部ram上的,下节同样是一个裸板程序,将讲到如何将程序运行在2440外接的SDRAM上。
2014-11-26
宋桓公
【arm学习】我的第一个裸板程序的更多相关文章
- 6410裸板程序,led、蜂鸣器、按键…
//***************************************************************** //作者:昊天 // //功能:在ok6410板子上跑裸板程序, ...
- 第8课.第一个ARM裸板程序(点亮led)及申引
1.原理图 2.芯片手册 3.几条汇编代码 1.ldr:读内存 ldr R0, [R1] 假设R1的值是x,读取地址x上的数据(4字节),保存到R0中 ldr R0, =0x12345678 (4字节 ...
- JZs3c2440裸板程序GPIO操作总结
分别用汇编,汇编+C两种方式 ***************************************汇编编程led_on.s********************************** ...
- SpringMVC学习笔记二第一个小的程序
首先:我们要用springmvc来写一个helloworld的例子: 首先我们需要导入所需要的架包: /demo1/WebRoot/WEB-INF/lib/commons-logging-1.1.1. ...
- 【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42239705 参考博客 : [嵌入式开发]嵌入式 开发环境 (远 ...
- arm裸板驱动总结(makefile+lds链接脚本+裸板调试)
在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...
- ARM裸板开发:04_MMU 链接地址与运行地址不一致时,(SDRAM)初始化程序地址无关码问题的分析
ARM裸板开发过程,程序的链接地址设置为为0x30000000,而前期的启动代码以及相关硬件的初始化代码需要在内部iRAM(steppingstone,起始地址0x0)的4K中运行.链接地址与运行地址 ...
- 关于在arm裸板编程时使用printf问题的解决方法
在ARM裸板驱动编程中,是不允许程序直接调用C库程序的.为什么呢?因为此时kernel还没有被加载,所以在封装在kernel层的C库的API是用不了的,那怎么办? 在开发过程中,printf的功能我不 ...
- ARM裸板开发:07_IIC 通过IIC总线接口读写时钟芯片时间参数实现的总结
问题一:程序直接在iRAM内部可正常执行,而程序搬移(Nand ->SDRAM)之后,就不能正常运行了 #define NAND_SECTOR_SIZE 2048 /* 读函数 */ void ...
随机推荐
- Spark随机森林实战
package big.data.analyse.ml.randomforest import org.apache.spark.ml.Pipeline import org.apache.spark ...
- 利用MVC Chart 打造后台图表、前端图表
应用场景是这个样子的:要做导出数据到PDF的功能,涉及到文本.表格.图表等内容.在做图表功能时,发现之前用Highcharts做的图表根本就不能集成到PDF中.这里需要一个能在程序后台就生成图表的功能 ...
- SDN负载均衡
我负责的工作: (1).前期工作思路设计及方案选定.讲解 (2).后期代码修正 (3).视频制作 负载均衡程序 程序流程图 代码 from mininet.topo import Topo class ...
- swift是强类型语言
swift是强类型语言 所有的变量必须先声明,后使用: 指定类型的变量只能接收类型与之匹配的值. 强类型:变量的类型明确,变量的赋值必须符合类型约束:变量的类型转化必须显式进行. 强类型:类型规则的制 ...
- Actor模型---SwiftActors
actor是一个无线程区别的内存访问对象:actor背后有线程支持:actor的事件处理依赖与这个线程(队列.池). actor是一种面向对象的线程(池)模型,强调对事件的响应:在iOS中相当于一种通 ...
- Tengine 2.1.2 (nginx/1.6.2)安装配置,淘宝 Web 服务器
简介 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很 ...
- 请问下.net俱乐部这个组织现在还存在么?
各位好,我是北京的一名.net开发人员,一直在想有什么线下技术活动可以开拓自己的视野,扩展人脉,我知道曾经有一个.net俱乐部很活跃 可是现在我在百度上搜了下.net俱乐部的信息,已经基本找不到201 ...
- cenos6.5 python2.6.6升级至python2.7.3
踩坑无数... 一.参照以下两篇博文把python升级至python2.7.3 https://www.cnblogs.com/senzhe/p/6322214.html http://www.jb5 ...
- java使用纯命令行打包项目
1: javac -d 编译之后的class文件输出目录 指定源文件位置即可.例如 对于多个包下面的源码编译,貌似javac不支持迭代编译,可能需要一次传入多个源码位置进行编译.一种便捷方法就是使 ...
- day1-课堂代码
# # a = 1 # b = a # print(b) # # c = a + 1 # print(c) # # def add(x,y): # return x+y # # d = add(3,5 ...