In the previous article, we introduced the framework of the character device driver. In this article, we will operate on the real hardware-led.
Author: canghai hunter Source: http://blog.csdn.net/embedded_hunter reproduced please indicate the source of embedded technology exchange QQ group: 179012822
I. experiment environment
Development machine environment
Operating System: Ubuntu 9.10
Cross-compiling environment: Arm-Linux-GCC 4.2.2, installation location/usr/local/ARM/4.3.2/
6410 board kernel source code path:/work/linux-2.6.36.2-v1.05/
Target Board Environment: OK6410-A linux2.6.36
Ii. Experiment Principles
Controlling LEDs is the simplest thing. Learning the LED driver is equivalent to learning the "Hello World" program in other programming languages. It is an entry-level program.
To learn the driver, you must understand the hardware. Next, let's look at the hardware-related materials.
Ok6410 led schematic
Ok6410 led schematic
From the above schematic, we can know that the connection method between the led and the CPU pin is as follows.
Led1-gpm0
Led2-gpm1
Led3-gpm2
Led4-gpm3
You can find the corresponding control method from the Data Manual. Here we take led1 as an example to introduce the led1 operation method. For other similar operations, please analyze it yourself.
As you can see above, you need to set gpm0 as the output mode first. Configure the corresponding registers.
Then, turn the 0th position of the gpmdat register 0 light on and turn off the 1 light.
Iii. Experiment steps
1. Write the driver
Driver_led.c
#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <asm/uaccess.h> /* copy_to_user,copy_from_user */#include <linux/miscdevice.h> #include <linux/pci.h> #include <mach/map.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank-m.h> #include <plat/gpio-cfg.h>#define LED_MAJOR 240int led_open (struct inode *inode,struct file *filp){unsigned tmp; tmp = readl(S3C64XX_GPMCON); tmp = (tmp & ~(0x7U<<1))|(0x1U); writel(tmp, S3C64XX_GPMCON); printk("#########open######\n");return 0;}ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos){printk("#########read######\n");return count;}ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos){char wbuf[10];unsigned tmp; printk("#########write######\n");copy_from_user(wbuf,buf,count);switch(wbuf[0]){case 0: //offtmp = readl(S3C64XX_GPMDAT); tmp |= (0x1U); writel(tmp, S3C64XX_GPMDAT);break;case 1: //ontmp = readl(S3C64XX_GPMDAT); tmp &= ~(0x1U); writel(tmp, S3C64XX_GPMDAT);break;default :break;}return count;}int led_release (struct inode *inode, struct file *filp){printk("#########release######\n");return 0;}struct file_operations led_fops ={.owner = THIS_MODULE,.open = led_open,.read = led_read,.write = led_write,.release = led_release,};int __init led_init (void){int rc;printk ("Test led dev\n");rc = register_chrdev(LED_MAJOR,"led",&led_fops);if (rc <0){printk ("register %s char dev error\n","led");return -1;}printk ("ok!\n");return 0;}void __exit led_exit (void){unregister_chrdev(LED_MAJOR,"led");printk ("module exit\n");return ;}module_init(led_init);module_exit(led_exit);
Makefile
obj-m := driver_led.oKDIR :=/work/linux-2.6.36.2-v1.05/all:make -C $(KDIR) M=$(shell pwd) modulesinstall:cp driver_led.ko /tftpboot/clean:make -C $(KDIR) M=$(shell pwd) clean
2. Compile the test program
Test. c
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main (void){int fd;char buf[10]={0,1};fd = open("/dev/my_led",O_RDWR);if (fd < 0){printf ("Open /dev/my_led file error\n");return -1;}while(1){write(fd,&buf[0],1);sleep(1);write(fd,&buf[1],1);sleep(1);}close (fd);return 0;}
3. Compile the driver and test program
Compile the driver
# Make
Place the driver in the TFTP working directory/tftpboot
# Make install
Compile the test program
# Arm-Linux-GCC test. C-o Test
Put the test program to the TFTP working directory/tftpboot
# Cp test/tftpboot
4. Download the program to the Development Board
Modify the IP address of the Development Board in the same CIDR block as the host. Make sure that the TFTP service of the PC is enabled.
Download the program to the Development Board
Smdk6410 # TFTP-L/lib/modules/2.6.36.2/driver_led.ko-r driver_led.ko-G 192.168.1.111192.168.1.111 is the Server IP Address
Smdk6410 # TFTP-l test-r test-G 192.168.1.111
5. Test
Load the driver # insmod/lib/modules/2.6.36.2/driver_led.ko
Create a device file # mknod/dev/my_led C 240 0
Test./test
[Root @ forlinx6410] #./test
The led0 on the ok6410 board is flashing.
Uninstall driver # rmmod driver_led
From the above results, we can see that when you call the corresponding file operation function, the corresponding function in the driver will also be called.
You can modify the corresponding program to test other cases.
Author: canghai hunter Source: http://blog.csdn.net/embedded_hunter reproduced please indicate the source of embedded technology exchange QQ group: 179012822
Note: This driver uses the most basic kernel functions. The operation method may be different from other drivers you have seen, especially the functions for registering character devices. It doesn't matter. We will introduce other related functions step by step.