uclinux简单LED驱动程序 by panasonic.lin@163.com 这回还是拿44b0x板上的LED开唰,这是linux2.4的方法,linux2.6有很大区别,相比之下还是2.4的内核比较简单,2.6比较灵活点。 首先声明,此方法是把驱动编译进内核,如果驱动程序比较多的话可能导致内核很冗肿,这时候建议用可加载模块的方式。顶层的简单应用程序放在文件系统中。1.0 uClinux-dist20050311/linux-2.4.x/drivers/char/{led.h,led.c} 驱动头文件 /************************************************************************************************************/ /*************led.h*************************************************/ /***********************************************************************************************************/ #ifndef __CONFIG_H #define __CONFIG_H #include<linux/config.h> #include<linux/module.h> #include<linux/kernel.h> #include<linux/fs.h> #include<linux/errno.h> #include<asm/uaccess.h> #include<linux/types.h> #include<linux/mm.h> #include<asm/arch/s3c44b0x.h> #define LED_MAJOR_NR 231 #define DEVICE_NAME "led" #define PCONC (*(volatile unsigned *)0x01D20010) #define PDATC (*(volatile unsigned *)0x01D20014) #define SET_LED_OFF 0 #define SET_LED_ON 1 #define LED0_CON (0x01<<2) #define LED1_CON (0x01<<4) #define LED2_CON (0x01<<6) #define LED0_DAT (0X1<<1) #define LED1_DAT (0X1<<2) #define LED2_DAT (0X1<<3) #endif 驱动程序主体: /************************************************************************************************************/ /*************led.c*************************************************/ /***********************************************************************************************************/ #include"led.h" static int led_open(struct inode *inode,struct file *filp); static int led_release(struct inode *inode,struct file *filp); static int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd); int led_init(void); void led_cleanup(void); static struct file_operations LED_fops= { owner:THIS_MODULE, #if 0 llseek:gpio_llseek, read:gpio_read, write:gpio_write, #endif ioctl:led_ioctl, open:led_open, release:led_release, }; static int led_open(struct inode *inode,struct file *filp) { PCONC =(PCONC&(~(0XC)))|LED0_CON;//change led0,not change led1 and led2! MOD_INC_USE_COUNT; return 0; } static int led_release(struct inode *inode,struct file *filp) { MOD_DEC_USE_COUNT; return 0; } static int led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd) { switch(cmd) { case 0: PDATC |= LED0_DAT;//LED0=1 break; case 1: PDATC &=~(LED0_DAT);//LED0=0 break; default: return -1; break; } return 0; } int led_init(void){ int result; result=register_chrdev(231,"led",&LED_fops); if(result<0) { printk(KERN_ERR ":unable to register!\n"); return (result); } printk(KERN_DEBUG ":init OK\n"); return 0; } void led_cleanup(void) { unregister_chrdev(231,"led"); }2.0 /uClinux-dist20050311/user/ledtest/{ledtest.c,Makefile} 用户空间程序 /************************************************************************************************************/ /*************ledtest.c*********************************************/ /***********************************************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> void delay(int delay){ int i; for(;delay>0;delay--){ for(i=0;i<5000;i++); } } int main(){ int fd1; int j; fd1=open("/dev/led",O_RDWR); if(fd1== -1){ printf("file can not be open"); return -1; } for(j=0;j<10;j++) { ioctl(fd1,1); delay(1000); ioctl(fd1,0); delay(1000); } close(fd1); return 0; } /************************************************************************************************************/ /*************Makefile*********************************************/ /***********************************************************************************************************/ EXEC = ledtest OBJS = ledtest.o all: $(EXEC) $(EXEC): $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) romfs: $(ROMFSINST) /bin/$(EXEC) clean: rm -f $(EXEC) *.elf *.gdb *.o3.0 修改添加驱动配置文件和Makefile uClinux-dist20050311/linux-2.4.x/drivers/char/{Makefile,config.in,mem.c} Makefile obj-$(CONFIG_C5471_WDT) += wdt_c5471.o #add by panasonic 2009-12-12 obj-$(CONFIG_LED_TEST) += led.oconfig.in if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then bool 'Samsung S3C44B0X serial ports support' CONFIG_SERIAL_S3C44B0X bool 'test led drivers' CONFIG_LED_TEST if [ "$CONFIG_SERIAL_S3C44B0X" = "y" ]; thenmem.c int __init chr_dev_init(void) { if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); memory_devfs_register(); rand_initialize(); /*add by panasonic 2009-1-1*/ #ifdef CONFIG_LED_TEST led_init(); #endif #ifdef CONFIG_I2C i2c_init_all(); #endifuClinux-dist20050311/vendors/Samsung/44B0/Makefile DEVICES = \ tty,c,5,0 console,c,5,1 cua0,c,5,64 cua1,c,5,65 \ \ mem,c,1,1 kmem,c,1,2 null,c,1,3 \ zero,c,1,5 random,c,1,8 urandom,c,1,9 \ \ ram0,b,1,0 ram1,b,1,1 \ \ 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 \ \ rom0,b,31,0 rom1,b,31,1 rom2,b,31,2 rom3,b,31,3 \ rom4,b,31,4 rom5,b,31,5 rom6,b,31,6 rom7,b,31,7 \ rom8,b,31,8 rom9,b,31,9 \ \ tty0,c,4,0 tty1,c,4,1 tty2,c,4,2 tty3,c,4,3 \ ttyS0,c,4,64 ttyS1,c,4,65 \ \ ttyp0,c,3,0 ttyp1,c,3,1 ttyp2,c,3,2 ttyp3,c,3,3 \ ttyp4,c,3,4 ttyp5,c,3,5 ttyp6,c,3,6 ttyp7,c,3,7 \ ttyp8,c,3,8 ttyp9,c,3,9 ttypa,c,3,10 ttypb,c,3,11 \ ttypc,c,3,12 ttypd,c,3,13 ttype,c,3,14 ttypf,c,3,15 \ \ led,c,231,04.0 修改添加应用程序的配置和Makefile uClinux-dist20050311/user/Makefile dir_$(CONFIG_USER_HELLO) += app dir_$(CONFIG_USER_LEDTEST) += ledtestuClinux-dist20050311/config/config.in ############################################################################# mainmenu_option next_comment comment 'led driver test' bool 'LEDtest' CONFIG_USER_LEDTEST comment "LED_TEST" endmenu #############################################################################5.0 编译连接调试 $make menuconfig 选中customize kernel settings/customize vendor/user settings 然后在kernel setting那里选中test led drivers 最后在vendor/user setting那里选中led drivers test下面的LEDtest应用程序 $make clean $make dep $make lib_only $make user_only $make romfs $make image $make 生成uclinux_rom.bin,uclinux_ram.bin.gz,romfs.img uclinux_rom.bin拷贝到tftp输出目录。 将根文件系统映像挂载到回环设备,然后拷贝到nfs输出目录: $mount -o loop romfs.img /mnt $cp -a /mnt/* /home/panasonic/nfs-root/ 在根文件系统的/etc目录新建init.d目录,在init.d目录下新建rcS脚本 #!/bin/sh mount -t proc proc /proc hostname 44b0 cat /etc/motd /bin/msh $chmod +x rcS添加可执行属性。 重启nfs服务 打开minicom 打开板子 $ping 192.168.0.1 $tftpboot 0xc500000 $bootm 0xc500000 进入shell后首先看看/dev下面有没有led的设备文件
也可以cat /proc/devices查看
好,看看bin目录有没有用户空间应用程序ledtest
运行./ledtest即可看到led一闪一闪的。
文章评论(0条评论)
登录后参与讨论