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");