TI中文支持网
TI专业的中文技术问题搜集分享网站

beaglebone black的GPIO的寄存器驱动

beaglebone black使用的是Angstrom系统,现使用下面的驱动控制GPIO,但编译进内核后,系统启动不了,是什么原因?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#include <asm/io.h>


//#define GPIO0 0x44E07000
//#define GPIO1 0x4804C000
//#define GPIO2 0x481AC000
#define GPIO3 0x481AE000
#define GPIO_OE 0x134
//#define GPIO_DATAIN 0x138
#define GPIO_DATAOUT 0x13c
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194
#define GPIO_CTRL 0x130


#define CONTROL_MODULE 0x44E10000
//#define SPIO_CS1 0x960 //gpio0_6
//#define ECAP0_IN 0x964
#define MCASP0_ACLKH 0x990 //gpio3_17
#define MCASP0_FSX 0x994 //gpio3_15


static struct class *leds_class;
static struct device *leds_class_dev;

int majors;

//struct LEDS{
//volatile unsigned long *gpio_oe;
//volatile unsigned long *gpio_datain;
//volatile unsigned long *gpio_dataout;
//volatile unsigned long *gpio_setdataout;
//volatile unsigned long *gpio_cleardataout;
//volatile unsigned long *gpio_ctrl;
//volatile unsigned long *spio_cs1;
//volatile unsigned long *ecap0_in;
 
//}_leds;

struct LEDS{
volatile unsigned long *gpio_oe;
volatile unsigned long *gpio_datain;
volatile unsigned long *gpio_dataout;
volatile unsigned long *gpio_setdataout;
volatile unsigned long *gpio_cleardataout;
volatile unsigned long *gpio_ctrl;
volatile unsigned long *mcasp0_aclkh;
volatile unsigned long *mcasp0_fsx;

}_leds;
struct LEDS *leds = &_leds;

static int led_open(struct inode *inode , struct file *file)
{
 printk("this is open!\n");
 return 0;
}

static int led_close(struct inode *inode , struct file *file)
{
 printk("this is close!\n");
 return 0;
}

static long led_ioctl(struct file *file , unsigned int cmd , 
 unsigned long arg)
{
 printk("cmd is : %d\n" , cmd);

// switch (cmd)
// {
 
// default:
// break;
// }
 return 0; 
}

static ssize_t led_read(struct file *file , char __user *buf , size_t count , loff_t *pos)
{
 printk("count is : %d\n" , count);
 return 0;
}

static ssize_t led_write(struct file *file , const char __user *buf , size_t count , loff_t *pos)
{

 int val;
 copy_from_user(&val,buf,count);
 printk("val is =%d\n",val);
 if (val==1)
 {
 *(leds->gpio_dataout)&=~((0x1<<6)|(0x1<<7));//设置gpio输出高/低电平

 }
 else
 {
 *(leds->gpio_dataout)|=((0x1<<6)|(0x1<<7));

 }

 return 0;
}

static struct file_operations fops = {
 .owner = THIS_MODULE,
 .open = led_open,
 .release = led_close,
 .unlocked_ioctl = led_ioctl,
 .read = led_read,
 .write = led_write,
};


static int __init test_init(void)
{

 majors = register_chrdev(0, "leds_drvS", &fops); // 注册, 告诉内核
 leds_class = class_create(THIS_MODULE, "ledsdrvS"); //自动创建设备节点
 leds_class_dev= device_create(leds_class, NULL, MKDEV(majors, 0), NULL, "ledsS");


 leds->gpio_oe = (volatile unsigned long *)ioremap(GPIO3 + GPIO_OE , sizeof(volatile unsigned long ));
 //leds->gpio_datain = (volatile unsigned long *)ioremap(GPIO3 + GPIO_DATAIN, sizeof(volatile unsigned long ));
 //leds->gpio_dataout = (volatile unsigned long *)ioremap_nocache(GPIO3 + GPIO_DATAOUT, sizeof(volatile unsigned long ));
 leds->gpio_dataout = (volatile unsigned long *)ioremap(GPIO3 + GPIO_DATAOUT, sizeof(volatile unsigned long ));
 leds->gpio_setdataout =( volatile unsigned long *)ioremap(GPIO3 + GPIO_SETDATAOUT, sizeof(volatile unsigned long ));
 leds->gpio_cleardataout = (volatile unsigned long *)ioremap(GPIO3 + GPIO_CLEARDATAOUT , sizeof(volatile unsigned long ));
 leds->gpio_ctrl=(volatile unsigned long *)ioremap(GPIO3+GPIO_CTRL,sizeof(volatile unsigned long ));
 leds->mcasp0_aclkh=(volatile unsigned long *)ioremap(CONTROL_MODULE+MCASP0_ACLKH,sizeof(volatile unsigned long ));
 leds->mcasp0_fsx=(volatile unsigned long *)ioremap(CONTROL_MODULE+MCASP0_FSX,sizeof(volatile unsigned long ));
 printk("insmod the leds module!\n");

 /*
 *配置相关引脚的pin_mux模式;
 *配置相关寄存器;
 *首先是寄存器OE,输出使能;设置0为输出使能;
 *其次是寄存器SETDATAOUT,设置允许输出位;设置1为允许;
 *最后是寄存器DATAOUT,设置输出高低电平;
 */

 *(leds->mcasp0_aclkh)|=(0x7);
 *(leds->mcasp0_fsx)|=(0x7);
 *(leds->gpio_ctrl)&=~(0x1);
 
 
 *(leds->gpio_oe) &= ~((0x1<<6)|(0x1<<7));
 *(leds->gpio_setdataout) |= ((0x1<<6)|(0x1<<7));

// *(leds->gpio_datain) |= ((0x1<<6)|(0x1<<7));
// *(leds->gpio_datain) &= ~((0x1<<6)|(0x1<<7));
 
 *(leds->gpio_dataout) |= ((0x1<<6)|(0x1<<7));
 *(leds->gpio_dataout) &= ~((0x1<<6)|(0x1<<7));

 return 0;
}

static void __exit test_exit(void)
{
 unregister_chrdev(majors, "leds_drvS"); // 卸载
 device_unregister(leds_class_dev);
 class_destroy(leds_class);
// *(leds->gpio_cleardataout) |= 0xffffffff;

 iounmap(leds->gpio_oe);
 //iounmap(leds->gpio_datain);
 iounmap(leds->gpio_dataout);
 iounmap(leds->gpio_setdataout);
 iounmap(leds->gpio_cleardataout);
 iounmap(leds->mcasp0_aclkh);
 iounmap(leds->gpio_ctrl);
 iounmap(leds->mcasp0_fsx);

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiaogao");
MODULE_DESCRIPTION("Class test");


Jian Zhou:

用insmode试过么?加载会出问题么?

shanshan wan:

回复 Jian Zhou:

用insmod 时出现Segmentation fault,用dmesg查看,多了以下信息:

[ 96.695288] insmod the leds module!
 [ 96.695310] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa1ae130
 [ 96.703349] Internal error: : 1028 [#1] SMP THUMB2
 [ 96.708387] Modules linked in: gpio(O+)
 [ 96.712423] CPU: 0 Tainted: G W O (3.8.13 #10)
 [ 96.718200] PC is at test_init+0xbf/0x133 [gpio]
 [ 96.723052] LR is at test_init+0xa2/0x133 [gpio]
 [ 96.727900] pc : [<bf8020c0>] lr : [<bf8020a3>] psr: 60000033
 sp : dcf07e58 ip : 00000021 fp : bf800294
 [ 96.739948] r10: 00000000 r9 : bf802001 r8 : bf8002d0
 [ 96.745441] r7 : 00000001 r6 : 00000000 r5 : bf8003e4 r4 : bf800218
 [ 96.752290] r3 : fa1ae130 r2 : 00000027 r1 : 00000001 r0 : 00000000
 [ 96.759144] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA Thumb Segment user
 [ 96.766815] Control: 50c5387d Table: 9c9e0019 DAC: 00000015
 [ 96.772855] Process insmod (pid: 618, stack limit = 0xdcf06240)
 [ 96.779077] Stack: (0xdcf07e58 to 0xdcf08000)
 [ 96.783648] 7e40: bf8001d2 00000000
 [ 96.792231] 7e60: 00000000 bf800288 dcf07f58 c000868d bf802001 00000000 00000001 bf800288
 [ 96.800819] 7e80: bf800288 dcf07f58 00000000 00000001 bf8002d0 dca77780 00000001 c005b553
 [ 96.809422] 7ea0: bf800294 00007fff c0059379 00000000 fa2000d8 0000001c 0000002c c065eacc
 [ 96.818006] 7ec0: bf8003c4 c0398f80 e09f4530 dcf07eec b6f34cc4 20000033 ffffffff c05c6870
 [ 96.826593] 7ee0: 00180011 c000c1b5 e09f6000 b6f4a000 00000248 00000000 00000000 00000000
 [ 96.835176] 7f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 [ 96.843758] 7f20: 00000000 00000000 00000000 00000000 20000033 00000000 b6f44000 b6f34cc4
 [ 96.852365] 7f40: 00000080 c000c824 dcf06000 00000000 00000000 c005b7d7 e09f0000 000062c8
 [ 96.860959] 7f60: e09f3e78 e09f3cb4 e09f60a8 00000404 00000644 00000000 00000000 00000000
 [ 96.869542] 7f80: 0000002b 0000002c 00000015 00000012 00000010 00000000 00000000 00000000
 [ 96.878123] 7fa0: 000210a0 c000c681 00000000 00000000 b6f44000 000062c8 b6f34cc4 00000002
 [ 96.886708] 7fc0: 00000000 00000000 000210a0 00000080 00021088 000062c8 b6f34cc4 00000000
 [ 96.895295] 7fe0: b6e9a890 bea64b98 b6f2d734 b6e9a8a0 60000010 b6f44000 9fefe821 9fefec21
 [ 96.903914] [<bf8020c0>] (test_init+0xbf/0x133 [gpio]) from [<c000868d>] (do_one_initcall+0x61/0xec)
 [ 96.913527] [<c000868d>] (do_one_initcall+0x61/0xec) from [<c005b553>] (load_module+0x10ff/0x1308)
 [ 96.922931] [<c005b553>] (load_module+0x10ff/0x1308) from [<c005b7d7>] (sys_init_module+0x7b/0x8e)
 [ 96.932342] [<c005b7d7>] (sys_init_module+0x7b/0x8e) from [<c000c681>] (ret_fast_syscall+0x1/0x46)
 [ 96.941749] Code: 0207 601a 6823 695b (681a) f022
 [ 96.946775] ---[ end trace 09c7d93bcbc542ab ]---

Jian Zhou:

回复 shanshan wan:

如果是GPIO控制LED的驱动,可以参考SDK06或者SDK07源代码目录下的\drivers\leds\leds-gpio.c来写,你的驱动感觉上有些问题。

shanshan wan:

回复 Jian Zhou:

当把以下注释掉,insmod接没问题,那要怎样才能操作这些寄存器呢?

//*(leds->mcasp0_aclkh)|=(0x7);
// *(leds->mcasp0_fsx)|=(0x7);
// *(leds->gpio_ctrl)&=~(0x1);
 
 
// *(leds->gpio_oe) &= ~((0x1<<6)|(0x1<<7));
// *(leds->gpio_setdataout) |= ((0x1<<6)|(0x1<<7));

//// *(leds->gpio_datain) |= ((0x1<<6)|(0x1<<7));
//// *(leds->gpio_datain) &= ~((0x1<<6)|(0x1<<7));
 
// *(leds->gpio_dataout) |= ((0x1<<6)|(0x1<<7));
 //*(leds->gpio_dataout) &= ~((0x1<<6)|(0x1<<7));

leo chen:

回复 shanshan wan:

可能是地址操作的问题

gpio的配置,使能,以及赋值,最好用系统自带的函数

gpio_set_value();

gpio_request();

等等‘

可参考http://bbs.eeworld.com.cn/thread-327156-1-1.html

赞(0)
未经允许不得转载:TI中文支持网 » beaglebone black的GPIO的寄存器驱动
分享到: 更多 (0)