728x90
반응형
make 를 하게 되면 컴파일로부터 생성된 파일을 확인할수 있습니다
simple_app컴파일을 위해서 만들어 놓은 Make file을 다시 실행한다
실행 파일이 생성 된것을 확인 할 수 있다
/Proc/devices 파일을 통해서도 simple_drv정보를 확인 할 수 있습니다
실행을 시켜 결과값을 알아 본다
소스
simple_drv.c
#include <sys/types.h> #include <sys/stat.h>#include <sys/mman.h> #include <sys/poll.h> #include <sys/ioctl.h> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include "simple_ioctl.h" #define SIMPLE_MAJOR 500 #define SIMPLE_MINOR 100 #define SIMPLE_DEV_NAME "/dev/simple" #define SIMPLE_DEV_ADDR 0x80000000 #define SIMPLE_DEV_SIZE 0x8000 int main() { int fd, ret, rVal = 0, wVal = 200; char rBuf[80] = ""; char wBuf[] = "98765432109876543210"; char *addr; struct pollfd pfd[1]; dev_t simple_dev; char tmp[40] = ""; simple_dev = makedev(SIMPLE_MAJOR, SIMPLE_MINOR); ret = mknod(SIMPLE_DEV_NAME, S_IFCHR|0666, simple_dev); fd = open(SIMPLE_DEV_NAME, O_RDWR); printf("open: %d\n", fd); ret = read(fd, rBuf, 15); rBuf[ret] = '\0'; printf("read: %s, reg: %d\n", rBuf, ret); ret = write(fd, wBuf, 15); printf("write ret: %d\n", ret); ret = ioctl(fd, SIMPLE_INIT); printf("ioctl[SIMPLE_INIT] ret: %d\n", ret); ret = ioctl(fd, SIMPLE_READ, &rVal); printf("ioctl[SIMPLE_READ] data: %d, ret: %d\n", rVal, ret); ret = ioctl(fd, SIMPLE_WRITE, &wVal); printf("ioctl[SIMPLE_WRITE] ret: %d\n", ret); printf("ioctl[SIMPLE_RDWR] before-> wVal: %d\n", wVal); ret = ioctl(fd, SIMPLE_RDWR, &wVal); printf("ioctl[SIMPLE_RDWR] after -> wVal : %d, ret: %d\n", wVal, ret); printf("--------------before mmap\n"); sprintf(tmp, "pmap -x %d", getpid() ); system(tmp); addr = (char *)mmap(0, SIMPLE_DEV_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, SIMPLE_DEV_ADDR); printf("mmap addr: %p\n", addr); printf("--------------after mmap\n"); system(tmp); munmap(addr, SIMPLE_DEV_SIZE); printf("--------------after munmap\n"); system(tmp); pfd[0].fd = fd; pfd[0].events = POLLIN|POLLOUT|POLLERR; while(1) { ret = poll((struct pollfd *)&pfd, 1, 3000); if(pfd[0].revents & POLLIN) { ret = read(fd, rBuf, 10); } else if(pfd[0].revents & POLLOUT) { ret = write(fd, wBuf, 10); } else if(pfd[0].revents & POLLERR) { printf("poll error!!\n"); } if(ret == 0) { printf("poll timeout occured\n"); break; } } close(fd); return 0; } |
simple_app.c
#include <linux/kernel.h> #include <linux/module.h>#include <linux/init.h> #include <linux/fs.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/mman.h> #include <linux/sched.h> #include <asm/page.h> #include <asm/io.h> #include <asm/uaccess.h> #include <linux/poll.h> #ifdef ARCH_ARM #include <mach/irgs.h> #include <mach/reg_gpio.h> #endif #include "simple_ioctl.h" #define DEV_MAJOR 245 #define DEV_NAME "Simple Driver" #define DEV_ADDR 0x80000000 #define DEV_SIZE 0x8000 #define IRQF_DISABLED 0x20 int simple_major; int simple_open(struct inode *inode, struct file *filp) { int major, minor; major = MAJOR(inode->i_rdev); major = MINOR(inode->i_rdev); printk("Simple Driver : open\n"); printk("--> major : %d, minor : %d\n", major, minor); return 0; } int simple_release(struct inode *inode, struct file *filp) { printk("Simple Driver : release\n"); return 0; } ssize_t simple_read(struct file *filp, char *buf, size_t size, loff_t *pos) { char data[] = "12345678901234567890"; printk("Simple Driver : read\n"); copy_to_user(buf, data, size); return 0x11; } ssize_t simple_write(struct file *filp, const char *buf, size_t size, loff_t *pos) { char data[40]; copy_from_user(data, buf, size); printk("Simple Driver : write\n"); data[size] = '\0'; printk("--> from user : %s\n", data); udelay(100); return 0x22; } long simple_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int size; int rval = 0; int wval = 100; int ret; printk("Simple Driver: ioctl\n"); if(_IOC_TYPE(cmd) != SIMPLE_IOCTL_MAGIC) return -EINVAL; if(_IOC_NR(cmd) >= SIMPLE_IOCTL_MAX) return -EINVAL; size = _IOC_SIZE(cmd); if(size) { if(_IOC_DIR(cmd) & _IOC_READ) if(access_ok(VERIFY_WRITE, (void *)arg, size) < 0) return -EINVAL; if(_IOC_DIR(cmd) & _IOC_WRITE) if(access_ok(VERIFY_READ, (void *)arg, size) < 0) return -EINVAL; } switch(cmd) { case SIMPLE_INIT: printk("-->SIMPLE_INIT\n"); ret = 0x31; break; case SIMPLE_READ: printk("-->SIMPLE_READ\n"); copy_to_user( (void *)arg, &wval, sizeof(int) ); ret = 0x32; break; case SIMPLE_WRITE: printk("-->SIMPLE_WRITE\n"); copy_from_user( &rval, (void *)arg, sizeof(int) ); printk("----> from user : %d\n", rval); ret = 0x33; break; case SIMPLE_RDWR: printk("-->SIMPLE_RDWR\n"); ret = 0x34; break; } return ret; } int simple_mmap(struct file *filp, struct vm_area_struct *vma) { printk("Simple Driver : mmap\n"); remap_pfn_range(vma, vma->vm_start, DEV_ADDR >> PAGE_SHIFT, DEV_SIZE, vma->vm_page_prot); printk("--> start : 0x%x, end: 0x%x\n", (unsigned int)vma->vm_start, (unsigned int)vma->vm_end); return 0; } int readCnt = 0; int writeCnt = 0; DECLARE_WAIT_QUEUE_HEAD(readQueue); DECLARE_WAIT_QUEUE_HEAD(writeQueue); int simple_poll(struct file *filp, struct poll_table_struct *pt) { unsigned int state = 0; printk("Simple Driver : poll\n"); poll_wait(filp, &readQueue, pt); poll_wait(filp, &writeQueue, pt); if(readCnt > 0) { state |= POLLIN | POLLRDNORM; } if(writeCnt > 0) { state |= POLLIN | POLLWRNORM; } return state; } irqreturn_t simple_handler(int irq, void *dev_id) { printk("Simple Interrupt handler\n"); printk("--> irq number : %d\n", irq); return IRQ_HANDLED; } struct file_operations simple_fops = { .open = simple_open, .release = simple_release, .read = simple_read, .write = simple_write, .unlocked_ioctl = simple_ioctl, .mmap = simple_mmap, .poll = simple_poll, }; int simple_drv_init(void) { simple_major = register_chrdev(DEV_MAJOR, DEV_NAME, &simple_fops); printk("Simple Driver : registered\n"); printk("--> major : %d\n", simple_major); if(request_irq(10, simple_handler, IRQF_DISABLED, "Simple Interrupt", NULL) < 0) printk("--> request irq failed\n"); return simple_major; } void simple_drv_exit(void) { unregister_chrdev(simple_major, DEV_NAME); printk("Simple Driver : unregistered\n"); return; } module_init(simple_drv_init); module_exit(simple_drv_exit); MODULE_LICENSE("Dual BSD/GPL"); |
simple_ioctl.h
#define SIMPLE_IOCTL_MAGIC 's' #define SIMPLE_INIT _IO(SIMPLE_IOCTL_MAGIC, 0) #define SIMPLE_READ _IOR(SIMPLE_IOCTL_MAGIC, 1, int) #define SIMPLE_WRITE _IOW(SIMPLE_IOCTL_MAGIC, 2, int) #define SIMPLE_RDWR _IOWR(SIMPLE_IOCTL_MAGIC, 3, int) #define SIMPLE_IOCTL_MAX 4 |
Makefile
obj-m := simple_drv.o ifeq ($(ARCH), xxx) KDIR :=/usr/src/linux CROSS_COMPILE :=arm-none-linux-gnueabi- CCFLAGS := -static else KDIR :=/lib/modules/$(shell uname -r)/build endif TARGET := simple_app PWD := $(shell pwd) CC := ${CROSS_COMPILE}gcc LD := ${CROSS_COMPILE}ld AR := ${CROSS_COMPILE}ar all: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules $(TARGET): simple_app.c $(CC) $(CCFLAGS) -o $@ $^ clean: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean rm -f $(TARGET) |
도움을 주신 반장 형님 감사합니다
728x90
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151106 - 11번 남수진 / 라즈베리 파이(디바이스 드라이버를 이용한 GPIO제어), 영상처리(비트맵 이미지 편집) (8) | 2015.11.07 |
---|---|
LED_DRIVER 소스 파일 (3) | 2015.11.06 |
20151106 출석번호 9번 김태현 비트맵파일 분석 (7) | 2015.11.06 |
디바이스 드라이브 예제 소스파일 (3) | 2015.11.05 |
20151102-김재홍-라즈베리파이_C프로그래밍&ASM_Translation (6) | 2015.11.02 |
20151030 - 홍준모 오전 : UART 이용. 오후 : 사물 인터넷 (라즈베리파이), 어셈블리 (8) | 2015.10.30 |
2015-10-29 업무일지 천정호 (3) | 2015.10.30 |
20151028-업무일지-주재민 (3) | 2015.10.28 |