Smart210学习记录----beep linux字符设备驱动
今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈。。。但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,,
还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决方法,但是我还是没看懂,只能慢慢找,,,
我在insmod字符设备是,出现了一下提示信息
这里只列出主要部分:
Unable to handle kernel NULL pointer dereference at virtual address pgd = c0004000 [] *pgd= Internal error: Oops: [#] Modules linked in: cirrus CPU: PC is at dequeue_task+0xc/0x78 LR is at deactivate_task+0x38/0x44 pc : [ <c0039c44>] lr : [ <c003a02c>] Not tainted sp : c0205cc4 ip : c0205cd4 fp : c0205cd0 r10: 0000038d r9 : 72b90480 r8 : c020719c r7 : c0206998 r6 : 0000000a r5 : c0204000 r4 : c0206998 r3 : r2 : r1 : r0 : c0206998 Flags: nZCv IRQs off FIQs on Mode SVC_32 Segment kernel Control: C000717F Table: 33B84000 DAC: 0000001D Process swapper (pid: , stack limit = 0xc0204190) Stack: (0xc0205cc4 to 0xc0206000) 5cc0: c0205ce4 c0205cd4 c003a02c c0039c48 0000038d c0205d20 c0205ce8 5ce0: c01d52c4 c003a004 c0205d84 c02069cc 01312d00 c0206b40 0005f5d6 c0204000 5d00: 0000000a c0205d24 c020719c c0205d60 c0205d24 c01d5b24
在网上查询可知,这是因为驱动中出现了空指针,,,,可是作为一个初学者,看了好几篇解决办法,感觉像是对牛弹琴,,,还是不会,,只能在驱动中慢慢找,不过还是被我给找到了,O(∩_∩)O
一个解决办法的网址:http://mengren425.blog.163.com/blog/static/56903931201525502222/
以下是beep驱动程序:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/device.h> #include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h> #define BEEPNAME "mybeep"
static int beepmajor = ; #define BEEPON 1
#define BEEPOFF 0 static struct class* my_beep_class;
static struct device* my_beep_device; struct beep_device {
struct cdev beep_dev;
unsigned char value;
}; struct beep_device* beep_device; static int my_beep_open(struct inode *node, struct file *filep)
{
gpio_request(S5PV210_GPD0(),BEEPNAME);
s3c_gpio_cfgpin(S5PV210_GPD0(), S3C_GPIO_OUTPUT);
gpio_set_value(S5PV210_GPD0(), );
return ;
} static int my_beep_close(struct inode * inode,struct file * file)
{
return ;
} static long my_beep_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
case BEEPON:
printk("beep on\n");
beep_device->value = ;
gpio_set_value(S5PV210_GPD0(), );
break; case BEEPOFF:
printk("beep off\n");
beep_device->value = ;
gpio_set_value(S5PV210_GPD0(), );
break; default:
return -EUNATCH;
}
return ;
} struct file_operations beep_ops = {
.owner = THIS_MODULE,
.unlocked_ioctl = my_beep_ioctl,
.open = my_beep_open,
.release = my_beep_close,
}; static void beep_setup_cdev(struct cdev *dev, int minor,struct file_operations *fops)
{
int err;
dev_t deno;
deno = MKDEV(beepmajor, minor);
cdev_init(&beep_device->beep_dev, &beep_ops);
beep_device->beep_dev.owner = THIS_MODULE;
beep_device->beep_dev.ops = &beep_ops;
err = cdev_add(&beep_device->beep_dev, deno, );
if(err) {
printk("beep cdev_add error");
}
} static int __init mybeep_init(void)
{
dev_t deno;
deno = MKDEV(beepmajor, ); if(beepmajor) {
register_chrdev_region(deno, , BEEPNAME);
printk(KERN_EMERG"beep major is %d\n", beepmajor);
} else {
if (alloc_chrdev_region(&deno, , , BEEPNAME))
printk(KERN_EMERG"alloc_chrdev_region error\n");
beepmajor = MAJOR(deno);
printk("beep major is %d\n", beepmajor);
} beep_device = kmalloc(sizeof(struct beep_device), GFP_KERNEL);
if(!beep_device) {
printk("beep kmalloc error\n");
}
memset(beep_device, , sizeof(struct beep_device)); beep_setup_cdev(&beep_device->beep_dev, , &beep_ops); my_beep_class= class_create(THIS_MODULE, BEEPNAME);
if(IS_ERR(my_beep_class)) {
printk(KERN_EMERG"class_create error\n");
} my_beep_device= device_create(my_beep_class, NULL, deno, NULL, "mybeep");
if(IS_ERR(my_beep_device)) {
printk(KERN_EMERG"device_create error\n");
}
return ;
} static void __exit mybeep_exit(void)
{
unregister_chrdev_region(MKDEV(beepmajor, ), );
cdev_del(&beep_device->beep_dev);
device_unregister(my_beep_device);
class_destroy(my_beep_class);
} MODULE_LICENSE("Dual BSD/GPL");
module_init(mybeep_init);
module_exit(mybeep_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> #define BEEPON 1
#define BEEPOFF 0 int main(void)
{
int dev_fd;
int i ;
dev_fd = open("/dev/mybeep", O_RDWR | O_NONBLOCK);
if (dev_fd == -) {
printf ("Can't open /dev/mybeep\n");
exit();
} ioctl(dev_fd, BEEPON, );
for(i = ; i > ; i ++);
ioctl(dev_fd, BEEPOFF, );
close(dev_fd);
return ;
}
Smart210学习记录----beep linux字符设备驱动的更多相关文章
- (57)Linux驱动开发之三Linux字符设备驱动
1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是: ...
- 深入理解Linux字符设备驱动
文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...
- Linux字符设备驱动实现
Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...
- Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...
- Linux字符设备驱动基本结构
1.Linux字符设备驱动的基本结构 Linux系统下具有三种设备,分别是字符设备.块设备和网络设备,Linux下的字符设备是指只能一个字节一个字节读写的设备,不能随机读取设备内存中某一数据,读取数据 ...
- linux字符设备驱动学习笔记(一):简单的字符设备驱动
最近在鼓捣lnux字符设备驱动,在网上搜集的各种关于linux设备驱动的代码和注释,要么是针对2.4的,要么是错误百出,根本就不能运行成功,真希望大家在发博客的时候能认真核对下代码的正确性,特别是要把 ...
- 嵌入式Linux驱动学习之路(十)字符设备驱动-my_led
首先贴上代码: 字符设备驱动代码: /** *file name: led.c */#include <linux/sched.h> #include <linux/signal.h ...
- 一步步理解linux字符设备驱动框架(转)
/* *本文版权归于凌阳教育.如转载请注明 *原作者和原文链接 http://blog.csdn.net/edudriver/article/details/18354313* *特此说明并保留对其追 ...
- linux字符设备驱动--基本知识介绍
一.设备驱动的分类 1.字符设备 字符设备是指那些能一个字节一个字节读取数据的设备,如LED灯.键盘.鼠标等.字符设备一般需要在驱动层实现open().close().read().write().i ...
随机推荐
- 在单元测试中指定log4j的配置文件
在开发过程中,我们会使用到log4j来输出日志,我们希望在单元测试的时候,只看到部分日志信息,或者定义日志输出的级别. 这个时候手工指定log4j的配置文件: 具体做法如下: 定义类如下: i ...
- POJ 1094 拓扑排序
Description: 规定对于一个只有大写字母的字符串是有大小顺序的.如ABCD.即A<B.B<C.C<D.那么问题来了.现在第一行给你n, m代表序列里只会出现前n的 ...
- 小记:使用SharedPreferences存储来设置程序第一次进入欢迎界面,以后不会再进入欢迎界面。
SharedPreferences mSharedPreferences = this.getSharedPreferences(NAME, this.MODE_PRIVATE); boolean f ...
- HDU 1542 线段树+扫描线+离散化
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 给出一个长度为n的数列,请对于每一个数,输出他右边第一个比他大的数。n<=100000.
RT,一个ppt里看到的题,不过没讲做法.百度上基本搜不到.自己想了个做法,理论上可行,复杂度也是O(nlogn). 首先,做一次RMQ,求区间最大值. 对于任意一个数s[i],可以用logn的时间求 ...
- Linux 常用命令杂记
移动光标:h:向左移动j:向下移动k:向上移动l:向上移动 与window 光标移动键功能一致. 常用命令行:shift + ^ 行首shift + $ 行尾ctrl + v 可视模式 , 选择一个范 ...
- WP8.1 Study12:文件压缩与Known Folder(包含SD卡操作)
一.文件压缩 当应用程序保存和加载数据,它可以使用压缩. 1.使用 Windows.Storage.Compression.Compressor 压缩,获得一个Compressor stream. v ...
- winform错误提示 :窗口类名无效(Window class name is not valid)
winfrom 程序在 xp 操作系统上报错提示 窗口类名无效(Window class name is not valid) 解决方法 注释 Program类 里 这句 Application.En ...
- yeild
正在使用cpu的线程,退出,返回等待池,其他优先级相同的线程竞争上岗.
- httplib、urllib、urllib2的区别
Python3.4互联网通讯协议支持 1,webbrowser方便的浏览器容器 2,cgi公共网关接口支持 3,cgitb管理cgi脚本 4,wsgiref WSGI实体和引用实现 5,urlli ...