全国统一学习专线

9. Cortex-A9 LED汇编、C语言驱动编写

logo
来源:七品教育

2024-03-26|已帮助:27

进入 >

0.前言一般我们在购买开发板的时候,厂商会给出相应的电路图文件,我们通过搜索相应的名称就可以找到相应的外设。对于驱动工程师来说,我们只需要知道外设与SOC交互的一些数据线和信号线。

用主控制芯片控制这些外设的一般步骤:

看电路原理图,了解主控芯片和外设是如何连接的。对于驱动工程师来说,主要看外设的一些clk、数据引脚、控制引脚是如何连接的。外围设备通常连接到SOC的一个或多个控制器。

比如i2c、spi、gpio等。一些数据线、一些信号线、中断线等。根据电路连接和要求设置主控芯片,外设的设置往往通过寄存器操作实现;编写相应的代码,实现功能,不同类型的外设、

代码结构也不一样,比如按键。我们可以通过轮询或中断来读取关键信息。下面以华清前瞻fs4412开发板为例,看看裸机led程序怎么写。

SOC exynos 4412 datahseet下载地址自寻。

一、LED灯的电路图通过后面几章对一些常见外设的分析,相信大家会掌握如何查阅电路图。先看led电路图:

LED电路图

板子有四个led,是发光二极管,电流是蓝色的;发光二极管都连接有上拉电阻;三极管的基极连接到SOC的GPIO引脚;比如GPX1_0,当此引脚为高电平时,晶体管pn结导通,因此LED3两侧存在电位差。

LED3打开。如果此引脚处于低电平,pn结关闭,因此LED3两侧没有电位差,LED3关闭。以下是CPU内核访问GPIO控制器的数据路径:

AHB:高速总线APB桥:APB总线桥APB:外设总线,低速总线GPIO安装在APB总线上。从上图可以看出,cpu需要通过路径来访问GPIO的寄存器。

2.GPIO GPIO(通用I/O端口)是指通用的输入/输出端口,通俗地说就是可以通过这些端口输出高电平和低电平或者可以通过这些端口读入引脚的状态——高电平或低电平。

用户可以通过GPIO口与硬件(如UART)进行交互,控制硬件(如LED、蜂鸣器等)的工作。),并读取硬件的工作状态信号(如中断信号)。GPIO口应用广泛。

但不包括gpx0、gpx1、gpx2和gpx33.6通用输入/输出(GPIO)控制器exynos 4412 SCP包括304个多功能输入/输出端口引脚和164个存储端口引脚,共有37个端口组和两个存储端口组。

下图显示了GPIO模块图:

三、GPIO怎么操作?GPIO引脚主要通过寄存器操作。GPxCON用于选择引脚功能,GPxDAT用于读/写引脚数据;此外,GPxUP用于确定是否使用内部上拉电阻。其中x是a,B….h h j等等。

1.从寄存器的名称可以看出,gpxcon寄存器用于配置)-选择引脚功能。

LED3连接到GPX1_0,该引脚解释如下:

如上图所示,

GPX1CON的地址是0x1100C20LED3是一个输出器件,所以需要将GPX1CON[3:0]设置为0x1,但其他bite可以修改。

2.GPxDAT寄存器GPxDAT用于读/写管脚;当引脚设置为输入时,读取该寄存器可以知道对应引脚的电平状态是高还是低;当引脚设置为输出时,写入该寄存器的相应位可以使该引脚输出高电平或低电平。

GPX1DAT的地址为0x1100C24LED3,对应的输出引脚为GPX1DAT[0]。点亮时只需将此引脚设置为1,关灯时将bite0设置为0。3.GPxUP寄存器GPxUP:当一个位为1时,

对应的引脚没有内部上拉电阻;为0时,相应的引脚使用内部上拉电阻。上拉电阻的作用是当GPIO引脚处于第三状态时(即不输出高电平或低电平,而是高阻态,即相当于不连接芯片),

其电平状态由上拉电阻和下拉电阻决定。这个例子不需要设置。

四、驱动编写下面我们用汇编和C语言为LED编写驱动。

1.汇编代码如果你已经掌握了我之前讲解的汇编指令的知识点,那么这段代码就很容易理解了:globl _ startarm _ start: ldrr0,=0x11000c20 @将配置寄存器GPX1CON的地址写入R0LDRR1,[R0]@将读寄存器GPX1CON的值保存到R1BICR1,R1,#0x0000000f@清除R1的3:0位,

TARGET=gcd all:arm-none-Linux-gnueabi-gcc-O0-g-c-o $(TARGET).o美元(目标)。sarm-none-linux-gnueabi-ld$(目标)。o-Ttext0x40008000-N-o$(目标)。elfarm-none-Linux-gnueabi-objcopy-o binary-S $(目标)。elf$(目标)。binclean:rm-rf* .o* .精灵*。dis* .箱子程序功能很简单,

2.C语言实现如果要进入C语言执行环境,必须设置堆栈空间,函数调用参数和返回值都是堆栈的。开始. s

.text.global_start_start:ldrsp,=0x70000000bmainmain.c

typedefstruct{unsignedintCON;unsignedintDAT;unsignedintPUD;unsignedintDRV;}gpx1;#defineGPX1(*(volatilegpx1*)0x11000C20)voidled_init(void){GPX1.CON=GPX1.CON(~(0x0000000f))|0x00000001;}voidled_on(intn){GPX1.DAT=GPX1.DAT|0x01;}voidled_off(){GPX1.DAT=GPX1.DAT(~(0x01));}voiddelay_ms(unsignedintnum){inti,j;for(i=num;i0;i--)for(j=1000;j0;j--);}intmain(void){led_init();while(1){led_on();delay_ms(500);led_off();delay_ms(500);}while(1);return0;}map.lds

OUTPUT_FORMAT('elf32-littlearm '' El f32-little arm ')OUTPUT _ ARCH(arm)ENTRY(_ start)SECTIONS .=0x40008000从该地址开始.=ALIGN(4);文本:指定代码段{gcd.o(.正文);代码的第一个部分,

TARGET=gcdTARGETC=mainall:arm-none-eabi-gcc-O0-g-c-o $(TARGETC).o美元(目标c)进行测试.carm-none-eabi-gcc-O0-g-c-o$(目标)。o美元(目标)。sarm-none-eabi-gcc-O0-g-S-o $(TARGETC).新元(目标c)进行测试.carm-none-eabi-ld$(TARGETC).o美元(目标)。o-Tmap.lds-o$(目标)。elfarm-none-eabi-objcopy-o binary-S $(目标)。elf$(目标)。binclean:rm-rf* .o* .精灵*。dis* .箱子执行制造命令,

typedefstruct { unsignedintCONunsignedintDATunsignedintpudunsignedintDRVgpx1# define px1(*(volatilegpx1 *)0x 11000 C20)Wie oben gez eigt:

(volatile gpx1 *)0x11000C20):将常量0x11000C20转换为struct gpx1类型的指针(* (volatile gpx1 *)0x11000C20):找到指针对应的内存驱动。

3.该测试采用UBOOT附带的命令loadb,下载二进制文件(bin)通过串口以波特率发送到SDRAM中的一个地址,然后用go命令从一个地址开始执行程序。

该命令使用kermit协议,嵌入式系统通常使用该协议与pc传输文件。操作步骤如下:

进入uboot命令界面执行loadb 40008000[地址与Makefile和map.lds文件中的地址一致],选择菜单transfer-send Kermit,然后选择我们编译好的gcd.bin文件,点击确定。

可以看到LED闪烁的现象。

5.注意,这个测试方法要求引导装载程序选择uboot,并且要求串行工具支持Kermit协议。您使用的是secure rt 7 . 3 . 3版本[其他较低版本可能不支持此协议]。

软件下载安装的方法【安装方法有点复杂】可以用我朋友的后台回复【SecureCRT】添加。

Security version

以上是七品教育整理的9. Cortex-A9 LED汇编、C语言驱动编写全部内容。