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: 60000033sp : 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