嵌入式驱动学习之GPIO驱动

发布者:创意火花最新更新时间:2021-07-22 来源: eefocus关键字:嵌入式驱动  GPIO驱动  s3c2440 手机看文章 扫描二维码
随时随地手机看文章

开发环境

主机开发环境:ubuntu12.04

BootLoader:u-boot-1.1.6

kernel:linux-2.6.30.4

CPU:s3c2440

开发板:TQ2440


开发步骤

1、硬件分析

在天嵌科技提供的开发板中 4 个 LED 灯(TQ2440)分别使用了 S3C2440芯片的:GPB5、GPB6、GPB7 和 GPB8,下面列出来对应的原理图:

在这里插入图片描述

根据上图可以知道,当 CPU 的 GPB5 到 8 是低电平时,LED 灯亮;当为高电平时 LED 灯灭。只需要在驱动中实现对 GPB 口电平的控制就可以实现对灯进行开关操作。


2、编写LED驱动

以下为驱动源码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#define DEVICE_NAME "le2440-leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */

#define LED_MAJOR 231         /* 主设备号 */


/* 应用程序执行 ioctl(fd, cmd, arg)时的第 2 个参数 */

#define IOCTL_LED_ON 1

#define IOCTL_LED_OFF 0


/* 用来指定 LED 所用的 GPIO 引脚 */

static unsigned long led_table[] = {

S3C2410_GPB5,

S3C2410_GPB6,

S3C2410_GPB7,

S3C2410_GPB8,

};


/* 用来指定 GPIO 引脚的功能:输出 */

static unsigned int led_cfg_table[] = {

S3C2410_GPB5_OUTP,

S3C2410_GPB6_OUTP,

S3C2410_GPB7_OUTP,

S3C2410_GPB8_OUTP,

};


/* 应用程序对设备文件/dev/le2440-leds 执行 open(...)时,

* 就会调用 le2440_leds_open 函数

*/

static int le2440_leds_open(struct inode *inode, struct file *file)

{

 int i;

 for (i = 0; i < 4; i++)

 {

// 设置 GPIO 引脚的功能:本驱动中 LED 所涉及的 GPIO 引脚设为输出功能

 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

 }

return 0;

}


/* 应用程序对设备文件/dev/le2440-leds 执行 ioclt(...)时,

* 就会调用 le2440_leds_ioctl 函数

*/

static int le2440_leds_ioctl(struct inode *inode, struct file *file,

       unsigned int cmd, unsigned long arg)

{

if (arg > 4) {

return -EINVAL;

}

switch (cmd) {

case IOCTL_LED_ON:

     // 设置指定引脚的输出电平为 0

s3c2410_gpio_setpin(led_table[arg], 0);

return 0;

case IOCTL_LED_OFF:

     // 设置指定引脚的输出电平为 1

s3c2410_gpio_setpin(led_table[arg], 1);

return 0;

default:

return -EINVAL;

}

}


/* 这个结构是字符设备驱动程序的核心

* 当应用程序操作设备文件时所调用的 open、read、write 等函数,

* 最终会调用这个结构中指定的对应函数

*/

static struct file_operations le2440_leds_fops = {

.owner = THIS_MODULE,                 /* 这是一个宏,推向编译模块时自动创建的__this_module 变量 */

.open = le2440_leds_open,

.ioctl = le2440_leds_ioctl,

};


static char __initdata banner[] ="TQ2440 le2240-ledsn";

static struct class *led_class;


/*

* 执行“insmod le2440_leds.ko”命令时就会调用这个函数

*/

static int __init le2440_leds_init(void)

{

int ret;

printk(banner);

/* 注册字符设备驱动程序

* 参数为主设备号、设备名字、file_operations 结构;

* 这样,主设备号就和具体的 file_operations 结构联系起来了,

* 操作主设备为 LED_MAJOR 的设备文件时,就会调用 le2440_leds_fops 中的相关成员函数

* LED_MAJOR 可以设为 0,表示由内核自动分配主设备号

*/

ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &le2440_leds_fops);

if (ret < 0) {

printk(DEVICE_NAME " can't register major numbern");

return ret;

}

//注册一个类,使 mdev 可以在"/dev/"目录下面建立设备节点

led_class = class_create(THIS_MODULE, DEVICE_NAME);

if (IS_ERR(led_class)) {

printk("Err: failed in le2440-leds class. n");

return -1;

}

//创建一个设备节点,节点名为 DEVICE_NAME

device_create(led_class, NULL, MKDEV(LED_MAJOR, 0), NULL,

    DEVICE_NAME);

printk(DEVICE_NAME " initializedn");

return 0;

}


/*

* 执行”rmmod le2440_leds.ko”命令时就会调用这个函数

*/

static void __exit le2440_leds_exit(void)

{

/* 卸载驱动程序 */

unregister_chrdev(LED_MAJOR, DEVICE_NAME);

device_destroy(led_class, MKDEV(LED_MAJOR, 0)); //删掉设备节点

class_destroy(led_class); //注销类

}


/* 这两行指定驱动程序的初始化函数和卸载函数 */

module_init(le2440_leds_init);

module_exit(le2440_leds_exit);


/* 描述驱动程序的一些信息,不是必须的 */

MODULE_DESCRIPTION("TQ2440 LED Driver"); // 一些描述信息

MODULE_LICENSE("GPL");                  // 遵循的协议


Makefile如下:


#Makefile 

ifeq ($(KERNELRELEASE),) 

 

KERNELDIR ?= /home/linux/sky/ker/linux-2.6.30.4/ 

#KERNELDIR ?= /lib/modules/$(shell uname -r)/build 

PWD := $(shell pwd) 

 

modules: 

    $(MAKE) -C $(KERNELDIR) M=$(PWD)  

 

modules_install: 

    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 

 

clean: 

    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules* 

 

.PHONY: modules modules_install clean 


else

obj-m := leds.o 

       

endif 


将其编译成.ko文件拷贝到NFS文件系统即可。
编译过程中遇到一些问题,经过查找资料,解决方法如下:
在这里插入图片描述

3、编写app控制LED灯

#include

#include

#include

#include


int main(int argc, char **argv)

{

int on;

int led_no;

int fd;

if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||

    on < 0 || on > 1 || led_no < 1 || led_no > 4) {

fprintf(stderr, "Usage: leds which-led  0|1n");

exit(1);

}

fd = open("/dev/le2440-leds", 0);

if (fd < 0) {

perror("open device leds");

exit(1);

}

ioctl(fd, on, (led_no-1));

close(fd);

return 0;

}


Makefile如下:


CROSS=arm-linux-

all: leds

leds:leds.c

$(CROSS)gcc -o leds leds.c

$(CROSS)strip leds

clean:

@rm -vf leds *.o *~


编译成可执行文件拷贝到NFS文件系统即可


4、实验现象

加载.ko文件,执行app,便可以在开发板上控制任意一个LED灯的亮灭

在这里插入图片描述

关键字:嵌入式驱动  GPIO驱动  s3c2440 引用地址:嵌入式驱动学习之GPIO驱动

上一篇:嵌入式驱动学习之按键驱动
下一篇:嵌入式驱动移植之IIC总线驱动移植

推荐阅读最新更新时间:2024-11-13 09:13

基于S3C2440的数控同步现场总线与CAN总线网关的设计
引言 现场总线控制系统在过去集散控制系统的基础上顺应用户对控制系统提出的开放性的要求而诞生。开放的具有互操作性的现场总线将网络现场的控制器及仪表设备互联,构成现场总线控制系统。由于工业控制领域现场总线技术的竞争,形成了当今众多总线标准并存的局面。这一局面限制了用户对总线产品的选择,同时也约束了总线技术的发展,这也使得各现场总线之间的互联和互操作成为当务之急。 开放式数控系统在结构上具有互换性、伸缩性、可操作性和可移植性,其能够方便灵活的进行裁剪、扩展和升级。数控系统中的现场总线是数控装置、执行装置和传感器件之间通信的系统。数控系统的开放性势必对现场总线开放性提出一定的要求。 数控同步现场总线(Numerical
[单片机]
基于<font color='red'>S3C2440</font>的数控同步现场总线与CAN总线网关的设计
S3C2440学习笔记五(2440slib.s源程序的分析)
以下程序是什么意思: 为啥这个文件是一堆的汇编代码,因为这里面涉及到了底层驱动,这里既是CPU的核心控制。涉及到了直接操作的寄存器和高速缓存,实际上和51的CPU是一回事,就是51可以干一件事,他就要干几十件事,没有强悍的架构和强大的寄存器和缓存团队,他就没法强悍!就跑400M吧,他为了效率加了cp15这个比较高速的协处理器,这个cp15的本质是数据处理中心。只有早期的PC机和现行的ARM还有这个东西,现在的PC机跑得非常快了,不需要CP15这类东西帮忙了。 补充一点是,CP15可以理解为MMU,它主要的工作是地址映射,也就是给CPU提供地址。SDRAM一般为32M或64M,但是对于32位的CPU,可以管理4G的空间。那么就把这个4
[单片机]
S3c2440ARM异常与中断体系详解6---按键中断程序示例概述与初始
在前面的视频里我们举了一个例子,母亲看书被声音打断,远处的声音来源有多种多样,声音传入耳朵,再由耳朵传入大脑,整个过程涉及声音来源耳朵大脑,为了确保这个母亲看书的过程能够被声音打断,我们必须保证声音来源可以发出声音,耳朵没有聋,脑袋没有傻。 中断处理流程 1、中断初始化: ①我们需要设置中断源,让它能够发出中断 ②设置中断控制器,让它能发出中断给CPU ③设置CPU,CPSR有I位,是总开关 2、处理完之后清理中断 3、处理时,要分辨中断源,对于不同的中断源要执行不同的处理函数 下面开始写代码 打开start.S 先做初始化工作,先做第 3 设置CPU,CPSR有I位,是总开关 我们需要把CPSR寄存器 b
[单片机]
S3c2440ARM异常与中断体系详解6---按键中断程序示例概述与初始
S3C2440-裸机篇-04 | ARM-THUMB子程序调用规则ATPCS
在GPIO的实验中,我们首先编写汇编程序操作寄存器点亮LED,奈何汇编语言可读性和可移植性太差,所以编写启动代码,设置栈顶指针SP,然后调用C语言中的main函数,转入C语言的世界,由C语言访问控制寄存器,点亮LED,程序的可读性和可移植性大大提高,那么,我们可曾想过,在汇编语言中是如何来调用C语言入口函数main呢? 其实,对于ARM处理器,在ARM指令集汇编程序和THUMB指令集汇编程序中制定了子程序调用的规则 —— ATPCS规则,这个规则包括: 寄存器使用规则 数据栈使用规则 参数传递规则 1.寄存器使用规则 ARM处理器中有R0-R15这16个寄存器,每个寄存器都由ATPCS规则规定了用途,并根据其用途规定
[单片机]
S3C2440-裸机篇-04 | ARM-THUMB子程序调用规则ATPCS
s3c2440为例讲解arm芯片的启动过程
arm 嵌入式芯片的启动过程对于嵌入式菜鸟来说其实是很复杂的,很多人都是一知半解,存在很多误区。在笔者看来,要想真正了解这一启动过程必须要首先了解存储器的区别与联系,参考文章:各种主流半导体存储器的区别与联系。还需要了解程序是如何编译链接和执行的。 本文将以s3c2440为例详细讲述 arm 芯片的启动过程。s3c2440支持两种启动模式:NAND FLASH 启动和非 NAND FLASH 启动(一般是NOR FLASH 启动,并且可以配置数据宽度),通过 OM1、OM0 两个管脚来控制。 NAND FLASH启动过程 当 OM1、OM0 两个管脚都为低电平时,CPU 就被配置成了 NAND FLASH 启动。此时 CP
[单片机]
以<font color='red'>s3c2440</font>为例讲解arm芯片的启动过程
S3C2440 启动代码分析
启动代码是系统上电或复位以后运行的第一段代码,它的作用是在用户程序运行之前对系统硬件及软件运行环境进行必要的初始化并在最后使程序跳转到用户程序,它直接面对ARM 处理器内核及硬件控制器进行编程,所执行的操作与具体的目标系统紧密相关。 S3C2440 支持两种方式的启动:Nor Flash 启动和Nand Flash 启动。Nor Flash 和Nand Flash 都是非易失性存储器,Nor Flash 的特点是芯片内执行,程序可以直接在其中运行,而不必将程序读取到RAM 中运行。Nor Flash 虽然具有这个优点,但是它的性价比远低于Nand Flash,因而很多系统采用Nand Flash 启动。Nand Flash 的特
[单片机]
s3c2440裸机-内存控制器(五、SDRAM编程实现)
配置内存控制器-SDRAM编程配置 2440内存控制器共有13个寄存器。 BANK0--BANK5只需要设置BWSCON和BANKCONx(x为0~5)两个寄存器; BANK6、BANK7外接SDRAM时,除BWSCON和BANKCONx(x为6、7)外,还要设置REFRESH、BANKSIZE、MRSRB6、MRSRB7等4个寄存器。 下面分别说明各个寄存起的设置: 1.位宽和等待控制寄存器BWSCON(BUSWIDTH&WAITCONTROLREGISTER) 我们SDRAM的位宽为32,DW6 设置成10, 没有使用等待信号,所以WS6 =0。 bank7跟随bank6的配置, 因此BWSCON寄存器的值为:
[单片机]
<font color='red'>s3c2440</font>裸机-内存控制器(五、SDRAM编程实现)
ARM中断区别-LPC2142与S3C2440的区别
/*************************************************** *说 明 :ARM中断区别-LPC2142与S3C2440的区别 ***************************************************/ LPC 与三星ARM的区别就是三星固定了中断向量的地址,而LPC的就没有。例如三星的S3C2440 所有的中断源都有相对应的中断向量。 关于三星ARM (1)使用向量中断 ENTRY b ResetHandler ; 0x00 b HandlerUndef ; 0x04 b
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved