arm 裸板驱动入门-LED

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

1)系统的启动

PC-->BIOS-->引导操作系统--->识别分区 (c盘、d盘等)--->启动应用程序。

嵌入式Linux--->bootloader--->引导linux操作系统--->挂载根文件系统----->启动应用。

2)怎么生成一个可执行程序?

得到一个可执行程序的步骤无非是这么几步: 

1> 编辑文件
2> 编译/链接
3> 烧写测试

  在Windows下有很多的集成开发环境,如ADS.TAR.KEIL等,点点鼠标就帮我们生成了。

  在Linux下也有一些GNU工具链,如gcc之类的,要我们用命令行来运行生成。最后的效果都是一样的。

3)应用程序与裸板程序的差别

以前一直没关心这个main()是怎么执行起来的,只知道一执行就从main()开始执行。然而,这个main函数也只是一个普通的函数而以,main它又被谁调用的呢? 
它是被启动代码调用,裸板没有操作系统,如果我们要在裸板上跑程序的话,这个启动代码也要由我们自己来写。

 启动代码要完成什么功能呢?

1>硬件相关的初始化。
2>调用C函数。

4)裸板点LED

一、写启动代码

1)硬件初始化

 a、设置CPU

    把外设的地址告诉处理器。

 b、关看门狗

    一般是3秒倒数,3秒一到就重启了(是为了防止死机)。

看一下,以下这是个完全汇编的代码例子:

.globl _start
_start:

/* 硬件相关的设置 */
    /* Peri port setup */
    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)
    
/* 关看门狗 */
/* 往WTCON(0x7E004000)写0 */
	ldr r0, =0x7E004000
	mov r1, #0
	str r1, [r0]
/* 设置GPMCON让GPM3作为输出引脚 */
	ldr r1, =0x7F008820
	mov r0, #0x1000
	str r0, [r1]

/* 设置GPMDAT让GPM3输出0 */
	ldr r1, =0x7F008824
	mov r0, #0
	str r0, [r1]
halt:
	b halt	
硬件代码实现点灯,汇编实现,_start开始,硬件相关设置---关看门狗---设置GPM3为输出,让它输出0。还要设置cpu,设定外设起始地址,(所谓外设地址就是gpio,uart等寄存器地址,从0x70000000~0x7fffffff)。
1》mcr p15,0,r0,c15,c2,4    //协处理指令,告诉CPU 0x70000000~0x7fffffff是外设的地址。0x70000000是基地址,#0x13表示多大,从ARM11的手册          在arm1176jzfs.pdf中搜索 CP15可以找到

搜索这个 Peripheral Port Memory Remap Register,找到0x13 对应256M.
2》 ldr r0, =0x70000000    //‘=’表明这是条伪汇编指令,最终会被真正的汇编指令代替,用反汇编可以看到最终被mov指令代替。有些汇编指令内容比较复杂,arm一条处理不过来,就会把内容先放在内存哪一个地方,再用ldr从那里读出来。
代码写出来了,怎么编译出来放到板子上运行呢?
进行linux环境,执行#arm-linux-gcc -o start.o start.S -c              -c是只编译不链接,把start.S 编译成 start.o。
#arm-linux-ld -Ttext 0 -o led.elf start.o                        -ld是链接,-Ttext 0 是代码段从0开始
#arm-linux-objcopy -O binary led.elf led.bin             再把.elf 格式的转换成.bin文件

   ELF:可执行链接格式。其实就是Unix下的执行文件和动态库(*.so)和目标文件(*.o)文件格式。
不光是可执行文件(Windows的.exe和Linux下的ELF可执行文件)按照可执行文件格式存储。动态链接库(DLL,Dynamic Linking Library)(Windows的.dll和Linux的.so)及静态链接库(Static Linking Library)(Windows的.lib和Linux的.a)文件都按照可执行文件格式存储。

上拉电阻:接到VCC。

下拉电阻:接到地。

2)调用C函数

上面一个程序是全汇编的,没有用到C的程序,汇编比较麻烦,下面我们来看看用C怎么写。  

.globl _start
_start:

/*设置CPU,把外设地址告诉CPU*/
    /* Peri port setup */
    ldr r0, =0x70000000
    orr r0, r0, #0x13
    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)
    
/*关看门狗*/
	ldr r0, =0x7E004000
	mov r1, #0
	str r1, [r0]

	/*设置栈*/
	ldr sp, =8*1024
	bl ledBright
halt:
	b halt	
调用c函数前还要设置栈,因为子函数中的变量,参数都是存在栈中的。设置栈很简单,只要让这个sp寄存器指向某块不用的内存就可以了。

我们还要了解一个6410的内部结构,我们现在都是设置的从Nand flash启动。这样一上电,Nand flash前8k的内容就会原原本本的拷贝到内存中。我们的程序很小,暂时就把sp指向8k之上。

启动后就会调用C函数,一般是名为main,但是这个叫什么是没关系的,程序中我们就命名为ledBright.

bl长跳转,后把下条指令的地址存到lr寄存器中。恢复是用ldr pc,lr就可跳回来。

二、写c函数

1)ledBright中实现点灯:

void delay()
{
	volatile int i = 0x10000;
	while (i--);
}
int ledBright()
{
	int i = 0;
	volatile unsigned long *gpmcon = (volatile unsigned long *)0x7F008820;
	volatile unsigned long *gpmdat = (volatile unsigned long *)0x7F008824;
	
	/* gpm0,1,2,3设为输出引脚 */
	*gpmcon = 0x1111;
	while (1)
	{
		*gpmdat = i;
		i++;
		if (i == 16)	i = 0;
		delay();
	}
	return 0;
}
pc:r15    lr:r14       ip: r12       fp:r 11
2)汇编与C语言之间怎么传递参数

它们之间有一个规则,称为ATPCS规则。
第1个参数存在r0,第2、3、4个参数分别存在r1 r2 r3中。如果还有更多参数的话,就存在栈里面。如:
int ledBright(int start, int end, int a, int b, int c, int d)         start存在r0,end a b 分别存在r1 r2 r3中,c d存在栈中。



ARM程序的开发和编译(以点亮LED灯为例) 制作好交叉编译工具链后,怎么确定是否有效呢,当然是编译一个程序烧写到上跑一下了。这里我们以点亮LED灯为例描述如何使用我们制作的交叉编译工具链编译程序。 首先,需要了解下Nor flash,Nand flash,片内内存,片外内存,地址空间这几个概念。其中,Nor flash是CPU可以直接通过硬件信号读取的,不需要配置,但是Norflash的写操作是需要配置和实现驱动的。片内内存不需要配 阅读详情

相关推荐

开发学习Day7-第一个ARM程序及引申

第008课:第一个ARM程序及引申 今天我们来写第一个ARM程序-点亮LED 我们怎样去点亮一个LED呢? 共分为三步 。 看原理图,确定控制LED的引脚; 看主芯片的芯片手册,确定如何设置控制这个引脚; 写具体的程序来实现; 第001节:硬件知识-LED原理图 点亮LED需要通电源,同时为了保护LED,加个电阻减小电流。 控制LED灯的亮灭,可以手动开关LED,但在电子系统...

Leonard's Blog 1972

LPC11C14(M0)全套驱动下载

非常好强大的驱动,就算没有原理图和硬件图,看代码收获也不小啊

嵌入式-ARM(开发)-2-LED驱动开发

一、LED驱动 1.比如我们要控制一个LED的亮灭,根据这个电路图,我们可以知道,让LED1亮或者灭实则就是控制导线GPIOC12上出现低/高电平。 2.再找到GPIOC12和CPU相连的管脚,就可以进一步理解为,控制LED1亮或者灭,实则就是控制CPU W15管脚输出低/高电平。 3.在数据手册中,我们得知,W15管脚如果想控制GPIOC12管脚,需要切换为功能1才可以。 4.如何切换功能,就需要查看数据表中的GPIOxALTFUN0这个表(x代表各种GPIO类型,比.

m0_65486182的博客 1450

ARM驱动开发说明书.pdf

ARM驱动开发说明书.pdf

驱动与Linux设备驱动的区别

驱动一般针对没有操作系统支持的层面,不用考虑操作系统对它的调用。 Linux驱动是在驱动基础上,按照一定的规范来实现, 虽然实现的都是同一个东西,不过你发现在 Linux驱动 搀杂 了许多维护信息。 总之,Linux设备驱动就是比驱动多了一些框架。 机底层驱动设计方法: 所谓机在这里主要是指系统软件平台没有用到操作系统。在基于ARM处理器平台的软件设计中,如

qianxuedegushi的博客 2892

I2C协议->机程序->adapter驱动程序分析

开发:mini2440 内核  :linux2.6.32.2 参考  :韦东山毕业班I2C视频教程 1、i2c协议简要分析     i2c中线是一种由 PHILIPS 公司开发的串行总线,用于连接微控制器及其外围设备,它具有以下特点。         1、只有两条总线线路:一条串行数据线SDA,一条串行是中线SCL。         2、每个连接到总线的器件都可以使用软件根据

漫不经心 7480

STM32F10x_硬件I2C读写EEPROM(标准外设库版本)

推荐 分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!http://www.captainbed.net/strongerhuang 我的网站:https://www.strongerhuang.com 我的知乎:https://www.zhihu.com/people/strongerHuang.com Ⅰ、写在前面...

strongerHuang 2万+

ARM11 Peripheral port setup

今天在UBOOT代码前面加了个点灯程序 但是却点不起来,很诧异. 后来发现原来要在这部分代码之后才能点灯     ldr r0, =CONFIG_PERIPORT_BASE orr r0, r0, #CONFIG_PERIPORT_SIZE mcr p15,0,r0,c15,c2,4  在网上查了查,就是下面这个博客 http://blog.csdn.net/a

ying_seven的专栏 1543

ARM:嵌入式系统之LED驱动

GPIO编程之LED驱动 提示:本次做的实验是关于LED驱动实验。 文章目录GPIO编程之LED驱动前言一、GPIO是什么?二、实验内容1.实验目的2.实验题目3.实验代码3.1 第一题3.2 第二题3.3 第三题总结 前言 本次实验是关于LED驱动的相关内容。如果对您有帮助,可以点点关注,期待下一次的相会。 提示:以下是本篇文章正文内容,下面案例可供参考。 一、GPIO是什么? GPIO,英文全称为Genneral-Purpose IO Ports,也就是通用IO口。 二、实验内

Azure的博客 812

基于ARM的模块方式驱动程序

基于ARM的模块方式驱动程序 作者:毛茏玮 / Saint 掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a 微博:https://weibo.com/5458277467/profile?topnav=1&wvr=6&is_all=1 GitHub:github.com/saint-000 CSDN: https://me.c...

一个会写代码的烤鸭 1万+

uart驱动

ARM11 s3c 6410 uart驱动

pcDuino程序-led

最近调驱动时,调试led时遇到了点问题,于是回过头来再写个led程序。在我写的pcDuino第一个程序uart的基础上,再写个led程序还是很轻松的。很多人觉得没有必要写什么pcDuino程序,觉得没啥意义。我觉得可以用来熟悉硬件,特别是想做底层驱动开发,以及系统移植,熟悉底层硬件还是有用的。其实做底层驱动开发,也是跟硬件打交道,硬件相关的操作和程序是一样的。下面介绍怎样在pc

u010216127的专栏 3470

ARM驱动开发之LED驱动

void Port_Init(void); void Beepon(void); void Beepoff(void); void Led_Display(int data); void LedBeepTest(void); void Port_Init(void) { //LED rGPKCON0 = (rGPKCON0 & ~(0xffffU<<16))|(0x1111U<<16

damlee的专栏 871

基于Linux_ARM驱动烧写及连接、挂载详细过程(附带驱动程序)

这里为似懂非懂的朋友简单叙述该文章的具体操作由来,我们的主要目的是将写好的驱动程序烧进开发中,看到我们想要的现象。第一个,我们需要让开发和Linux平台建立联系,这样我们才能让俩者进行更好的交互,这个中间件网上有许多,这里我以putty为例连接展示。第二个,在Linux上交叉编译好的可执行文件需要上传到中间件上运行,这里需要使用nfs服务挂载到开发上。第三个,在该ARM上,厂商已为客户写入部分内核驱动模块。

Bit_Dong的博客 3530

从零到第一个程序的过程

第一次真正意义上的接触嵌入式开发,并没有之前接触软件开发那么的顺利,过程复杂,涉及的知识广是嵌入式门槛高的部分原因。一开始接触,我不断地在找概念,现在特在此将我的一些经验记录下来,以便不时之需,也提供给各位参考。 说明:我是用的开发ARM9 的S3C2440 ,系统环境是 xp + linux 。   1.      安装ADS,我的环境是在xp下,我安装的是ADS1.2,安装过程可以

u014699958的专栏 2516

ARM11与Windows CE环境下的LED驱动开发实战

本文还有配套的精品资源,点击获取 简介:ARM11架构应用于嵌入式系统中,提供高性能和低功耗特点。Windows CE操作系统支持ARM架构并提供丰富的API和开发工具。LED驱动程序是硬件抽象层的一部分,用于管理和控制LED硬件。该驱动程序通过Windows CE的DDK进行开发,并基于KMDF或UMDF框架。驱动程序的主要任务包括初始化硬件、设置状态、控制亮度及处理中断...

weixin_42097508的博客 2699

韦东山Linux视频第1期 ARM驱动 学习笔记索引

ARM

ymangu的专栏 1796

嵌入式ARM程序——存储管理器驱动

本博文是根据百问网韦东山老师的嵌入式视频教程,基于jz2440进行嵌入式开发学习所记录的学习体会,如有雷同纯属巧合。存储管理器ARM的存储管理器,其实是一个存储控制器的作用。通过前面的学习我们可以了解到,在2440开发上,单一上电开机,开发会自动地从flash中拷贝4K字节的数据(无论有没有)到片内内存SRAM中然后程序指针PC会从0地址开始执行指令。所以,我们如果在单上想运行程序,那么

JewelCCL的博客 1868
上一篇: 编写通用Makefile
下一篇: 系统时钟 裸板
ymangu
博客等级 码龄16年 202粉丝 249原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值