驱动层代码
/*************************************************************************
> File Name: led_drv.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Sun 26 Feb 2017 04:28:00 AM PST
************************************************************************/
#include<linux/init.h>
#include<linux/module.h>
#include<asm/gpio.h>
#include<mach/iomux-mx6q.h>
#include<linux/cdev.h>
#include<linux/fs.h>
#include<linux/device.h>
#define SABRESD_GPIO_LED4 IMX_GPIO_NR(3, 21)
#define SABRESD_GPIO_LED5 IMX_GPIO_NR(3, 22)
#define SABRESD_GPIO_LED6 IMX_GPIO_NR(3, 23)
#define LED_ON 1
#define LED_OFF 0
struct led_resource {
int gpio;
char *name;
int data;
};
static struct cdev led_cdev;
static dev_t led_dev_id;
static struct class *cls;
static struct led_resource led_res[] = {
[0] = {
.gpio = SABRESD_GPIO_LED4,
.name = "xxdk_led4",
},
[1] = {
.gpio = SABRESD_GPIO_LED5,
.name = "xxdk_led5",
},
[2] = {
.gpio = SABRESD_GPIO_LED6,
.name = "xxdk_led6",
}
};
static int led_open(struct inode* ip,
struct file* fp)
{
int i;
printk("%s\n", __func__);
for(i=0; i<ARRAY_SIZE(led_res); i++) {
gpio_set_value(led_res[i].gpio, 1);
}
return 0;
}
static int led_close(struct inode* ip,
struct file* fp)
{
int i;
printk("%s\n", __func__);
for(i=0; i<ARRAY_SIZE(led_res); i++) {
gpio_set_value(led_res[i].gpio, 0);
}
return 0;
}
static struct file_operations led_fops = {
.owner = THIS_MODULE,
.open = led_open,
.release = led_close
};
static int led_init(void)
{
int i;
alloc_chrdev_region(&led_dev_id, 0, 1, "led@xxdk");
cdev_init(&led_cdev, &led_fops);
cdev_add(&led_cdev, led_dev_id, 1);
for(i=0; i<ARRAY_SIZE(led_res); i++) {
gpio_request(led_res[i].gpio, led_res[i].name);
gpio_direction_output(led_res[i].gpio, 0);
}
cls = class_create(THIS_MODULE, "xxdk");
device_create(cls, NULL, led_dev_id, NULL, "led@xxdk");
return 0;
}
static void led_exit(void)
{
int i;
cdev_del(&led_cdev);
unregister_chrdev_region(led_dev_id, 1);
for(i=0; i<ARRAY_SIZE(led_res); i++) {
gpio_set_value(led_res[i].gpio, 0);
gpio_free(led_res[i].gpio);
}
device_destroy(cls, led_dev_id);
class_destroy(cls);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
应用层代码
/*************************************************************************
> File Name: led_test.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Sun 26 Feb 2017 05:22:08 AM PST
************************************************************************/
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main(void)
{
int fd;
fd = open("/dev/led@xxdk", O_RDWR);
if(fd < 0) {
printf("open led device failed!\n");
return -1;
}
sleep(3);
close(fd);
return 0;
}
编译脚本
#Makefil
ifneq ($(KERNELRELEASE),)
obj-m += led_drv.o
else
KERNEL_DIR = /opt/EmbedSky/TQIMX6/TQ_COREC/linux_IMX6_CoreC_3.0.35_for_Linux
all:
PWD=$(shell pwd)
$(MAKE) -C $(KERNEL_DIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko *.tmp_versions module* Module*
endif