本文代码转载请注明转自http://blog.csdn.net/jinatom/article/details/7756694
小车驱动
//cardev.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include</home/linux-3.0.1/arch/arm/mach-s3c64xx/include/mach/gpio.h>
#include </home/linux-3.0.1/arch/arm/plat-samsung/include/plat/gpio-cfg.h>
#include "cardev.h"
static unsigned long CAR[] =
{
S3C64XX_GPC(0),
S3C64XX_GPC(1),
};
static long s3c6410_car_ioctl(
struct file *filp,
unsigned int cmd,
unsigned long arg)
{
//check the cmd
if(_IOC_TYPE(cmd) != CAR_CMD_MAGIC)
{
return -EINVAL;
}
if((_IOC_NR(cmd) + 1) > CAR_CMD_MAX)
{
return -EINVAL;
}
//check the arg
if (arg > 2)
{
return -EINVAL;
}
switch(cmd)
{
case CAR_CMD_ON:
gpio_set_value(CAR[arg],CAR_ON);
printk("CAR is ON\n",arg);
return 0;
case CAR_CMD_LEFT:
gpio_set_value(CAR[0],CAR_ON);
gpio_set_value(CAR[1],CAR_OFF);
printk("TURN LEFT\n",arg);
return 0;
case CAR_CMD_RIGHT:
gpio_set_value(CAR[0],CAR_OFF);
gpio_set_value(CAR[1],CAR_ON);
printk("TURN RIGHT\n",arg);
return 0;
case CAR_CMD_OFF:
gpio_set_value(CAR[arg],CAR_OFF);
printk("CAR is OFF\n",arg);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = s3c6410_car_ioctl,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int s3c6410_car_init(void)
{
int ret;
int i;
//gpio init
for(i = 0;i < 2; i ++)
{
//car[0-1]pull up
s3c_gpio_setpull(CAR[i],S3C_GPIO_PULL_UP);
//car[0-1]config output and turn off all CARS
gpio_direction_output(CAR[i],CAR_OFF);
}
//register micdevice
ret = misc_register(&misc);
printk (DEVICE_NAME"\tinitialized\n");
return ret;
}
static void s3c6410_car_exit(void)
{
misc_deregister(&misc);
printk (DEVICE_NAME"\tremoved\n");
}
module_init(s3c6410_car_init);
module_exit(s3c6410_car_exit);
MODULE_AUTHOR("jinatom");
MODULE_LICENSE("GPL");
头文件
//cardev.h
#ifndef CARDEV_H_
#define CARDEV_H_
#include <linux/ioctl.h>
#define DEVICE_NAME "cardev"
#define CAR_ON 1
#define CAR_OFF 0
//ioctl命令的定义
#define CAR_CMD_MAGIC 'G'
#define CAR_CMD_ON _IOW(CAR_CMD_MAGIC,0,int)
#define CAR_CMD_OFF _IOW(CAR_CMD_MAGIC,1,int)
#define CAR_CMD_LEFT _IOW(CAR_CMD_MAGIC,2,int)
#define CAR_CMD_RIGHT _IOW(CAR_CMD_MAGIC,3,int)
#define CAR_CMD_MAX 2
#endif
makefile文件
obj-m := cardev.o
mymodule-objs:=module
#设置内核地址
KERNELDIR := /home/linux-3.0.1
CC=arm-unknown-linux-gnueabi-gcc
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) -I/home/linux-3.0.1/include/ modules
clean:
@ rm *.o *.ko* *.mod* *.order *.symvers -rf
测试程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "cardev.h"
int main(int argc, char **argv)
{
int on;
int car_no;
int fd;
//check the ags number
if (argc != 3)
{
fprintf(stderr, "please input two args\n");
exit(1);
}
//check the first arg
if (sscanf(argv[1],"%d", &on) != 1 || on < 0 || on > 1)
{
fprintf(stderr, "The first arg can only be 0|1\n");
exit(1);
}
//check the second arg
if (sscanf(argv[2],"%d", &car_no) != 1 || car_no < 0 || car_no > 1)
{
fprintf(stderr, "The second arg can only be 0|1|n");
exit(1);
}
fd = open("/dev/cardev", 0);
if (fd < 0)
{
perror("can not open device car");
exit(1);
}
//exe cmd
if(on == 1)
{
ioctl(fd,CAR_CMD_ON,car_no);
}
else
{
ioctl(fd,CAR_CMD_OFF,car_no);
}
close(fd);
return 0;
}