mirror of
https://github.com/ioacademy-jikim/device_driver.git
synced 2026-08-11 16:32:54 +00:00
first sample
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
obj-m = my_work.o
|
||||
|
||||
KDIR = /usr/src/tegra
|
||||
PWD = $(shell pwd)
|
||||
|
||||
default:
|
||||
make -C $(KDIR) SUBDIRS=$(PWD) modules
|
||||
|
||||
clean:
|
||||
make -C $(KDIR) SUBDIRS=$(PWD) clean
|
||||
@@ -0,0 +1,34 @@
|
||||
#if 1
|
||||
#include <stdio.h>
|
||||
struct aaa
|
||||
{
|
||||
int count;
|
||||
int flag;
|
||||
int data[];
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
struct aaa *p;
|
||||
p = malloc( sizeof(struct aaa) + sizeof(int)*100 );
|
||||
p->count = 0;
|
||||
p->data[0] = 10;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
struct aaa
|
||||
{
|
||||
int a;
|
||||
int b[];
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
struct aaa a;
|
||||
printf("sizeof(a)=%lu\n", sizeof a );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h> //misc_register
|
||||
#include <linux/wait.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
static struct input_dev *my_input;
|
||||
|
||||
irqreturn_t my_handler_up(int irq, void *id)
|
||||
{
|
||||
printk("my_handler_up()\n");
|
||||
input_sync(my_input);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
irqreturn_t my_handler_down(int irq, void *id)
|
||||
{
|
||||
static int value=0;
|
||||
printk("my_handler_down()\n");
|
||||
input_report_key(my_input, KEY_VOLUMEDOWN, value^=1);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int my_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags=IRQF_SHARED;
|
||||
my_input = input_allocate_device();
|
||||
__set_bit( EV_KEY, my_input->evbit);
|
||||
__set_bit( KEY_VOLUMEDOWN, my_input->keybit);
|
||||
__set_bit( KEY_VOLUMEUP, my_input->keybit);
|
||||
|
||||
ret = input_register_device(my_input);
|
||||
flags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(342, my_handler_down, flags, "MY_INT_DOWN", my_handler_down);
|
||||
ret = request_irq(379, my_handler_up, flags, "MY_INT_UP", my_handler_up);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void my_exit(void)
|
||||
{
|
||||
free_irq( 342, my_handler_down);
|
||||
free_irq( 379, my_handler_up);
|
||||
input_unregister_device(my_input);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init( my_init );
|
||||
module_exit( my_exit );
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_CFLAGS := -fPIE
|
||||
LOCAL_LDFLAGS := -fPIE -pie
|
||||
LOCAL_MODULE := myapp
|
||||
LOCAL_SRC_FILES := input_app.c
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#if 1
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
int fd, ret;
|
||||
struct input_event events[64];
|
||||
fd = open( "/dev/input/event4", O_RDONLY );
|
||||
while (ret = read( fd, events, sizeof events ))
|
||||
{
|
||||
for( i=0 ; i<(ret/(int)sizeof(struct input_event)); i++ )
|
||||
printf("type=%d, code=%d, value=%d\n",
|
||||
events[i].type, events[i].code, events[i].value);
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#if 1
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
int fd, ret;
|
||||
int temp[64];
|
||||
fd = open( "/dev/mydev", O_RDONLY );
|
||||
while (ret = read( fd, temp, sizeof temp ))
|
||||
{
|
||||
for( i=0 ; i<(ret/(int)sizeof(int)); i++ )
|
||||
printf("temp[%d] = %d\n", i, temp[i] );
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
static struct work_struct work;
|
||||
|
||||
irqreturn_t my_handler(int irq, void *id)
|
||||
{
|
||||
printk("my_handler()\n");
|
||||
schedule_work( &work );
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
void my_work_handler(struct work_struct *work)
|
||||
{
|
||||
printk("my_work_handler()\n");
|
||||
}
|
||||
|
||||
int my_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags=IRQF_SHARED;
|
||||
flags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(342, my_handler, flags, "MY_INT", my_handler);
|
||||
INIT_WORK(&work, my_work_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void my_exit(void)
|
||||
{
|
||||
free_irq( 342, my_handler);
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init( my_init );
|
||||
module_exit( my_exit );
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
typedef struct
|
||||
{
|
||||
int queue[64];
|
||||
int head;
|
||||
int tail;
|
||||
int count;
|
||||
} QUEUE;
|
||||
|
||||
void init( QUEUE *q )
|
||||
{
|
||||
q->head = 0;
|
||||
q->tail = 0;
|
||||
q->count = 0;
|
||||
}
|
||||
void put( QUEUE *q, int data )
|
||||
{
|
||||
q->queue[q->head] = data;
|
||||
q->head = (q->head+1)%64;
|
||||
q->count++;
|
||||
}
|
||||
int get( QUEUE *q )
|
||||
{
|
||||
int temp;
|
||||
temp = q->queue[q->tail];
|
||||
q->tail = (q->tail+1)%64;
|
||||
q->count--;
|
||||
return temp;
|
||||
}
|
||||
int is_empty( QUEUE *q )
|
||||
{
|
||||
return q->count == 0 ;
|
||||
}
|
||||
int main()
|
||||
{
|
||||
QUEUE q;
|
||||
init( &q );
|
||||
put( &q, 1 );
|
||||
put( &q, 2 );
|
||||
put( &q, 3 );
|
||||
while( !is_empty( &q ) )
|
||||
printf("%d\n", get(&q) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h> //misc_register
|
||||
#include <linux/wait.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int queue[64];
|
||||
int head;
|
||||
int tail;
|
||||
int count;
|
||||
} QUEUE;
|
||||
static QUEUE queue;
|
||||
static DECLARE_WAIT_QUEUE_HEAD(my_wait);
|
||||
|
||||
|
||||
void init( QUEUE *q )
|
||||
{
|
||||
q->head = 0;
|
||||
q->tail = 0;
|
||||
q->count = 0;
|
||||
}
|
||||
void put( QUEUE *q, int data )
|
||||
{
|
||||
q->queue[q->head] = data;
|
||||
q->head = (q->head+1)%64;
|
||||
q->count++;
|
||||
}
|
||||
int get( QUEUE *q )
|
||||
{
|
||||
int temp;
|
||||
temp = q->queue[q->tail];
|
||||
q->tail = (q->tail+1)%64;
|
||||
q->count--;
|
||||
return temp;
|
||||
}
|
||||
int is_empty( QUEUE *q )
|
||||
{
|
||||
return q->count == 0 ;
|
||||
}
|
||||
|
||||
int my_open (struct inode *inode, struct file *filp)
|
||||
{
|
||||
init(&queue);
|
||||
printk("my_open()\n");
|
||||
return 0;
|
||||
}
|
||||
int my_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
printk("my_close()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
irqreturn_t my_handler_up(int irq, void *id)
|
||||
{
|
||||
printk("my_handler_up()\n");
|
||||
wake_up_interruptible(&my_wait);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
irqreturn_t my_handler_down(int irq, void *id)
|
||||
{
|
||||
printk("my_handler_down()\n");
|
||||
put( &queue, KEY_VOLUMEDOWN );
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
ssize_t my_read (struct file *filp, char __user *buff, size_t size,
|
||||
loff_t *off)
|
||||
{
|
||||
int i;
|
||||
int *p = (int*)buff;
|
||||
printk("my_read()\n");
|
||||
if( is_empty(&queue) )
|
||||
interruptible_sleep_on(&my_wait);
|
||||
|
||||
for(i=0; !is_empty(&queue); i++ )
|
||||
put_user( get(&queue) , p+i);
|
||||
return 4*i;
|
||||
}
|
||||
|
||||
static struct file_operations fops =
|
||||
{
|
||||
.open = my_open,
|
||||
.release = my_close,
|
||||
.read = my_read,
|
||||
};
|
||||
|
||||
static struct miscdevice misc =
|
||||
{
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = "mydev",
|
||||
.fops = &fops,
|
||||
};
|
||||
|
||||
int my_init(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags=IRQF_SHARED;
|
||||
misc_register( &misc );
|
||||
flags |= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
ret = request_irq(342, my_handler_down, flags, "MY_INT_DOWN", my_handler_down);
|
||||
ret = request_irq(379, my_handler_up, flags, "MY_INT_UP", my_handler_up);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void my_exit(void)
|
||||
{
|
||||
free_irq( 342, my_handler_down);
|
||||
free_irq( 379, my_handler_up);
|
||||
misc_deregister( &misc );
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init( my_init );
|
||||
module_exit( my_exit );
|
||||
|
||||
Reference in New Issue
Block a user