kernel_thread로 디바이스 접근 가능한가요?
글쓴이: jeon9075 / 작성시간: 토, 2008/08/23 - 2:45오전
kernel_thread를 사용하여 fnd device에 불을 키려고 합니다.
가능한 방법이 있는지 알고 싶습니다.
제가 시도한 방법으로는 되질 않네요~
*** device driver code *** fnd.c #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/types.h> #include <asm/fcntl.h> #include <linux/ioport.h> #include <asm/processor.h> #include <asm/ioctl.h> #include <asm/hardware.h> #include <asm/uaccess.h> #include <asm/io.h> #define DRIVER_AUTHOR "hanback" #define DRIVER_DESC "fnd test" #define FND_MODULE_VERSION "FND PORT V0.1" #define FND_NAME "FND" #define FND_MAJOR_NUMBER 0 #define FND_ADDRESS_GRID 0x08800000 #define FND_ADDRESS_DATA 0x08801000 #define FND_ADDRESS_RANGE 0x1000 //Global variable static unsigned int fnd_usage = 0; static unsigned int fnd_major = 0; static unsigned char *fnd_data; static unsigned char *fnd_grid; static char data[6]; static unsigned char digit[6]={0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; int fnd_open (struct inode *inode, struct file *filp) { if(fnd_usage != 0) return -EBUSY; fnd_grid = ioremap(FND_ADDRESS_GRID, FND_ADDRESS_RANGE); fnd_data = ioremap(FND_ADDRESS_DATA, FND_ADDRESS_RANGE); if(!check_region(fnd_data,FND_ADDRESS_RANGE) && !check_region(fnd_grid, FND_ADDRESS_RANGE)) { request_region(fnd_grid, FND_ADDRESS_RANGE, FND_NAME); request_region(fnd_data, FND_ADDRESS_RANGE, FND_NAME); } else printk("driver : unable to register this!\n"); fnd_usage = 1; return 0; } int fnd_release (struct inode *inode, struct file *filp) { iounmap(fnd_grid); iounmap(fnd_data); release_region(fnd_data, FND_ADDRESS_RANGE); release_region(fnd_grid, FND_ADDRESS_RANGE); fnd_usage = 0; return 0; } unsigned char Getfndcode (char x) { unsigned char code; switch (x) { case 0x0 : code = 0x3f; break; case 0x1 : code = 0x06; break; case 0x2 : code = 0x5b; break; case 0x3 : code = 0x4f; break; case 0x4 : code = 0x66; break; case 0x5 : code = 0x6d; break; case 0x6 : code = 0x7d; break; case 0x7 : code = 0x07; break; case 0x8 : code = 0x7f; break; case 0x9 : code = 0x6f; break; case 0xA : code = 0x77; break; case 0xB : code = 0x7c; break; case 0xC : code = 0x39; break; case 0xD : code = 0x5e; break; case 0xE : code = 0x79; break; case 0xF : code = 0x71; break; default : code = 0; break; } return code; } int myfunc (void *unused) { unsigned int i,k; for (;;) { for(i=0;i<6;i++) { // *fnd_grid = ~digit[i]; // *fnd_data = data[i]; for(k=0;k<65536;k++); //schedule_timeout(1000); } } } ssize_t fnd_write (struct file *inode, const char *gdata, size_t length, loff_t *off_what) { unsigned int num; copy_from_user(&num,gdata,4); data[5]=Getfndcode (num & 0x0f); data[4]=Getfndcode (0xE); // 'S' strike data[3]=Getfndcode (num & 0xf0); data[2]=Getfndcode (0xB); // 'B' ball data[1]=Getfndcode (0); data[0]=Getfndcode (0); } struct file_operations fnd_fops = { .owner = THIS_MODULE, .open = fnd_open, .write = fnd_write, .release = fnd_release, }; int fnd_init(void) { int result; kernel_thread(myfunc, NULL, 0); result = register_chrdev(FND_MAJOR_NUMBER, FND_NAME, &fnd_fops); if (result < 0) { printk(KERN_WARNING"Can't get any major\n"); return result; } fnd_major = result; printk("init module, fnd major number : %d\n", result); return 0; } void fnd_exit(void) { if(unregister_chrdev(fnd_major,FND_NAME)) printk("driver: %s DRIVER EXIT FAILED\n", FND_NAME); else printk("driver: %s DRIVER EXIT\n", FND_NAME); } module_init(fnd_init); module_exit(fnd_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("Dual BSD/GPL"); *********** test.c code ******************** #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> #include <fcntl.h> int baseball[3], userball[3]; int baserand() { srand((unsigned int)time(NULL)); return (rand()%9); } void initgame(int baseball[]) { baseball[0] = baserand(); baseball[1] = baserand(); while (baseball[0] == baseball[1]) baseball[1]=baserand(); baseball[2] = baserand(); while ((baseball[0] == baseball[2]) || (baseball[1] == baseball[2])) baseball[2]=baserand(); } void inputball(int userball[], int tmp) { int i; for(i=2; i>=0; i--) { userball [i] = tmp % 10; tmp /= 10; } } void cmpball(int *baseball, int *userball, int *strike, int *ball) { int i, j; for(i=0; i<3; i++){ for(j=0; j<3; j++){ if((i==j) && (baseball[i] == userball[j])) *strike = *strike+1; else if(baseball[i] == userball[j]) *ball = *ball+1; else ; } } } int main(void) { int fd; int value; int strike, ball; int cnt, tmp; int call; printf("===Baseball Game===\n\n"); if((fd=open("/dev/fnd",O_RDWR|O_SYNC)) < 0) { printf("FND open fail\n"); exit(1); } initgame (baseball); for (cnt=0; cnt<3; cnt++) printf("baseball[%d] = %d\n",cnt,baseball[cnt]); printf("\n"); cnt = 1; while(1){ printf("\n%dth Input 3 Numbers ?", cnt); scanf("%d",&tmp); strike=0 , ball=0; inputball(userball, tmp); cmpball (baseball, userball, &strike, &ball); printf("\n%d Strike! %d Ball!!\n",strike, ball); ball = ball << 4; call = ball | strike; write(fd,&call,4); if(strike == 3) break; cnt++; } printf("\n==========!!Congraturation!!==========\n\n"); printf("\nYou find %dth count.\n",cnt); close(fd); return 0; } ****************** Makefile ************************************* # 7-segment Device Driver Makefile CC = arm-linux-gcc obj-m := fnd.o KDIR := /working/linux-2.6.12-sm2 PWD := $(shell pwd) TEST_TARGET = test TEST_SRCS = test.c default:$(TEST_TARGET) $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules $(CC) $(TEST_SRCS) -o $@ rm -f default clean: rm -f fnd rm -f *.ko rm -f *.o rm -f *.mod.* rm -f .*.cmd rm -f $(TEST_TARGET)
Forums:
댓글 달기