Presentation is loading. Please wait.

Presentation is loading. Please wait.

 LED 를 직접 제어하는 디바이스 드라이버를 작성해 보자  Reminder: LED 는 SPI 를 통해 ARM7 과 연결된다. ◦ 그렇다면 고쳐야 하는 코드는 어디에 ?  linux-2.6.x/arch/arm/mach-nds/arm7 ◦ Hardware spec.

Similar presentations


Presentation on theme: " LED 를 직접 제어하는 디바이스 드라이버를 작성해 보자  Reminder: LED 는 SPI 를 통해 ARM7 과 연결된다. ◦ 그렇다면 고쳐야 하는 코드는 어디에 ?  linux-2.6.x/arch/arm/mach-nds/arm7 ◦ Hardware spec."— Presentation transcript:

1

2  LED 를 직접 제어하는 디바이스 드라이버를 작성해 보자  Reminder: LED 는 SPI 를 통해 ARM7 과 연결된다. ◦ 그렇다면 고쳐야 하는 코드는 어디에 ?  linux-2.6.x/arch/arm/mach-nds/arm7 ◦ Hardware spec 은 ??  슬라이드 05

3  Power management device ◦ Index register  0-1: register select (0~3)  2-6: not used  7: direction (0=write, 1=read) ◦ Register 0 : power management control  0: sound amplifier (0=disable, 1=enable)  1: sound related? (0=disable, 1=enable)  2: lower backlight (0=disable, 1=enable)  3: upper backlight (0=disable, 1=enable)  4: power LED blinking enable (0=always on, 1=blinking)  5: power LED blinking speed (0=slow, 1=fast)  6: DS system power (0=normal, 1=shut down)  7: not used ◦ Register 1: battery status  0: battery power LED status (0=Good/Green, 1=Low/Red) ◦ Register 2: microphone amplifier control  0: amplifier (0=disable, 1=enable) ◦ Register 3: microphone amplifier gain control  0-1: gain (0~3=gain 20, 40, 80, 160)

4  다행히도, 이미 되어 있음.  linux-2.6.x/arch/arm/mach-nds/arm7/spi.c ◦ power_write(enum power_reg reg, u8 val)  …/spi.h #define POWER0_SOUND_AMP (1<<0) #define POWER0_LOWER_BACKLIGHT (1<<2) #define POWER0_UPPER_BACKLIGHT (1<<3) #define POWER0_LED_BLINK (1<<4) #define POWER0_LED_FAST (1<<5) #define POWER0_SYSTEM_POWER (1<<6) enum power_reg { POWER_CONTROL, POWER_BATTERY, POWER_MIC_CONTROL, POWER_MIC_GAIN };

5  Power control (Register 0) 의 제어가 가능하도록 하는 디바이스 드라이버를 만들어 보자.  설계 사항 ◦ ARM9 에서 ARM7 으로 명령을 보내야 한다. ◦ ARM7 에서는 명령을 처리한다. ◦ Device driver 를 만들어야 한다. ◦ 파일 시스템에 device driver 를 만들어야 한다. ◦ 테스트할 응용 프로그램을 만들어야 한다.

6  구현되어 있음  linux-2.6.x/include/asm/arch/fifo.h #define FIFO_FIRMWARE (0 << 29) #define FIFO_BUTTONS (1 << 29) #define FIFO_TOUCH (2 << 29) #define FIFO_MIC (3 << 29) #define FIFO_WIFI (4 << 29) #define FIFO_SOUND (5 << 29) #define FIFO_POWER (6 << 29) #define FIFO_TIME (7 << 29) #ifdef __DSLINUX_ARM7__ static inline void nds_fifo_send(u32 command) { while (NDS_REG_IPCFIFOCNT & FIFO_SEND_FULL) ; /* do nothing */ NDS_REG_IPCFIFOSEND = command; } #else static inline void nds_fifo_send(u32 command) { int fifo_full = 0; while (NDS_REG_IPCFIFOCNT & FIFO_SEND_FULL) fifo_full = 1; NDS_REG_IPCFIFOSEND = command; if (fifo_full) printk(KERN_WARNING "fifo: detected send attempt while " "fifo was full\n"); } #endif /* __DSLINUX_ARM7__ */

7  어디서 처리하는가 ? ◦ arch/arm/mach-nds/arm7/main.c  static void receiveFIFOCommand(void) ◦ ARM9 에서 보낸 명령은 data = FIFO_GET_TYPE_DATA(fifo_recv);  여기에서 읽음 ◦ 처리는 case FIFO_POWER: power_write(POWER_CONTROL, POWER0_SYSTEM_POWER); break;  현재 구현은 명령이 들어오면 시스템을 끈다. ◦ 우리가 바라는 구현은 case FIFO_POWER: power_write(POWER_CONTROL, (data & 0xff) ); break;

8  어디에 ? ◦ char device 에 만들자 ( 쉬우므로 ) ◦ drivers/char/ds_power.c

9 #include #define DEVNAME "/dev/dspower" int ds_power_major=254; // 에러인 경우 바꾸어야 함. 0 이면 자동 부여. int result; static int ds_power_open(struct inode *inode, struct file *flip); static int ds_power_release(struct inode *inode, struct file *flip); static int ds_power_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned int arg); static ssize_t ds_power_read(struct file *flip, char *buf, size_t count, loff_t *f_pos); static ssize_t ds_power_write(struct file *flip, char *buf, size_t count, loff_t *f_pos); static int ds_power_open(struct inode *inode, struct file *flip)

10 static int ds_power_release(struct inode *inode, struct file *flip); static int ds_power_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned int arg); static ssize_t ds_power_read(struct file *flip, char *buf, size_t count, loff_t *f_pos); static ssize_t ds_power_write(struct file *flip, char *buf, size_t count, loff_t *f_pos); static int ds_power_open(struct inode *inode, struct file *flip) { return 0; } static int ds_power_release(struct inode *inode, struct file *flip) { return 0; } static int ds_power_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned int arg) { return 0; }

11 static ssize_t ds_power_read(struct file *flip, char *buf, size_t count, loff_t *f_pos) { return 0; } static ssize_t ds_power_write(struct file *flip, char *buf, size_t count, loff_t *f_pos) { nds_fifo_send(FIFO_POWER | (buf[0] & 0xff)); return 0; } static struct file_operations ds_power_fops = {.open = ds_power_open,.read = ds_power_read,.write = ds_power_write,.ioctl = ds_power_ioctl,.release = ds_power_release, };

12 static int ds_power_init() { result = register_chrdev(ds_power_major, DEVNAME, &ds_power_fops); if(result < 0) { printk(KERN_WARNING "%s: can't get major %d\n", DEVNAME, ds_power_major); return result; } printk(" init module succes: %s major number : %d\n", DEVNAME, result); devfs_mk_cdev(MKDEV(result,0), S_IFCHR|S_IRUGO|S_IWUGO, "dspower"); return 0; } static void ds_power_exit() { unregister_chrdev(result, DEVNAME); } module_init(ds_power_init); module_exit(ds_power_exit);

13  이제 커널에 포함 시켜야 한다. ◦ drivers/char/Makefile obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o ds_power.o 추가

14  이름이.. /dev/dspower  Major number.. 254  문제점 : DSLinux 는 ROMFS 를 쓴다. ◦ 부팅 후 디바이스 파일을 만들 수 없다. (mknod 안됨 )  빌드 시 ROMFS 를 만들어야 함.  만드는 파일 ◦ dslinux/vendors/Nintendo/DLDI/Makefile

15  Devices :=  이 부분 에서 dldi,b,240,0 \ dldi1,b,240,1 dldi2,b,240,2 dldi3,b,240,3 dldi4,b,240,4 \ \ ptyp0,c,2,0 ptyp1,c,2,1 ptyp2,c,2,2 ptyp3,c,2,3 \ ptyp4,c,2,4 ptyp5,c,2,5 ptyp6,c,2,6 ptyp7,c,2,7 \ ptyp8,c,2,8 ptyp9,c,2,9 ptypa,c,2,10 ptypb,c,2,11 \ ptypc,c,2,12 ptypd,c,2,13 ptype,c,2,14 ptypf,c,2,15 \ \ dsp,c,14,3 dspower,c,254,0 \ \ fb0,c,29,0\ fb1,c,29,1\ 여기에 넣자

16 이제 make!

17  romfs/dev 에 dspower 파일이 만들어졌는 지 확인 embedded@ubuntu:~/dslinux$ ls romfs/dev @console,c,5,1 @mouse0,c,13,32 @ptypc,c,2,12 @tty0,c,4,0 ttyp7 @cua0,c,5,64 @mtd0,c,90,0 @ptypd,c,2,13 @tty1,c,4,1 ttyp8 @cua1,c,5,65 @null,c,1,3 @ptype,c,2,14 @tty2,c,4,2 ttyp9 @dldi1,b,240,1 @psaux,c,10,1 @ptypf,c,2,15 @tty3,c,4,3 ttypa @dldi2,b,240,2 @ptyp0,c,2,0 @ram0,b,1,0 @tty4,c,4,4 ttypb @dldi3,b,240,3 @ptyp1,c,2,1 @ram1,b,1,1 @tty5,c,4,5 ttypc @dldi4,b,240,4 @ptyp2,c,2,2 @random,c,1,8 @tty6,c,4,6 ttypd @dldi,b,240,0 @ptyp3,c,2,3 @rom0,b,31,0 @tty7,c,4,7 ttype @dsp,c,14,3 @ptyp4,c,2,4 @rom1,b,31,1 @tty,c,5,0 ttypf @dspower,c,254,0 @ptyp5,c,2,5 @rom2,b,31,2 ttyp0 @tun,c,10,200 @fb0,c,29,0 @ptyp6,c,2,6 @rom3,b,31,3 ttyp1 @urandom,c,1,9 @fb1,c,29,1 @ptyp7,c,2,7 @rom4,b,31,4 ttyp2 @zero,c,1,5 @firmware,c,90,2 @ptyp8,c,2,8 @rom5,b,31,5 ttyp3 @kmem,c,1,2 @ptyp9,c,2,9 @rom6,b,31,6 ttyp4 log @ptypa,c,2,10 @rom7,b,31,7 ttyp5 @mem,c,1,1 @ptypb,c,2,11 @touch,c,13,65 ttyp6

18  드라이버가 포함되었는 지 확인  linux-2.6.x 디렉터리에서 ◦ arm-linux-elf-nm linux | grep ds_power 020a3cf4 t ds_power_exit 02160870 d ds_power_fops 020a3c80 tds_power_init 020a3c1c t ds_power_ioctl 02173b8c B ds_power_major 020a3c0c t ds_power_open 020a3c24 t ds_power_read 020a3c14 t ds_power_release 020a3c2c t ds_power_write 0200cd68 t __initcall_ds_power_init

19  test_power.c #include int main(int argc, char* argv[]) { int fd; unsigned int cmd; fd = open("/dev/dspower", O_RDWR); if(fd<0) { printf("error(open):%d\n", fd); return -1; } if(argc>1) { sscanf(argv[1], "%x", &cmd); } else cmd = 0x1f; // 천천히 깜빡인다. write(fd, &cmd, 1); close(fd); return 0; } 이건 응용 프로그램이다. 운영체체 directory 안에다 만들면 안된다.

20  test_power 1f ◦ LED 가 천천히 깜빡인다.  test_power 3f ◦ LED 가 빠르게 깜빡인다.  test_power f ◦ LED 가 깜빡이지 않는다.  test_power 7 ◦ 상단 LCD 백라이트가 꺼진다. ( 화면 안보임 )  test_power f ◦ 상단 LCD 백라이트가 켜진다.  test_power 0 ◦ NDSL 이 꺼진다. ( 완전히 꺼지는 것은 아님 )

21  POWER_BATTERY 에 대하여 실습해 보자.  스스로 디바이스 드라이버를 만들어 보자. ◦ 설계 : 2 bytes 를 받아, 상위 바이트가 1 이면 BATTERY, 0 이면 CONTROL 로 설정 ◦ arch/arm/mach-nds/arm7/main.c  static void receiveFIFOCommand(void) case FIFO_POWER: if( (data >> 8) & 1) power_write(POWER_BATTERY, (data & 0xff) ); else power_write(POWER_CONTROL, (data & 0xff) ); break;

22  디바이스 드라이버 제작 ◦ ds_battery.c  write 함수에서  nds_fifo_send(FIFO_POWER | ((1<<8) | (buf[0] & 0xff)));  /dev/ 에 들어갈 파일명을 정한다.  Major number 를 정한다. ◦ Makefile 을 수정  ROMFS ◦ 결정한 Major number 와 파일명으로 파일을 만든다.  DLDI/Makefile 수정  빌드  테스트할 응용을 만든다. ◦ 0: Green, 1: Red


Download ppt " LED 를 직접 제어하는 디바이스 드라이버를 작성해 보자  Reminder: LED 는 SPI 를 통해 ARM7 과 연결된다. ◦ 그렇다면 고쳐야 하는 코드는 어디에 ?  linux-2.6.x/arch/arm/mach-nds/arm7 ◦ Hardware spec."

Similar presentations


Ads by Google