링크 ux 장치 드라이버 문자 장치 드라이버
문자 장치 드라이버:
이 편 은 비교적 화가 난다.불 러 오 는 데 성 공 했 지만 데 이 터 를 읽 을 수 없습니다. 어떻게 된 일 인지 아 는 사람 이 있 으 면 메 시 지 를 남 겨 서 같이 토론 합 시다.
데이터 구조
struct scull_mem{
void *data;
struct scull_mem *next;
};
struct scull_dev{
struct cdev cdev;
unsigned long size;
struct scull_mem *data;
}*dev;
전체 드라이버 코드 는 다음 과 같 습 니 다.
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#define BUFFERSIZE 4096
ssize_t scull_read (struct file *filp,char __user* buf,size_t count,loff_t *offset);
ssize_t scull_write(struct file *filp,const char __user*buf,size_t count,loff_t *offset);
int scull_open(struct inode *inode,struct file *filp);
int scull_release(struct inode *inode,struct file *filp);
struct scull_mem{
void *data;
struct scull_mem *next;
};
struct scull_dev{
struct cdev cdev;
unsigned long size;
struct scull_mem *data;
}*dev;
dev_t scull_dev_num=0;
int major,minor;
int cdev_registered=0;
void scull_trim(void)
{
struct scull_mem *ptr,*tmp;
for(ptr=dev->data;ptr!=NULL;ptr=tmp){
tmp=ptr->next;
if(ptr->data!=NULL){
kfree(ptr->data);
}
kfree(ptr);
}
dev->data=NULL;
dev->size=0;
}
int scull_open(struct inode *inode,struct file *filp)
{
printk(KERN_ALERT "Scull is opened!
");
if((filp->f_flags&O_ACCMODE)==O_WRONLY)
scull_trim();
return 0;
}
int scull_release(struct inode *inode,struct file *filp)
{
printk(KERN_ALERT "Scull is released!
");
return 0;
}
struct scull_mem * scull_follow(int item)
{
struct scull_mem *tmp,*ptr=NULL;
int times=item;
for(tmp=dev->data;item-->=0;tmp=tmp->next){
if(tmp==NULL){
if((tmp=(struct scull_mem *)kmalloc(sizeof(struct scull_mem),GFP_KERNEL))==NULL)
return NULL;
tmp->next=NULL;
if((tmp->data=kmalloc(BUFFERSIZE,GFP_KERNEL))==NULL){
return NULL;
}
memset(tmp->data,0,BUFFERSIZE);
if(times==0){
dev->data=tmp;
times++;
}
}
ptr=tmp;
}
return ptr;
}
ssize_t scull_read (struct file *filp,char __user* buf,size_t count,loff_t *offset)
{
ssize_t retval=0;
size_t item,pos;
struct scull_mem *ptr;
item=*offset / BUFFERSIZE;
pos=*offset % BUFFERSIZE;
ptr=scull_follow(item);
if(ptr==NULL||ptr->data==NULL){
goto out;
}
if(*offset+count>dev->size)
count=dev->size-*offset;
count=count > (BUFFERSIZE-pos)? (BUFFERSIZE-pos):count;
if(copy_to_user(buf,ptr->data+pos,count)){
retval=-EFAULT;
goto out;
}
*offset+=count;
retval=count;
out:
return retval;
}
ssize_t scull_write(struct file *filp,const char __user*buf,size_t count,loff_t *offset)
{
ssize_t retval=0;
size_t item,pos;
struct scull_mem *ptr;
item=*offset / BUFFERSIZE;
pos=*offset % BUFFERSIZE;
ptr=scull_follow(item);
if(ptr==NULL||ptr->data==NULL){
goto out;
}
count=count > (BUFFERSIZE-pos)? (BUFFERSIZE-pos):count;
if(copy_from_user(ptr->data+pos,buf,count)){
retval=-EFAULT;
goto out;
}
*offset+=count;
retval=count;
dev->size+=count;
out:
return retval;
}
loff_t scull_llseek(struct file *filp,loff_t offset,int start)
{
loff_t new;
switch(start)
{
case 0:
new=offset;
break;
case 1:
new=filp->f_pos+offset;
break;
case 2:
new=dev->size+offset;
break;
default:
return -EINVAL;
}
if(new<0) return -EINVAL;
filp->f_pos=new;
return new;
}
struct file_operations scull_ops={
.owner=THIS_MODULE,
.open=scull_open,
.read=scull_read,
.write=scull_write,
.release=scull_release,
.llseek=scull_llseek,
.unlocked_ioctl=NULL,
};
void cleanup(void)
{
if(cdev_registered)
cdev_del(&dev->cdev);
if(dev!=NULL){
scull_trim();
kfree(dev);
}
if(scull_dev_num!=0)
unregister_chrdev_region(scull_dev_num,1);
}
static int __init scull_init(void)
{
int retval=0;
/*first,requset device number*/
if((retval=alloc_chrdev_region(&scull_dev_num,0,1,"scull_jakilll"))<0)
goto fail;
major=MAJOR(scull_dev_num);
minor=MINOR(scull_dev_num);
/*then alloc device structure*/
if((dev=kmalloc(sizeof(struct scull_dev),GFP_KERNEL))==NULL){
retval=-ENOMEM;
goto fail;
}
dev->size=0;
dev->data=NULL;
/*finally,register cdev*/
cdev_init(&dev->cdev,&scull_ops);
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&scull_ops;
if((retval=cdev_add(&dev->cdev,scull_dev_num,1))<0)
goto fail;
cdev_registered=1;
printk(KERN_ALERT "Scull inited ok!
");
return retval;
fail:
cleanup();
return retval;
}
static void __exit scull_exit(void)
{
cleanup();
printk(KERN_ALERT "Scull cleanuped!
");
}
module_init(scull_init);
module_exit(scull_exit);
MODULE_LICENSE("GPL");
초기 화:
장치 이름 에 따라 alloc 사용chrdev_region () 장치 번호 신청, sculldev 메모리 할당, cdev 사용init () cdev 장 치 를 초기 화하 고 dev 의 각 구성원 을 초기 화 합 니 다. 이어서 cdevadd () dev 의 cdev 를 커 널 에 추가 하여 초기 화 끝
마 운 트 해제:
먼저 커 널 에서 sucldev - > cdev 구조, 그리고 kfree scull_dev 구조, 마지막 으로 unregister 사용chrdev_region () 장치 마 운 트 해제
위의 절차 와 같이 읽 기와 쓰기 프로그램 을 마음대로 쓰 는 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.