1.驱动程序
led.c
***************************************************************************************************************************8
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <mach/hardware.h>
#include <linux/miscdevice.h>
#define LIGHT_ON 0X01
#define LIGHT_OFF 0X02
#define gpbcon S3C2410_GPBCON
#define gpbdat S3C2410_GPBDAT
#define gpbup S3C2410_GPBUP
#define led1 0x01
#define led2 0x02
#define led3 0x04
#define led4 0x08
#define ledall 0x0f
#define led_on_1 ~(1<<5)
#define led_on_2 ~(1<<6)
#define led_on_3 ~(1<<7)
#define led_on_4 ~(1<<8)
#define led_on_all (~(1<<5) & ~(1<<6) & ~(1<<7) & ~(1<<8))
#define led_off_1 (1<<5)
#define led_off_2 (1<<6)
#define led_off_3 (1<<7)
#define led_off_4 (1<<8)
#define led_off_all ((1<<5) | (1<<6) | (1<<7) | (1<<8))
#define DEVICE_NAME “linux_led”
MODULE_AUTHOR(“xiaoheng”);
inline void light1_on(void)
{
writel(led_on_1 & readl(gpbdat), gpbdat);
}
inline void light1_off(void)
{
writel(led_off_1 | readl(gpbdat), gpbdat);
}
inline void light2_on(void)
{
writel(led_on_2 & readl(gpbdat), gpbdat);
}
inline void light2_off(void)
{
writel(led_off_2 | readl(gpbdat), gpbdat);
}
inline void light3_on(void)
{
writel(led_on_3 & readl(gpbdat), gpbdat);
}
inline void light3_off(void)
{
writel(led_off_3 | readl(gpbdat), gpbdat);
}
inline void light4_on(void)
{
writel(led_on_4 & readl(gpbdat), gpbdat);
}
inline void light4_off(void)
{
writel(led_off_4 | readl(gpbdat), gpbdat);
}
inline void lightall_on(void)
{
writel(led_on_all & readl(gpbdat), gpbdat);
}
inline void lightall_off(void)
{
writel(led_off_all | readl(gpbdat),gpbdat);
}
int light_open(struct inode* inode, struct file* filp)
{
printk(“myled open NOW!”);
writel(((1<<10) | (1<<12) | (1<<14) | (1<<16)) | readl(gpbcon), gpbcon);
lightall_on();
return 0;
}
int light_release(struct inode* inode, struct file* filp)
{
lightall_off();
printk(“myled close NOW!”);
return 0;
}
int light_ioctl(struct inode* inode, struct file* filp, unsigned int cmd,unsigned long t)
{
switch(cmd)
{
case LIGHT_ON:
if (t == ledall)
lightall_on();
else
{
if (t & led1) {light1_on(); printk(“led1_on
“);}
if (t & led2) {light2_on(); printk(“led2_on
“);}
if (t & led3) {light3_on(); printk(“led3_on
“);}
if (t & led4) {light4_on(); printk(“led4_on
“);}
}
break;
case LIGHT_OFF:
if (t == ledall)
lightall_off();
else
{
if (t & led1) {light1_off(); printk(“led1_off
“);}
if (t & led2) {light2_off(); printk(“led2_off
“);}
if (t & led3) {light3_off(); printk(“led3_off
“);}
if (t & led4) {light4_off(); printk(“led4_off
“);}
}
break;
default:
return -ENOTTY;
}
return 0;
}
struct file_operations light_fops = {
.owner = THIS_MODULE,
.ioctl = light_ioctl,
.open = light_open,
.release = light_release,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &light_fops,
};
int light_init(void)
{
int ret;
printk(“my led init NOW
“);
ret = misc_register(&misc);
printk(DEVICE_NAME”initialized
“);
return ret;
}
void light_cleanup(void)
{
printk(“myled OVER
“);
misc_deregister(&misc);
}
module_init(light_init);
module_exit(light_cleanup);
MODULE_LICENSE(“Dual BSD/GPL”);
*******************************************************************************************************************
2.测试程序
ledtest.c
****************************************************************************************************
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define LED_ON 0x01
#define LED_OFF 0x02
void delay()
{
unsigned int i, j;
for (i = 0; i < 0xf; i++)
for (j = 0; j < 0xff; j++)
;
}
int main(int argc, char **argv)
{
int fd;
int i = 2;
unsigned long led = 0;
if (argc < 3)
{
printf(“usage: led [on/off] [led1|led2|led3|led4]
“);
return 0;
}
fd = open(“/dev/linux_led”, 0);
while(i < argc)
{
if (!strcmp(argv[i], “led1”))
led += 1;
else if (!strcmp(argv[i], “led2”))
led += 2;
else if (!strcmp(argv[i], “led3”))
led += 4;
else if (!strcmp(argv[i], “led4”))
led += 8;
i++;
}
printf(“The led is %d
“, led);
if(!strcmp(argv[1], “on”))
{
while(1)
{
//delay();
ioctl(fd, LED_ON, led);
//printf(“The option is on!
“);
}
}
else if (!strcmp(argv[1], “off”))
{
while(1)
{
//delay();
ioctl(fd, LED_OFF, led);
//printf(“The option is off!
“);
}
}
else
printf(“the led option is on or off !”);
close(fd);
return 0;
}
**************************************************************************************************************8
3.Makefile
obj-m:=led.o
KDIR:=/home/xiaoheng/Desktop/2.6.30.4/opt/EmbedSky/linux-2.6.30.4
all:
make -C $(KDIR) M=$(shell pwd) modules
clean:
make -C $(KDIR) M=$(shell pwd) clean