【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 ...
随机推荐
- android 性能优化 -- 启动过程 冷启动 热启动
一.应用的启动方式 通常来说,启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动. 2.热启动:当启 ...
- 如何用 Python 实现 Web 抓取?
[编者按]本文作者为 Blog Bowl 联合创始人 Shaumik Daityari,主要介绍 Web 抓取技术的基本实现原理和方法.文章系国内 ITOM 管理平台 OneAPM 编译呈现,以下为正 ...
- python websocket client 使用
import websocket ws = websocket.WebSocket() ws.connect("xx.xx.xx") ws.send("string&qu ...
- .NET、ADO.NET、ASP.NET名称解析及.NET平台架构组成
转https://blog.csdn.net/xiaouncle/article/details/53265256 名词解释 1.Winform:Windows应用程序.桌面应用程序.C/S应用程序 ...
- sqlserver 一键备份,异机还原脚本
REM +---------------------------------------------------------------------------------+ REM |desc AU ...
- SQLServer中DataLength()和Len()两内置函数的区别(转载)
最近工作中遇到了个问题:在数据库中声明字段类型时char(4),但实际只存储了‘DCE’三个字母,程序中拼装以该字段作为key的Map中,会把‘DCE’+空格作为其Key,这样造成用没加空格的‘DCE ...
- 转:35个让人惊讶的 CSS3 动画效果演示
本文收集了35个惊人的 CSS3 动画演示,它们将证明 CSS3 Transform 和 Transition 属性的强大能力.CSS 是网页设计非常重要的一部分,随着越来越多的浏览器对 CSS3 支 ...
- python爬虫_入门_翻页
写出来的爬虫,肯定不能只在一个页面爬,只要要爬几个页面,甚至一个网站,这时候就需要用到翻页了 其实翻页很简单,还是这个页面http://bbs.fengniao.com/forum/10384633. ...
- 插入算法---java实现
插入排序java代码实现 package algorithms.插入排序; import java.io.BufferedReader; import java.io.InputStreamReade ...
- python第三十课--异常(raise关键字)
演示: 1.手动抛出异常对象-->raise关键字 2.try-except代码不能解决语法错误 try: print('try...') raise TypeError('类型有误的异常') ...