Part2:S3C2440落跑一个LED程序

  • 0 写在前面
  • 1 明确“操作对象”和“操作过程”
  • 2 代码编写和分析——看一个程序如何裸跑...
    • 2.1 代码编写
      • 2.1.1 汇编代码——点亮一个LED
      • 2.1.2 C代码——点亮一个LED
    • 2.2 代码分析——揭秘程序启动及函数调用过程
    • 2.3 运行结果(后面补上)

0 写在前面

目标:点亮一个在ARM9为核心的s3c2240开发板上的LED——>like "Hello world"
三步走:1)读原理图,明确操作对象——即找到LED输出引脚2)  明确操作,即如何控制LED3)代码编写——重点!分别用汇编和C实现
这里,我把1)2)步合成一部分讲解,重点讲解代码编写(涉及到ARM汇编指令、C函数调用栈机制)
备注一点:限于篇幅,我把S3C如何烧写程序步骤省去了。因为这不是本文关注的重点,也不是我们要掌握的重点。

1 明确“操作对象”和“操作过程”

操作对象——LED引脚在看原理图时,涉及一些模电知识,如二极管、三极管 :)对于LED发光二极管,有贴片和插脚两种,但两者点亮的工作原理是相同的(Note: 此处略过不讲,有兴趣的可自行查阅)操作过程——GPFCON和GPFDAT 设置一个引脚可用作输出、输入、中断等使用故,这里需先配置LED对于引脚为输出,查阅手册可得,需修改GPFCON对应位然后,即可操作引脚寄存器的值了,也就能够改变LED的状态(熄灭、点亮)这里,0——点亮1——熄灭

2 代码编写和分析——看一个程序如何裸跑…

2.1 代码编写
2.1.1 汇编代码——点亮一个LED
再开始编写如何点亮一个LED的汇编程序前,需理解几个汇编指令用法1)LDR:读内存指令,如 ldr r0, [r1]   读取r1地址值对应的4字节内存值到r02)STR:写内存指令,如str r0, [0x1234] 将r0寄存器值写入0x00001234地址开始的4字节内存3)B:跳转4)MOV:如 MOV r0, r1 将r1的值复制为r0,注意是从右往左,像AT&T汇编风格,但与Intel风格相反5)LDR R0, =0x12345678 伪指令,最终被解析为几条ARM的真正指令,注意区分LDR,这里是有=的,切忌写成#立即数了
此外,还要知道几个寄存器及其作用,S3C2440有常见16个寄存器(总共27个),s0至s15,它们有对应的别名,如sp、lr、pc等这里介绍这里涉及到的三个重要寄存器:pc、sp、lrpc:是保存下条指令的地址,注意实际是当前指令 + 8,因为使用了流水线...一个时钟周期,执行--译码--取指是同时进行的也就是说,在执行A地址指令时,也在对A+4指令译码,并读取A+8的指令lr:保存函数返回地址sp:栈顶指针
下面是点亮一个LED1(GPF4)的汇编程序 led_on.S
.text
.global _start
_start:/*配置GPF4引脚为输出 */ldr r1,=0x56000050mov r0,#0x100 /*ldr r0,=0x100*/sdr r0,[r1]/*设置GPF4引脚输出0,这里0即点亮,1则熄灭*/ldr r1,=0x56000054mov r0,#0  /*ldr r0,=0*/sdr r0,[r1]
halt:   /*死循环*/b halt
补充一点:GPIO即“通用IO”,GPIO控制器里的寄存器在CPU眼里就像内存,
即它们是统一编址,而不是独立编址。故0x56000050即是GPFCON配置寄存器,
0x56000054是CPGDAT数据寄存器。
(统一编址,即对外设寄存器也作为外部地址总线可寻址范围内的一部分,CPU就像访问内存一样
而独立编址,即这些外设寄存器有自己的编址空间,CPU访问它们需向相应控制器发送/接收命令)
2.1.2 C代码——点亮一个LED
实现之前,涉及一些C语言的指针操作、字节序、位操作、函数调用栈、一个程序如何启动运行等知识
这里简要概括下,在后面代码分析时会着重详细讲解。
C语言的指针操作:从底层角度看1)一切变量在内存中都有一块区域2)可通过变量或指针操作内存如 int a = 10;  ---->a = 20; 把20写入a地址处的4字节内存,a是intint* pa= &a; ----> *pa = 40;  把40写入(*pa地址处)(即a地址处)的4字节内存,*pa指向4字节内存
字节序:大端序:内存高地址开始存放低地址的值小端序:内存低地址开始存放低地址的值有个形象类比记忆。桌面为高地址,一个鸡蛋放在桌面上有两种竖直放法(当然,除去横着放:)1)鸡蛋大端在桌面时,属于低地址放在高地址,则为大端2)鸡蛋小端在桌面时,属于高地址放在高地址,则为小端前提:鸡蛋从大端-->小端 == 低地址--->高地址
位操作:与或非、异或、移位这些很好理解难点在于它们的组成使用,例如怎样置位/清零某一个或几个位呢?这要多加练习才能掌握
函数调用栈:涉及三个问题:1)调用者参数如何传递给被调用者,被调用者的返回值如何返回给调用者2)main函数谁调用的,局部变量保存在内存哪里3)函数调用惯例问题(即ATPCS,后面有补充),即被调用者和调用者谁负责保存哪些寄存器,返回时谁恢复在三个问题答案在后面代码分析中。
一个程序如何启动运行:针对S3C2440这款开发板而言两个地方可供CPU读取第一条指令:NOR 和 NAND Flash --->可用版上拨码开关选择1)NOR启动: CPU从 NOR Flash 的基地址0 开始读取,此时片内RAM地址为0x4000,00002)NAND启动:CPU从片内4K RAM 基地址0开始读取,此时 NOR Flash不可用2440硬件把NAND前4K内容读取到片内4KRAM中,然后CPU从0地址处读取第一条指令开始指令补充一点:在S3C2440开发板中,NAND Flash 256MB,而NOR Flash仅2M左右
下面是C实现的点亮一个LED代码 led.c
int main()
{unsigned int *pGPFCON = (unsigned int*)0x56000050;unsigned int *pGPFDAT = (unsigned int*)0x56000054;/*配置GPF4为输出引脚*/*pGPFCON = 0x100;/*设置GPF4引脚输出0,即点亮LED1*/*pGPFDAT = 0;return 0;
}

此外,还需要一个调用main函数的启动汇编代码 start.S

.text
.global _start
_start:ldt  sp,=4096  /* nand启动*/// ldt sp,=0x40000000 + 4096 /* nor启动 */bl  main
halt:b halt
最后,来个makefile文件
all:arm-linux-gcc -c -o led.o  led.carm-linux-gcc -c -o start.o start.Sarm-linux-ld -Ttext 0 start.o led.o -o led.elfarm-linux-objcopy -O binary led.elf led.binarm-linux-objdump -D led.elf > led.dis
clean:rm *.bin *.o *.elf *.dis
执行make即可生成二进制代码led.bin,烧写进开发板即可
(备注:汇编实现的点亮LED的makefile文件一样,修改生成的目标文件名即可)
2.2 代码分析——揭秘程序启动及函数调用过程
这里看下C代码实现点亮LED1的反汇编代码、内存布局及程序执行流程图

分析一下:
1)上电启动过程:这里使用的是NAND启动,故上电后,从片内4KROM的0x00000000基地址处取第一条指令指令
2)函数调用机制的三大部分:保存现场-->函数功能--->恢复现场这时候可以回答之前三个问题了。1)main函数由启动程序调用,局部变量保存在被调用者栈中2)被调用者负责保护现场和恢复现场(现场或者上下文,指一些调用者寄存器和sp预先分配局部变量所需栈空间)3)调用者将传递的参数保存在一些寄存器中(看下图)(注意:参数很多时可压入调用者栈中供被调用者使用)-->本应代码演示,限于篇幅,可自己验证而被调用者通过指定的寄存器保存返回值,还可以直接将返回值写入调用者的栈中

备注一点:下图是来自韦东山老师上课时的笔记文档(偷懒的我:)

补充一点:ATPCS即ARM-THUMB procedure call standard(ARM-Thumb过程调用标准)的简称
引自百度:

PCS规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,
所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议
言而总之,PCS强制实现如下约定:调用函数如何传递参数(即压栈方法,以何种方式存放参数),被调用函数如何获取参数,以何种方式传递函数返回值

2.3 运行结果(后面补上)
[无...],先欠着:),我都板子还在路上....哭辽...顺风不应该隔天到?
?难道我这里太山啦?
好吧,穷孩子看书去了....

Part2:S3C2440裸跑一个LED程序相关推荐

  1. 服务器实践002 -- 裸跑一个flask程序

    安装 基本依赖 mkvirtualenv blog --python=python3 # 创建python3虚拟环境 pip install flask --index http://pypi.dou ...

  2. 在Android开发板跑一个LED驱动的历程(个人笔记)

    [版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 在Android开发板跑一个LED驱动的历程(个人笔记) 1. 板子端, 放置驱动程序 1.1 编写一个驱动程序 驱动程序的编写上, ...

  3. 任哲ucos第二版 如何用精简版的borland C++3.1跑一个简单程序 【转】

    转自http://zhangzhenyuan163.blog.163.com/blog/static/858193892011427111228258/ Borland C++ 在C:\bc  中 t ...

  4. elf section类型_在 498 行极小 OS 上跑标准 ELF 程序

    本文首发于 在 498 行极小系统跑标准 ELF 程序 简介 ELF 在 Linux 系统中作为标准可执行文件格式已经存在了 ~25 年. 如果要在 Linux 下直接研究 ELF,通常很难绕过 Li ...

  5. 阿里云python轻应用学习笔记(二)---开发一个LED跑马灯程序

    摘要:本篇文章将使用python开发一个LED闪烁的程序.程序源代码从官方帮助文档复制过来,开发的时候会遇到一些错误,本篇文章也一并提供解决方法. 实验目的:编写python程序,实现LED跑马灯. ...

  6. 01-第一个裸机程序led及其引申

    目录 第一节 硬件知识_LED原理图 1. 点亮LED需要做的事情: 2. LED原理图 第二节:S3C2440启动流程与GPIO 1.原理图中的net 2.看芯片手册 3.补充几个概念.补充S3C2 ...

  7. Zigbee之旅(二):第一个CC2430程序——LED灯闪烁实验

    Zigbee之旅(二):第一个CC2430程序--LED灯闪烁实验 一.承上启下 在上一篇文章<Zigbee之旅(一):开天辟地>中,我们简要的介绍了Zigbee,以及其开发环境的搭建.O ...

  8. 玩转Zynq连载29——[ex51] 制作裸跑程序的启动文件BOOT.bin

    特权同学玩转Zynq连载29--[ex51] 制作裸跑程序的启动文件BOOT.bin 1 概述 对于Zynq的裸跑程序加载,比linux的SD卡启动文件制作要简单得多. 只需要在FAT32格式化后的S ...

  9. 裸跑2440启动MMC后LED全亮或者全灭问题

    在编写完成裸跑2440的MMC测试程序后烧写至开发版,竟然LED全亮,并没有闪动起来.其确定编程没有任何问题,比如只给四个LED一种状态时是可以实现的,就是没法流水灯. 网上解决这个问题的方法很少,后 ...

最新文章

  1. 激光雷达模块支持提高高速公路速度
  2. 最强干货实践教程 | YOLOv5在建筑工地中安全帽佩戴检测的应用
  3. 今日 Paper | 手部和物体重建;三维人体姿态估计;图像到图像变换等
  4. python全球购代码_理解python的unicode字符串
  5. java程序设计题目_Java程序设计习题集(含答案).doc
  6. java 获取远程文件_java获取远程文件
  7. 【P000-008】交易费计算系统,1.1版
  8. 第一批做移动开发的程序员,现在怎么样了?
  9. zabbix触发器表达式详解
  10. spring mybatis mysql 事务不起作用
  11. ssh-keygen的使用方法及配置authorized_keys两台linux机器相互认证
  12. springboot指定属性返回_Spring Boot 最最最常用的注解梳理
  13. 【SpringBoot_ANNOTATIONS】自动装配 04 Aware 注入Spring底层组件 原理
  14. Memory ordering in some architectures
  15. 虚幻4 配置打包安卓
  16. excel数据正在计算机,excel数据太多表格太卡-急!Excel数据量大,电脑卡死?
  17. [2019年国庆专题训练] dp专题训练
  18. 倾斜摄影技术发展与应用前景
  19. 前端性能优化之----静态文件客户端离线缓存_20191110
  20. android监控树莓派,树莓派定制为无线便携监控摄像头

热门文章

  1. 自考计算机专业的草根,我找到了自己的南方——《草根考研心经》传授
  2. 智能公交考勤系统管理软件设计
  3. vscode win10笔记本 蓝屏_win10 最近突然频繁蓝屏
  4. Windows系统自动切换IP批处理
  5. Java使用elasticjob实现定时任务(v2.1.5)
  6. ecmall 学习记录
  7. 毕业设计:基于SSM框架的新生报到数据可视化系统
  8. 什么样的女人才是老婆
  9. 打卡日历html源码,经典模式打卡日历_闯关模式打课时列表.html
  10. WAVE音频文件格式及其64位扩展格式的简要介绍