设为首页 加入收藏

TOP

ARM+Linux驱动----点亮开发板的LED(一)
2014-11-24 07:54:03 来源: 作者: 【 】 浏览:0
Tags:ARM Linux 驱动 ----点亮 开发 LED

使用FS2440开发板2.6.4内核


1)关于fs_operations的问题
fs_operations数据结构是有文件系统(虚拟文件系统VFS)提供的,其主要作用是向上(应用层)提供统一的系统调用接口,比如open(),read(),write(),ioctl()等文件(Linux把所有的设备也当作文件)操作,向下屏蔽各种不同平台的差异。fs_operations内部是一个指针实现,链接了向上的接口和向下的具体实现。设备驱动的层次在文件系统之下,就是这个道理。因为设备驱动文件包含了对与底层硬件具体实现,虚拟文件系统通过fs_operation与之链接。注意一点:字符设备是没有对应的文件系统的,所以字字符设备的fs_operations需要在驱动文件当中提供。


2)关于主设备号和次设备号
linux 2.6.4设备通过一个dev_t来定义自身的设备号。其实也就是一个unsigned int 类型的数据。在这个32位的数据里面,前12位用于保存主设备号,后10位用于保存次设备号。所有功能相同且使用同一个驱动程序的设备有相同的主设备号,然后需要用次设备好去具体区分。理论上,一个主设备可以带有1024个次设备。


4)对硬件的操作: 可以使用内核提供的接口 s3c2410_gpio_setpin(管脚号,管脚状态代号)设置管脚状态 (设置GPnDAT) , s3c2410_gpio_cfgpin(管脚号,管脚功能代号) 设置管脚功能(相当于设置GPnCON)


源代码:


include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


#include"linux/module.h"
#include"linux/types.h"
#include"linux/fs.h"
#include"linux/errno.h"
#include"linux/mm.h"
#include"linux/sched.h"
#include"linux/init.h"
#include"linux/cdev.h"
#include"asm/io.h"
#include"asm/uaccess.h"
#include"asm/arch-s3c2410/regs-gpio.h" // S3C2410_GPF4 and S3C2410_GPF4_OUTP
#include "asm/arch-s3c2410/hardware.h"
#define DEVICE_NAME "leds"



#define LIGHT_MAJOR 0 //i want a device number dynamatically



struct light_dev{ //Make the device an object , now it declar a device class and you can think it making an abstract
struct cdev cdev; //Declar a char device abstract
unsigned char value; //usr can read and write this car
};


struct light_dev *light_devp; //now programe make a half abstract for the divice,and in light_init(),when kmalloc() allocate a space,it can think manke a real_abstraction
dev_t light_major = LIGHT_MAJOR;



void light_GPIO_init(void){
s3c2410_gpio_cfgpin( S3C2410_GPF4 , S3C2410_GPF4_OUTP );
s3c2410_gpio_cfgpin( S3C2410_GPF5 , S3C2410_GPF5_OUTP );
s3c2410_gpio_cfgpin( S3C2410_GPF6 , S3C2410_GPF6_OUTP );
s3c2410_gpio_cfgpin( S3C2410_GPF7 , S3C2410_GPF7_OUTP );
}



void light_on(void){
s3c2410_gpio_setpin(S3C2410_GPF4 , 0);
s3c2410_gpio_setpin(S3C2410_GPF5 , 0);
s3c2410_gpio_setpin(S3C2410_GPF6 , 0);
s3c2410_gpio_setpin(S3C2410_GPF7 , 0);
}


void light_off(void){
s3c2410_gpio_setpin(S3C2410_GPF4 , 1);
s3c2410_gpio_setpin(S3C2410_GPF5 , 1);
s3c2410_gpio_setpin(S3C2410_GPF6 , 1);
s3c2410_gpio_setpin(S3C2410_GPF7 , 1);
}



int light_open(struct inode * inode , struct file * filp)
{
//when device driver open.fill the device struct
struct light_dev * dev;
dev = container_of(inode->i_cdev,struct light_dev,cdev ); //contariner_of is a macros
//make the device struct be a private in device file
filp -> private_data = dev; //make the releationship between the file and device in Linux,because Linux regard the device as a file!~


return 0;
}


ssize_t light_release(struct inode * inode, struct file * filp )
{
return 0;
}


ssize_t light_read(struct file * filp , char __user * buff , size_t count , loff_t * f_pos)
{
struct light_dev * dev = filp->private_data;


if(copy_to_user(buff , &(dev->value) , 1))
{
return - EFAULT;
}
else
{
return 1;
}


}



ssize_t light_write(struct file * filp , const char __user * buff , size_t count , loff_t * f_pos)
{
struct light_dev *dev = filp -> private_data;


if(copy_from_user(&(dev->value) , buff ,1) )
{
return -EFAULT;
}
else
{
if(dev->value)
{
light_on();
}
else{
light_off();
}
return 0;
}



}



static int light_ioctl(struct inode * inode ,struct file * filp , unsigned int _

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇一个让桌面下雪的ruby 小程序 snow 下一篇Linux Kernel 2.6.37.2内核编译实..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)
·Redis配置中`require (2025-12-26 03:18:58)
·Asus Armoury Crate (2025-12-26 02:52:33)
·WindowsFX (LinuxFX) (2025-12-26 02:52:30)