Linux2.6.33 自己动手写驱动
一、GPIO驱动编写和测试
1、GPIO的这点事儿
GPIO(General-Purpose IO ports),通用的IO端口。一般的微处理器芯片都提供通用的可编程IO端口,用户可以通过配置寄存器将其配置成输入、输出或者其他特殊功能模式。
通用IO端口一般都可以实现按位操作,即用户可以针对IO端口的每一位(以下简称IO位)进行操作。
GPIO端口输出的高低电平可以通过控制一组LED发光二极管来加以验证,这里,我们截取TE2440-DEV-I教学板中的四个发光二极管做实验。
应用S3C2440的GPF4-GPF7共四个IO位,各自控制一个发光二极管,分别对应D1-D4,硬件原理如图6.1所示。
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="图片_x0020_1" o:spid="_x0000_i1026" type="#_x0000_t75" o:bordertopcolor="black" o:borderleftcolor="black" o:borderbottomcolor="black" o:borderrightcolor="black" style="visibility: visible; width: 371.25pt; height: 137.25pt; mso-wrap-style: square"><font size="3"><imagedata src="file:///C:/DOCUME~1/IBM/LOCALS~1/Temp/msohtmlclip1/01/clip_image001.emz" o:title="" gain="192753f" grayscale="t" bilevel="t"></imagedata><bordertop type="single" width="4"></bordertop><borderleft type="single" width="4"></borderleft><borderbottom type="single" width="4"></borderbottom><borderright type="single" width="4"></borderright></font></shape>
图6.1 IO控制LED原理图
原理图分析:
(1) 四个发光二极管采用共阳极的连接方法,即四个发光二极管的阳极连接在一起,并连接到3.3V电源。
(2) 发光二极管的负极各自连接一个1K限流电阻,再分别连接到S3C2440的GPF4-GPF7。
思考:为什么要接一个1K的限流电阻呢?
顾名思义,串接限流电阻就是为了显示通过发光二极管的电流,从而达到减少功耗或者满足端口对最大电流的限制。
一般发光二极管的点亮电流为5mA~10mA。TE2440采用贴片发光二极管,1K限流电阻,驱动电压为3.3V,发光二极管压降为1.6V,那么发光二极管的电流大约为1.7mA。发光二极管已经能点亮了,如果希望更亮一些,可以将限流电阻减小,但是二极管的电流不能超多ARM芯片IO口的最大驱动电流。
(3) 根据电路原理可知,当GPF4-GPF7输出低电平时,由于发光二极管两端加上电压,则发光二极管点亮;当GPF4-GPF7输出高电平只,由于发光二极管两端压差为0,则发光二极管熄灭。
思考:发光二极管为什么会亮呢?
发光二极管在其两端的电压差超出其导通压降时开始工作,普通发光二极管的导通压降一般为1.6V~2.1V,同时,工作电流要满足该二极管的工作电流。满足电压和电流的要求,该二极管就可以发光了。
二极管的正负极可以用万用表的二极管档量出来,如果表上有了一点多的读数,红表笔接的发光二极管的正极,黑表笔接的就是发光二极管的负极。
(4) 我们可以通过程序控制GPF4-GPF7有规律的输出高低电平,则实现发光二极管有规律的亮灭。
2、驱动怎样编写
了解的硬件的概念以后,我们开始我们的驱动编写工作。
然后再在内核源码的“drivers/char/”目录下新建一个名为“TopElec_GPIO.c”的文件,作为我们的驱动文件。内容如下:
/*************************************
NAME:TopElec_GPIO.c
COPYRIGHT:www.top-elec.com
Ver1.00 2010/05/19
*************************************/
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <linux/gpio.h>
#define DEVICE_NAME "GPIO-Control"
#define S3C2410_GPFCON S3C2410_GPIOREG(0x50)
#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54)
#define S3C2410_GPFUP S3C2410_GPIOREG(0x58)
#define S3C2410_GPF4 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 4)
#define S3C2410_GPF5 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 5)
#define S3C2410_GPF6 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 6)
#define S3C2410_GPF7 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 7)
#define S3C2410_GPF4_OUTP (0x01 << 8)
#define S3C2410_GPF5_OUTP (0x01 << 10)
#define S3C2410_GPF6_OUTP (0x01 << 12)
#define S3C2410_GPF7_OUTP (0x01 << 14)
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_GPIO_ON 1
#define IOCTL_GPIO_OFF 0
/* 用来指定LED所用的GPIO引脚 */
static unsigned long gpio_table [] =
{
S3C2410_GPF(4),
S3C2410_GPF(5),
S3C2410_GPF(6),
S3C2410_GPF(7),
};
/* 用来指定GPIO引脚的功能:输出 */
static unsigned int gpio_cfg_table [] =
{
//由于2.6.33内核中没有定义GPIO的动作,所以我在上面自己定义了一下。
S3C2410_GPF4_OUTP,
S3C2410_GPF5_OUTP,
S3C2410_GPF6_OUTP,
S3C2410_GPF7_OUTP,
};
static int te2440_gpio_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
if (arg > 4)
{
return -EINVAL;
}
switch(cmd)
{
case IOCTL_GPIO_ON:
// 设置指定引脚的输出电平为0
s3c2410_gpio_setpin(gpio_table[arg], 0);
return 0;
case IOCTL_GPIO_OFF:
// 设置指定引脚的输出电平为1
s3c2410_gpio_setpin(gpio_table[arg], 1);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.ioctl = te2440_gpio_ioctl,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
int i;
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(gpio_table[i], gpio_cfg_table[i]);
s3c2410_gpio_setpin(gpio_table[i], 0);
}
ret = misc_register(&misc);
printk (DEVICE_NAME" initialized/n");
return ret;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.top-elec.com");
MODULE_DESCRIPTION("GPIO control for Topelec TE2440DEV_I Board");
3、让驱动到内核里混一下
在内核源码中添加对LED 灯驱动的支持,修改同目录下的Kconfig文件,添加如下内容:
config TE2440_GPIO_TEST
tristate "TE2440DEV-I Board GPIO Test(LED TEST)"
depends on ARCH_S3C2440
default y if ARCH_S3C2440
help
GPIO control for TE2440DEV-I Board.
|
同样的道理,修改同目录下的Makefile文件,修改的内容如下:
obj-$(CONFIG_TE2440_GPIO_TEST) += TopElec_GPIO.o
|
4、配置和编译内核
进入内核目录,键入make menuconfig命令,进入内核配置菜单,如下图所示:
图
Diver->chacarter device-> TE2440DEV-I Board GPIO Test 的支持,当然,你也可以选择<M>将驱动编译成模块。
好了,OK,大胆的make吧!
当然可能有错误,因为内核的版本不一致,或是编译器的问题,总之,Linux虽然玩起来和带劲,但是问题也会很多,要有越挫越勇的精神才能成为真正的高手哦!
至于,怎么把内核搞到板子上不在这里就不说了。
5、编写测试程序
/*************************************
NAME:GPIO_TEST.c
COPYRIGHT:www.top-elec.com
*************************************/
#include <stdio.h> /*定义函数要用到的头文件*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc, char **argv) /*运行时参数传递,开或关哪个LED*/
{
int on; /*定义led状态变量,1表示灯亮,2表示灯灭*/
int led_no; /*定义led变量--哪个led*/
int fd; /*定义led设备文件描述符的变量*/
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: Please enter led number and led status,For example GPIO_TEST 1 0 /n");
exit(1);
}
fd = open("/dev/GPIO-Control", 0); /*为只读打开GPIO-Control设备文件,取出文件描述符*/
if (fd < 0) {
perror("open device /dev/GPIO-Control"); /*如果打开led文件出错,拿不到文件描述符,用perror宏输出错原因及信息*/
exit(1);
}
ioctl(fd, on, (led_no-1)); /*用ioctl()函数控制LED,其中fd--是前面打开的LED文件描述符,on--是开关命令0和1,led_no--是哪个LED*/
close(fd);
return 0;
}
顺便这个Makefile文件,看起来专业点:
CROSS=arm-softfloat-linux-gnu-
all:GPIO_TEST
GPIO_TEST:GPIO_TEST.c
$(CROSS)gcc GPIO_TEST.c -o GPIO_TEST
$(CROSS)strip GPIO_TEST
clean:
@rm -vf GPIO_TEST *.o *~
|
有了上面的两个 make就可以了
最后把测试程序搞的开发板上运行一下:
bash-3.2# ./GPIO_TEST 1 1 意思是D1被点亮
很多资料来源于网络,谢谢网络的上的无私奉献大侠们!
华清远见-嵌入式领域著名讲师 O(∩_∩)O 牛牛猛
点击链接加我好友!
http://student.csdn.net/invite.php?u=111047&c=758a60d66d3a92d1
欢迎大家去我CSDN博客上踩踩
我的个人主页
分享到:
相关推荐
在基于Linux 2.6.33的SPI Flash驱动移植过程中,主要涉及到了三个关键组件:SPI主机驱动(dm644x上的SPI功能模块驱动)、SPI Flash芯片驱动(w25x80的芯片驱动)以及SPI总线驱动。 **1. SPI主机驱动(dm644x上的SPI...
总的来说,基于Linux-2.6.33内核的cs8900网卡驱动开发涉及的知识点包括:C语言编程,Linux内核驱动开发框架,CS8900A硬件特性,中断处理,网络协议栈的接口,设备模型,以及驱动程序的移植技术。通过研究这些内容,...
### Linux 2.6.33 内核移植到 S3C2410 平台详解 #### 一、前言 随着嵌入式系统的不断发展,Linux内核的移植成为了一个重要的研究方向。本文主要介绍了如何将最新的Linux 2.6.33内核移植到S3C2410平台上,包括搭建...
### S3C2410的 Linux2.6.33 内核移植与搭建交叉编译环境 #### 概述 本篇文章旨在详细介绍如何针对S3C2410平台进行Linux2.6.33内核移植,并在此基础上构建交叉编译环境的过程。整个流程分为几个关键步骤,包括环境...
### Linux2.6.33下ZC301USB摄像头使用教程 #### 一、概述 本教程旨在详细介绍如何在Linux2.6.33环境下配置与使用ZC301USB摄像头,特别是针对中芯优电的TE-2440开发板。文章分为几个部分:编译器配置、内核配置、...
linux 2.6.33源码,官方版本。
2.6.33linux虚拟网卡设备驱动
本文将深入探讨嵌入式Linux帧缓冲驱动的体系结构、关键数据结构和编写方法,并结合具体的ARM9处理器S3C2440平台上的开发实例,介绍Linux 2.6.33内核基于Platform总线的帧缓冲驱动的实现原理和开发流程。 首先,帧...
在Ubuntu 10.10环境下编译Linux内核2.6.38涉及一系列步骤,需要对操作系统、内核版本、编译工具和配置选项有深入理解。以下是详细的编译流程和注意事项: 首先,确保你的环境是Pentium 4架构的Ubuntu 10.10(内核...
虚拟网卡驱动VirtualMachineNetworkDriver是为虚拟化环境设计的一种特殊网络适配器,它使得在无需物理添加网卡的情况下,虚拟机也能实现网络通信。这个驱动程序的主要目标是提高虚拟化平台的效率,减少对硬件资源的...
2.6.33-at91.patch.gz arm linux补丁
linux 2.6.33.2源码,官方版本。
5. **设备驱动**:Linux内核通过驱动程序与硬件交互,提供了广泛的设备支持。在这一版本中,可以学习到如何编写和调试设备驱动,例如USB、PCI等总线上的设备驱动。 6. **模块化设计**:Linux内核采用模块化设计,...
关于cs8900驱动移植基于linux2.6.33 s3c2410开发板
Smarty是一个流行的PHP模板引擎,它的版本2.6.33是该软件的一个特定迭代。...这个压缩包“Smarty v2.6.33....通过研究和使用这个压缩包中的文件,开发者和学习者可以提升自己的Web开发技能,同时了解软件工具的演变历程。
- **备注**: 移除了Android代码的Linux Kernel 2.6.33版代码库。 ##### 8. Honeycomb (蜂巢) - **Android系统版本**: 3.0 - **发布时间**: 2011年2月2日 - **Linux Kernel内核版本**: 2.6.36 - **备注**: 专门针对...