02 LED 驅動程式S3C64XX

[php]
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <linux/ioctl.h>
#include <linux/init.h>

#define DEVICE_NAME "leds0" // (/dev/leds)

#define UGPMCON (*(volatile unsigned long *)S3C64XX_GPMCON)
#define UGPMDAT (*(volatile unsigned long *)S3C64XX_GPMDAT)
#define UGPMPUD (*(volatile unsigned long *)S3C64XX_GPMPUD)

static long S3C64XX_GPMCON=0xF4500820;
static long S3C64XX_GPMDAT=0xF4500824;

#define LED_MAJOR 240

static int led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
// printk(KERN_ALERT"\ncmd = %d arg = %d \n", cmd, arg);

switch(cmd)
{
case 0:
printk(KERN_ALERT"led%d off\n", arg);
switch(arg)
{
case 0:
UGPMDAT |= 0x01;
break;
case 1:
UGPMDAT |= 0x02;
break;
case 2:
UGPMDAT |= 0x04;
break;
case 3:
UGPMDAT |= 0x08;
break;

default:
break;
}
break;
case 1:
printk(KERN_ALERT"led%d on\n", arg);
switch(arg)
{
case 0:
UGPMDAT &= 0xfe;
break;
case 1:
UGPMDAT &= 0xfd;
break;
case 2:
UGPMDAT &= 0xfb;
break;
case 3:
UGPMDAT &= 0xf7;
break;

default:
break;
}

break;
case 11:
printk(KERN_ALERT"led all on\n");
UGPMDAT &= 0xe0;
break;
case 10:
printk(KERN_ALERT"led all off\n");
UGPMDAT |= 0xff;
break;

default:
break;
}

return 0;
}

struct file_operations led_fops={
.owner = THIS_MODULE,
.unlocked_ioctl = led_ioctl,
};

static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR, //动态设备号

.name = DEVICE_NAME,

.fops = &led_fops,

};

static int __init led_init(void)
{
int rc;
rc = misc_register(&misc);
outl(0x00111111,S3C64XX_GPMCON);
outl(0xff,S3C64XX_GPMDAT);

if(rc<0)
{
printk(KERN_ALERT"register %s char dev error\n","leds");
return -1;
}
printk(KERN_ALERT"OK!\n");
return 0;
}

static void __exit led_exit(void)
{
unregister_chrdev(LED_MAJOR, "leds");
printk(KERN_ALERT"module exit\n");
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("cw");

[/php]

Makefile
[php]
KERNELDIR :=/home/share/linux/linux3.0/kernel/linux-3.0.1
#KERNELDIR :=/home/share/linux/linux2.6.36/linux-2.6.36.2-v1.05
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
obj-m:=led.o

clean:
rm -rf *.o *~core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers

[/php]

測試程式

[php]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
int main(int argc, char **argv)
{
int on, cmd;
int led_no;
int fd;

if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || led_ no < 0 || led_no > 3) {
fprintf(stderr, "Usage: leds led_no 0|1|2|3\n");
exit(1);
}
fd = open("/dev/leds0", 0);
if(fd < 0)
printf("Can't open /dev/leds!\n");

ioctl(fd, on, led_no);
close(fd);

return 0;
}

[/php]

Android 系統底層
CH01 簡介CH02 安裝CH03 編譯系統CH04 編譯程式的QACH05 系統軟體CH06 JNICH07 APP呼叫Android Driver教學CH30 DRM