bsp资料
在其他的驅動程序中可以透過下步驟控制GPIO :
在驅動程序中加入#inlcude <linux/gpio.h>
| 依據 arch\arm\mach-nuc970\inlcude\mach\gpio.h 決定使用哪個GPIO |
| 以NUC970_PC7為例子如下: |
設定輸入模式: | gpio_direction_input(NUC970_PC7); |
設定輸出模式和輸出值:gpio_direction_output(NUC970_PC7,1);
設定輸出high: gpio_set_value(NUC970_PC7, 1 );
設定輸出low: gpio_set_value(NUC970_PC7, 0 );
取值: gpio_get_value(NUC970_PC7);
確認GPIO是否正在使用: gpio_request(NUC970_PC7, "NUC970_PC7");
取得GPIO 中斷號碼 : gpio_to_irq(NUC970_PC7);
drv_led.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-gcr.h>
#include <mach/irqs.h>
#include <linux/fs.h>
#include <linux/cdev.h>
MODULE_LICENSE("GPL");
#define LED_MAJOR 200 /* 主设备号 */
#define LED_NAME "led" /* 设备名字 */
#define LEDOFF 0 /* 关灯 */
#define LEDON 1 /* 开灯 */
static int nuc977_led_open(struct inode *ino, struct file *file)
{
return 0;
}
static int nuc977_led_release(struct inode *ino, struct file *file)
{
return 0;
}
/*
static long nuc977_led_ioctl(struct file *file, unsigned int command , unsigned long arg)
{
int val;
unsigned int cmd=*((unsigned int *)command);
if (cmd==0)
{
printk(KERN_INFO "nuc977_led_ioctl cmd=0\n");
gpio_set_value(NUC970_PB0, 0);
}
else
{
printk(KERN_INFO "nuc977_led_ioctl cmd=1\n");
gpio_set_value(NUC970_PB0, 1);
}
return 0;
}
*/
static long nuc977_led_ioctl( struct file *files, unsigned int cmd, unsigned long arg)
{
printk("cmd is %d,arg is %d \n",cmd,(unsigned int)(arg));
switch(cmd)
{
case LEDOFF:
{
printk(KERN_INFO "LEDOFF \n");
gpio_set_value(NUC970_PB0, 0);
break;
}
case LEDON:
{
printk(KERN_INFO "LEDON \n");
gpio_set_value(NUC970_PB0, 1);
break;
}
}
}
static struct file_operations nuc977_led_fops = {
.owner = THIS_MODULE,
.open = nuc977_led_open,
.release = nuc977_led_release,
.unlocked_ioctl = nuc977_led_ioctl,
};
static int __init nuc977_led_init(void)
{
int ret;
u32 val = 0;
ret=register_chrdev(LED_MAJOR,LED_NAME,&nuc977_led_fops);
if(ret < 0){
printk("register nuc977_led_init failed!\r\n");
return -EIO;
}
ret = gpio_request(NUC970_PB0,"NUC970_PB0");
if(ret < 0){
printk(KERN_EMERG "gpio_request NUC970_PB0 failed!\n");
return ret;
}
gpio_direction_output(NUC970_PB0,1);
printk(KERN_INFO "nuc977_led_init module initialized\n");
return 0;
}
static void __exit nuc977_led_exit(void)
{
/* 注销字符设备驱动 */
unregister_chrdev(LED_MAJOR, LED_NAME);
//gpio_free(NUC970_PB0);
printk(KERN_INFO "nuc977_led_exit module exited\n");
}
module_init(nuc977_led_init);
module_exit(nuc977_led_exit);
MODULE_LICENSE("GPL");
Makefile
obj-m := drv_led.o
PWD := $(shell pwd)
KDIR ?= /home/hbin/nuc977_bsp/nuc970bsp/linux-3.10.x
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf .*.cmd *.o *.mod.c *.ko
app测试程序 app_led.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define IOCTL_LED_ON 1
#define IOCTL_LED_OFF 0
int main(int argc, char **argv)
{
int fd = -1;
fd = open("/dev/led", 0); // 打开设备
if (fd < 0) {
printf("Can't open /dev/led\n");
return -1;
}
if (!strcmp(argv[1], "on")) {
ioctl(fd, IOCTL_LED_ON, 0); // 点亮它
} else if (!strcmp(argv[1], "off")) {
ioctl(fd, IOCTL_LED_OFF, 0); // 熄灭它
}
close(fd);
return 0;
}
文件传到ubuntu16.04下
先编译drv_led.c
到文件目录下执行make
编译测试文件app_led.c
到文件目录下执行 arm-linux-gcc app_led.c -o app_led
开发板上电 secureCRT调试
挂载nfs文件系统
~ # ifconfig eth0 192.168.0.4 up
nuc970-emac0 nuc970-emac0: eth0 is OPENED
~ # mount -t nfs -o nolock 192.168.0.199:/home/hbin/nfs /mnt
~ # cd /mnt
~ # cd /mnt
/mnt # ls
app driver rootfs_hb
/mnt # cd driver/
/mnt/driver # ls
drv_hello drv_led
/mnt/driver # cd drv_led/
/mnt/driver/drv_led # ls
Makefile built-in.o drv_led.ko drv_led.mod.o modules.order
Module.symvers drv_led.c drv_led.mod.c drv_led.o
/mnt/driver/drv_led # cp drv_led.ko /lib/modules/
/mnt/driver/drv_led # cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
29 fb
90 mtd
128 ptm
136 pts
180 usb
189 usb_device
253 ubi0
254 bsg
Block devices:
1 ramdisk
259 blkext
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
加载模块驱动
/mnt/driver/drv_led # insmod drv_led.ko
nuc977_led_init module initialized
/mnt/driver/drv_led # cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
29 fb
90 mtd
128 ptm
136 pts
180 usb
189 usb_device
200 led
253 ubi0
254 bsg
Block devices:
1 ramdisk
259 blkext
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
创建节点
/mnt/driver/drv_led # mknod /dev/led c 200 0
/mnt/driver/drv_led # ls /dev
bus ram14 tty24 tty50
console ram15 tty25 tty51
cpu_dma_latency ram2 tty26 tty52
fb0 ram3 tty27 tty53
full ram4 tty28 tty54
kmem ram5 tty29 tty55
kmsg ram6 tty3 tty56
led ram7 tty30 tty57
mdev.seq ram8 tty31 tty58
mem ram9 tty32 tty59
mtd0 random tty33 tty6
mtd0ro tty tty34 tty60
mtd1 tty0 tty35 tty61
mtd1ro tty1 tty36 tty62
mtd2 tty10 tty37 tty63
mtd2ro tty11 tty38 tty7
mtdblock0 tty12 tty39 tty8
mtdblock1 tty13 tty4 tty9
mtdblock2 tty14 tty40 ttyS0
network_latency tty15 tty41 ubi0
network_throughput tty16 tty42 ubi0_0
null tty17 tty43 ubi_ctrl
ptmx tty18 tty44 urandom
ram0 tty19 tty45 vcs
ram1 tty2 tty46 vcs1
ram10 tty20 tty47 vcsa
ram11 tty21 tty48 vcsa1
ram12 tty22 tty49 zero
ram13 tty23 tty5
/mnt/driver/drv_led # lsmod
drv_led 1116 0 - Live 0xbf000000 (O)
/mnt/driver/drv_led # ls -l /dev/led
crw-r--r-- 1 root root 200, 0 Jan 1 00:03 /dev/led
测试app程序,检测开发板上的pb0的电平,观察led
/mnt # ls
app driver rootfs_hb
/mnt # cd app/
/mnt/app # ls
app_led app_led.c helloworld helloworld.c
/mnt/app # ./app_led on
cmd is 1,arg is 0
LEDON
/mnt/app # ./app_led off
cmd is 0,arg is 0
LEDOFF
实测成功。