This two days wrote an LED driver, online also read a lot of posts.
Start thinking very clear, is to see the circuit diagram first, found that LED lights are connected to the GPM port,
Then look at the s3c6410 data manual, first to Gpmcon mouth to write command words, let gpm0-5 set to output, and then to the gpmdat mouth write data words, in the gpm0-5 pin pull low or pull high level,
Thereby controlling the LED's light and extinguish.
1. Circuit diagram
It's obvious that the LED lights are under the gpm pin.
2. Data manual
3. LED Driver Program
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/ uaccess.h>/*copy_to_user,copy_from_user*/#include <linux/io.h>/*inl (), Outl () * * * #include <linux/m iscdevice.h> #include <linux/pci.h> static long s3c64xx_gpmcon=0xf4500820; /* Here is the virtual address, the physical address can be found in the s3c6410 data manual. The virtual address can also be obtained by IOREMAP () according to the physical address.
*/static long s3c64xx_gpmdat=0xf4500824;
#define LED_MAJOR 240/* main device number/int led_open (struct inode *inode,struct file *file) {unsigned tmp;
Tmp=inl (S3c64xx_gpmcon);
PRINTK ("The Pre Gpmcon is%x", TMP);
Tmp=inl (S3c64xx_gpmdat);
PRINTK ("The Pre Gpmdat is%x", TMP); Outl (0x00111111,s3c64xx_gpmcon);
/* to Gpmcon command port to write command words, set gpm0-5 for Output port * * * PRINTK ("############ #open #############");
return 0; Static ssize_t led_read (struct file *file,char __user *buf,size_t count,loff_t * f_pos) {unsigned tmp=inl (s3c64xx_gpm
DAT);
int Num=copy_to_user (buf,&tmp,count); if (num==0) PRINTK ("Copy successfully");
else PRINTK ("Sorry copy failly");
PRINTK ("The Gpmdat is%x.", TMP);
return count; Static ssize_t led_write (struct file * file,const Char __user * buf,size_t count,loff_t * f_pos)/* I control LED lights through write (), but also
To control */{char kbuf[10] by IOCTL ();
PRINTK ("########## #write ###########");
int Num=copy_from_user (kbuf,buf,count);
if (num==0) PRINTK ("copy successfully");
else PRINTK ("Sorry copy failly");
PRINTK ("# #the Kbuf is%c", kbuf[0]); Switch (kbuf[0]) {case 0://off outl (0xff,s3c64xx_gpmdat);
/* Pull high gpmdat[0:5] pin, so that LED lights out, because the LED is a low level of current through the * * break; Case 1://on Outl (0x00,s3c64xx_gpmdat);
* * Pull low gpmdat[0:5] pin, so that LED lights on the break;
Default:break;
return count;
int led_release (struct inode *inode,struct file *file) {PRINTK ("###### #release ##########");
return 0; struct File_operations led_fops={. Owner = This_module,. Open = Led_open,. Read = Led_read,. Write = Led_write,. R
Elease = 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");
} module_init (Led_init);
Module_exit (Led_exit);
Write good source code, write makefile
OBJ-M:=LED_DRIVER.O
kdir:=/home/tmp/linux2.6.28 all
:
make-c $ (kdir) m=$ (shell pwd) modules compile=/usr/local/arm/4.4.1/bin/arm-linux-
/* Before make, there are some problems, such as the lack of a header file, and so on, the original is not set up the kernel tree, to the kernel source directory make a little bit better
After writing the driver source code and makefile file, make in this directory
The Led_driver.ko file is then generated and downloaded to the Development Board.
4. Test driver
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h >/
* #include <unistd.h>*/
int main ()
{
printf ("Hello led device.");
Char buf[10]={0,1,0,1};
int Fd=open ("/dev/led", 2,0777);
if (fd<0) {
printf ("Can ' t Open led Device");
return-1;
}
printf ("Open the LED device successfully.");
while (1)
{
int num=write (fd,&buf[0],1);
if (num<0)
printf ("We set the LED failly.");
else printf ("We set the LED off");
Sleep (1);
Write (fd,&buf[1],1);
printf ("We set the LED on");
Sleep (1);
}
Close (FD);
printf ("Bye led device.");
return 0;
}
Arm-linux-gcc-o LED_TEST.O led_test.c
After compiling, download the LED_TEST.O file to the Development Board
5. Specific operation steps
My OK6410 Development Board has installed the LINUX-2.6.18 kernel Linux system before the shell command
Insmod Led_driver.ko//load Led_driver.ko drive to Kernel
Mknod/dev/led C 240 0//The LED device file is mounted on the/dev/led, C represents the character device, 240 is the main device number, 0 is the minor
./LED_TEST.O//Start test program, light LED light
Attention:
On the PC to write the arm Development Board driver, you need to configure the PC (commonly known as the upper computer) on the configuration of cross-compilation tool chain arm-linux-
Beginning to want to not through the driver, through IOPL (3), elevation of authority, direct operation of the hardware, found in the arm Development Board can not do so.
Originally thought can only write driver's way to control registers, later found that mmap () that "/dev/mem" file system can also.
Start debugging on the Development Board, cat/var/log/messages view PRINTK output, found nothing, the original need to enter the shell command klogd to open the log function.
I wish you all a good time on the Development Board.