驱动程序显示加载成功,但是运行测试应用程序后,向设备发数据就出现键盘鼠标无响应,串口端没有打印信息,也不能输入。求助!!!,只能

小北丶 2018-09-20 11:18:39
这是我的驱动程序

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/interrupt.h>

#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/types.h>
#include <linux/errno.h>
/* Standard module information, edit as appropriate */
MODULE_LICENSE("GPL");
MODULE_AUTHOR
("Xilinx Inc.");
MODULE_DESCRIPTION
("mygpio - loadable module template generated by petalinux-create -t modules");

#define DRIVER_NAME "mygpio"

/* Simple example of how to receive command line parameters to your module.
Delete if you don't need them */
unsigned myint = 0xdeadbeef;
char *mystr = "default";

module_param(myint, int, S_IRUGO);
module_param(mystr, charp, S_IRUGO);

struct mygpio_local {
unsigned long mem_start;
unsigned long mem_end;
void __iomem *base_addr;
struct device *dev;
struct cdev cdev;
};
static struct mygpio_local *lp;
struct class *mygpio_class;
static int mygpio_major;
/*文件打开函数*/
static int mygpio_open(struct inode *inode, struct file *filp){
printk("mygpio open success\n");
return 0;
}
/*文件释放函数*/
static int mygpio_release(struct inode *inode, struct file *filp){
printk("mygpio release success\n");
return 0;
}
/*文件写函数*/
static ssize_t mygpio_write(struct file *f, const char __user * buf, size_t len, loff_t * off)
{

int ret;
printk("mygpio start to write.\n");
ret=copy_from_user(lp->base_addr,buf,len);
if(ret!=0){
printk("copy from user failure\n");
return -EFAULT;
}
return len;
}
static long mygpio_ioctl(struct file *filp, unsigned int reg_num, unsigned long arg)
{
printk("reg num is %d,arg is %d\n",reg_num,arg);
iowrite32(arg,lp->base_addr+reg_num*4);
return 0;
}
static ssize_t mygpio_read(struct file *f, char __user * buf, size_t len, loff_t * off)
{
int ret;
printk("mygpio start to read\n");
ret=copy_to_user(buf,lp->base_addr,len);
if(ret!=0){
printk("copy to user failure\n");
return -EFAULT;
}
return len;
}
/*文件操作结构体*/
static const struct file_operations mygpio_fops={
.owner = THIS_MODULE,
.open = mygpio_open,//打开设备函数
.write = mygpio_write,
.read = mygpio_read,
.unlocked_ioctl=mygpio_ioctl,
.release= mygpio_release,//释放设备函数
};
static void mygpio_cdev_setup_cdev(struct mygpio_local *devp, int minor){
int err;
dev_t devno = MKDEV(mygpio_major, minor);/*构造设备号*/
cdev_init(&devp->cdev, &mygpio_fops);/*初始化cdev设备*/
devp->cdev.owner = THIS_MODULE;/*使驱动程序属于该模块*/
devp->cdev.ops = &mygpio_fops;/*cdev连接file_operations指针*/
err = cdev_add(&devp->cdev, devno, 1);/*将cdev注册到系统中*/
if (err)
printk(KERN_NOTICE "mygpio: error in cdev_add()\n");
}
static int mygpio_probe(struct platform_device *pdev)
{
struct resource *r_mem; /* IO mem resources */
struct device *dev = &pdev->dev;
dev_t devno;
int rc = 0;
int ret;
dev_info(dev, "Device Tree Probing\n");
/* Get iospace for the device */
r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r_mem) {
dev_err(dev, "invalid address\n");
return -ENODEV;
}
lp = (struct mygpio_local *) kmalloc(sizeof(struct mygpio_local), GFP_KERNEL);
if (!lp) {
dev_err(dev, "Cound not allocate mygpio device\n");
return -ENOMEM;
}
dev_set_drvdata(dev, lp);
lp->mem_start = r_mem->start;
lp->mem_end = r_mem->end;

if (!request_mem_region(lp->mem_start,
lp->mem_end - lp->mem_start + 1,
DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at %p\n",
(void *)lp->mem_start);
rc = -EBUSY;
goto error1;
}

lp->base_addr = ioremap(lp->mem_start, lp->mem_end - lp->mem_start + 1);
if (!lp->base_addr) {
dev_err(dev, "mygpio: Could not allocate iomem\n");
rc = -EIO;
goto error2;
}


dev_info(dev,"mygpio at 0x%08x mapped to 0x%08x",
(unsigned int __force)lp->mem_start,
(unsigned int __force)lp->base_addr);
ret=alloc_chrdev_region(&devno,0,1,"mygpio");//分配设备号
if(ret<0){
printk("mygpio: allocate devno failed\n");
return ret;
}
mygpio_major=MAJOR(devno);
//用于创建/dev目录下的设备节点
mygpio_class=class_create(THIS_MODULE,"mygpio_class");
if(IS_ERR(mygpio_class)){
printk("mygpio_class: create class error\n");
return -1;
}
lp->dev=device_create(mygpio_class,NULL,devno,NULL,"mygpio");
mygpio_cdev_setup_cdev(lp,0);
return 0;
error2:
release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1);
error1:
kfree(lp);
dev_set_drvdata(dev, NULL);
return rc;
}

static int mygpio_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1);
kfree(lp);
dev_set_drvdata(dev, NULL);
return 0;
}

#ifdef CONFIG_OF
static struct of_device_id mygpio_of_match[] = {
{ .compatible = "xlnx,ww-gpio-1.00.a", },
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(of, mygpio_of_match);
#else
# define mygpio_of_match
#endif


static struct platform_driver mygpio_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = mygpio_of_match,
},
.probe = mygpio_probe,
.remove = mygpio_remove,
};

static int __init mygpio_init(void)
{
printk("<1>Hello module mygpio.\n");
printk("<1>Module parameters were (0x%08x) and \"%s\"\n", myint,
mystr);

return platform_driver_register(&mygpio_driver);
}


static void __exit mygpio_exit(void)
{
platform_driver_unregister(&mygpio_driver);
printk(KERN_ALERT "Goodbye module mygpio.\n");
}

module_init(mygpio_init);
module_exit(mygpio_exit);


这是我的测试应用程序

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
int fd1,fd2;
void dma_data_read(void)
{
char buffer[4096];
int i;
printf("start to read !\n");
read(fd1,&buffer,sizeof(buffer));//从内核空间读出dma传送的数据并保存在buffer中
//打印出保存的数据,验证传输的数据是否正确是否正确
for(i=0;i<4096;i++)
{
printf("buffer[%d]=%d,\n",i,buffer[i]);
}

}
int main(int argc, char **argv)
{
printf("Test start!\n");
int gpiodata;
int Oflags;
int ret;
signal(SIGIO,dma_data_read);
fd1=open("/dev/s2mmdma",O_RDWR);//打开s2mmdma设备
if(fd1<0){
printf("can not open device s2mmdma!\n");
return 0;
}
fd2=open("/dev/mygpio",O_RDWR);//打开mygpio设备
if(fd2<0){
printf("can't open device mygpio!\n");
}
//建立异步通知机制,当dma通道传输完成时,会通过异步通知机制告诉应用程序去读数据
ret=fcntl(fd1,F_SETOWN,getpid());
if(ret<0){
printf("can't fcntl_1!\n");
}
Oflags=fcntl(fd1,F_GETFL);
printf("Oflags is : %d\n",Oflags);
if(Oflags<0){
printf("can't fcntl_2\n");
}
ret=fcntl(fd1,F_SETFL,Oflags | FASYNC);
if(ret<0){
printf("can't fcntl_3\n");
}
//
printf("input gpio data:\n");
scanf("%d",&gpiodata);
ioctl(fd1,1,4096); //第二个参数怎定为1,第三个参数是dma传输的长度 以字节为单位 当把传输的字节长度写入dma相应的寄存器后,dma传输就绪(详见pg021)
//write(fd2,&gpiodata,sizeof(gpiodata));
ioctl(fd2,0,gpiodata);//控制gpio的输出,开始产生数据
sleep(1);
close(fd1);
close(fd2);
return 0;
}

希望得到各位的指点。
...全文
361 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
小北丶 2018-09-21
  • 打赏
  • 举报
回复
引用 2 楼 Dennis_Sck 的回复:
因为加载之后还要启动啊

你没看测试文件当中已经启动了我的设备。
小北丶 2018-09-20
  • 打赏
  • 举报
回复
在打开测试应用程序之前,串口已经打印出驱动加载成功的信息,测试程序打开后,在向gpio发数据之前都是正常,没有出现异常,但是在向gpio发1或0后,就出现linux死机状态,键盘和鼠标无效,串口也不能进行操作。
sunchuquin 2018-09-20
  • 打赏
  • 举报
回复
因为加载之后还要启动啊
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis中,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开的架构无关的公共控件, 以满足该类需求可以通过快速配置来开。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据现,BoneCP是最快的连接池。BoneCP很小,只有四十几K

21,619

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧