驱动学习1
KERNELRELEASE = $(shell cat include/config/kernel.release 2>
int num = MINOR(inode->
if(num >
filp->
实现*/
int mem_release(struct inode *inode, struct file *flip)
{
return 0;
}
/*read函数的实现*/
static ssize_t mem_read(struct file *filp,char __user *buf, size_t size,loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
/*获得file结构体上的指针*/
struct mem_dev *dev = filp->private_data;
/*参数的检查*/
if(p >= MEMDEV_SIZE)
return 0;
if(count > MEMDEV_SIZE - p)
count = MEMDEV_SIZE - p;
/*从内核读数据到用户空间*/
if(copy_to_user(buf,(void *)(dev->data + p),count))
{
/*出错误*/
ret = -EFAULT;
}
else
{
/*移动当前文件光标的位置*/
*ppos += count;
ret = count;
printk(KERN_INFO "read %d bytes(s) from %d",count,p);
}
return ret;
}
/*write函数的实现*/
static ssize_t mem_write(struct file *filp,const char __user *buf,size_t size,loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
/*获得设备结构体的指针*/
struct mem_dev *dev = filp->private_data;
/*检查参数的长度*/
if(p >= MEMDEV_SIZE)
return 0;
if(count > MEMDEV_SIZE - p)
count = MEMDEV_SIZE - p;
if(copy_from_user(dev->data + p,buf,count))
ret = -EFAULT;
else
{
/*改变文件位置*/
*ppos += count;
ret = count;
printk(KERN_INFO "writted %d bytes(s) from %d",count,p);
}
return ret;
}
/*lseek的实现*/
static loff_t mem_llseek(struct file *filp,loff_t offset, int whence)
{
loff_t newpos;
switch(whence)
{
case 0:/*SEEK_SET*/
newpos = offset;
break;
case 1:/*SEEK_CUR*/
newpos = filp->f_pos + offset;
break;
case 2:/*SEEK_END*/
newpos = MEMDEV_SIZE - 1 + offset;
break;
default:
return -EINVAL;
}
filp->f_pos = newpos;
return newpos;
}
/*作者以及权限的声明*/
MODULE_AUTHOR("GongPing");
MODULE_LICENSE("GPL");
/*通过宏module_init和module_exit实现模块添加*/
module_init(memdev_init);
module_exit(memdev_exit);
第三个是Makefile:
ifneq ($(KERNELRELEASE),)
obj-m := memdev.o
else
#KDIR :=/usr/src/kernels/2.6.35.14-96.fc14.i686
#KDIR :=/lib/modules/2.6.35.14-96.fc14.i686/build
#KDIR ?=/opt/LinuxKernel/linux-2.6.38.1
KDIR :=/opt/LinuxKernel/linux-2.6.38.1
PWD :=$(shell pwd)
default:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
第4个是应用程序:
#include #include #include int main() { FILE *fp0 = NULL; char Buf[4096]; /*复制数据到buf中*/ strcpy(Buf,"Mem is char devices!"); printf("Buf: %s",Buf); /*打开设备文件*/ fp0 = fopen("/dev/memdev0","rw"); /*错误处理*/ if(fp0 == NULL) { printf("Open Memdev0 Error!"); return -1; } /*写数据到设备中*/ //fread(Buf,sizeof(Buf),1,fp0); fwrite(Buf,sizeof(Buf),1,fp0); /*定位*/ fseek(fp0,0,SEEK_SET); /*复制数据到Buf*/ strcpy(Buf,"Buf is NULL!"); /*打印*/ printf("Buf: %s",Buf); /*读数据*/ fread(Buf,sizeof(Buf),1,fp0); printf("BUF: %s",Buf); fclose(fp0); return 0; } 源码是别人的,我只是做了一下注释,然后做了适当的修改,驱动程序与应用程序以及硬件代码存在较大的差别,以后要多写,多理解,多总结。
驱动学 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)