mobile CCTV,mobile surveillance,police body worn cameras

 forgetPW
 registerNow
search
view: 2664|reply: 0
打印 prevThread nextThread

ZT:一个blackfin uClinux驱动问题

[copyURL]

13

主题

373

帖子

2023

积分

vipMem

Rank: 6Rank: 6

积分
2023
jumpTo
owner
poston 2015-11-12 11:19 | authorOnly 回帖奖励 |倒序浏览 |阅读模式
版主 这个错误是什么意思
如题:我在 我的驱动程序里面
static struct spi_driver spi_test_driver = {
.probe = spi_test_probe,
.remove = spi_test_remove,
.driver = {
.name = "netx-spi",
},
};
先 result=spi_register_driver(&spi_test_driver);

然后调用 SPI的驱动spi.c里面的spi_write();怎么会出这个错??
void Mp3WriteRegister(struct spi_device *spi,unsigned char addressbyte, unsigned char highbyte, unsigned char lowbyte)

{

    Mp3DeselectData();

    Mp3SelectControl();//XCS = 0
        unsigned char writebuf[4]={VS_WRITE_COMMAND,addressbyte,highbyte,lowbyte};

    spi_write(spi, writebuf, 4);

    Mp3DeselectControl();

}



[  189.590000] Unable to handle kernel NULL pointer dereference at virtual address 00000130
[  189.600000] pgd = c365c000
[  189.600000] [00000130] *pgd=83b78031, *pte=00000000, *ppte=00000000
[  189.600000] Internal error: Oops: 17 [#1]
[  189.600000] Modules linked in:
[  189.600000] CPU: 0    Tainted: GF        (2.6.23.1-rt5-ptx3-netx2 #63)
[  189.600000] PC is at spi_sync+0x3c/0x6c
[  189.600000] LR is at Mp3WriteRegister+0xcc/0xf4
[  189.600000] pc : [<c0216438>]    lr : [<c01f9980>]    psr: 40000013
[  189.600000] sp : c3c9bd48  ip : c3c9bd78  fp : c3c9bd74
[  189.600000] r10: 00000000  r9 : 00000008  r8 : 00000020
[  189.600000] r7 : 00000000  r6 : 00000000  r5 : c3c9bd7c  r4 : c3c9bd4c
[  189.600000] r3 : c0216468  r2 : c3c9bd50  r1 : c3c9bd7c  r0 : 00000000
[  189.600000] Flags: nZcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[  189.600000] Control: 0005317f  Table: 8365c000  DAC: 00000015
[  189.600000] Process spi_ctrl_test (pid: 953, stack limit = 0xc3c9a260)
[  189.600000] Stack: (0xc3c9bd48 to 0xc3c9c000)
[  189.600000] bd40:                   c3c1de60 00000000 c3c9bd50 c3c9bd50 00000000 c3c9bd7c
[  189.600000] bd60: 00000000 00000004 c3c9bdfc c3c9bd78 c01f9980 c021640c c008560c c3c9bdc4
[  189.600000] bd80: c3c9bdc4 00000000 00000000 c0216468 c3c9bd4c 00000000 00000000 00000000
[  189.600000] bda0: 00000000 00000000 c3c9bdcc 00000000 00000004 00000000 00000000 00000000
[  189.600000] bdc0: 00000000 c3c9bd7c c3c9bd7c 20080002 c3c1de60 00000000 c0588ea0 c3571000
[  189.600000] bde0: c3c1de60 c06b3880 c3c9a000 00000000 c3c9be74 c3c9be00 c01f9a58 c01f98c4
[  189.600000] be00: c3c9be24 c3c9be10 c01c4074 c01c4f58 ffffff9c 00000000 c3c9be3c c3c9be28
[  189.600000] be20: c00978f0 c01c4064 c04fe900 00000000 c3c9be4c c3c9be40 c0097920 c00978b8
[  189.600000] be40: c3c9be84 c3c9be50 c0204044 c005f264 00000000 c0588ea0 c3571000 c3c1de60
[  189.600000] be60: c06b3880 00000000 c3c9be84 c3c9be78 c01f9cfc c01f99b8 c3c9beac c3c9be88
[  189.600000] be80: c00979dc c01f9cec c3c9beac 00000000 c3c1de60 c3571000 c0097930 c3b6aa00
[  189.600000] bea0: c3c9bed4 c3c9beb0 c0092a58 c0097940 c3c1de60 c3c9bf00 c06ad000 00000003
[  189.600000] bec0: ffffff9c 00000000 c3c9bef4 c3c9bed8 c0092c3c c00929a4 00000000 ffffff9c
[  189.600000] bee0: c3c9a000 00000802 c3c9bf64 c3c9bef8 c0092c90 c0092c08 c3c9bf00 c01e568c
[  189.600000] bf00: c3b6aa00 c06b3880 00000013 00000000 00000000 00000101 00000001 00000000
[  189.600000] bf20: c3d96b48 c3d96b40 c3c9a000 00000802 c3c9bf64 c3c9bf40 c00928e0 c00abce8
[  189.600000] bf40: c009e45c 00000803 00000000 c3c1de60 00000802 4001e000 c3c9bf94 c3c9bf68
[  189.600000] bf60: c0092cec c0092c54 c3c9bfa4 c3c9bf78 c00958c4 40023db8 00000000 00000000
[  189.600000] bf80: 00000005 c0027fc8 c3c9bfa4 c3c9bf98 c0092db4 c0092ca4 00000000 c3c9bfa8
[  189.600000] bfa0: c0027e20 c0092da0 40023db8 00000000 000086fc 00000802 4001e000 00000001
[  189.600000] bfc0: 40023db8 00000000 00000000 00000005 00000000 00000000 4013a000 becaed3c
[  189.600000] bfe0: 00000000 becaed20 000084ac 400d244c 60000010 000086fc 00000000 00000000
[  189.600000] Backtrace:
[  189.600000] [<c02163fc>] (spi_sync+0x0/0x6c) from [<c01f9980>] (Mp3WriteRegister+0xcc/0xf4)
[  189.600000]  r7:00000004 r6:00000000 r5:c3c9bd7c r4:00000000
[  189.600000] [<c01f98b4>] (Mp3WriteRegister+0x0/0xf4) from [<c01f9a58>] (VsSineTest+0xb0/0x334)
[  189.600000] [<c01f99a8>] (VsSineTest+0x0/0x334) from [<c01f9cfc>] (spi_codec_open+0x20/0x38)
[  189.600000] [<c01f9cdc>] (spi_codec_open+0x0/0x38) from [<c00979dc>] (chrdev_open+0xac/0x190)
[  189.600000] [<c0097930>] (chrdev_open+0x0/0x190) from [<c0092a58>] (__dentry_open+0xc4/0x1ec)
[  189.600000]  r7:c3b6aa00 r6:c0097930 r5:c3571000 r4:c3c1de60
[  189.600000] [<c0092994>] (__dentry_open+0x0/0x1ec) from [<c0092c3c>] (nameidata_to_filp+0x44/0x4c)
[  189.600000] [<c0092bf8>] (nameidata_to_filp+0x0/0x4c) from [<c0092c90>] (do_filp_open+0x4c/0x50)
[  189.600000]  r4:00000802
[  189.600000] [<c0092c44>] (do_filp_open+0x0/0x50) from [<c0092cec>] (do_sys_open+0x58/0xe8)
[  189.600000]  r5:4001e000 r4:00000802
[  189.600000] [<c0092c94>] (do_sys_open+0x0/0xe8) from [<c0092db4>] (sys_open+0x24/0x28)
[  189.600000]  r8:c0027fc8 r7:00000005 r6:00000000 r5:00000000 r4:40023db8
[  189.600000] [<c0092d90>] (sys_open+0x0/0x28) from [<c0027e20>] (ret_fast_syscall+0x0/0x2c)
[  189.600000] Code: e5850008 e50b2020 e50b7028 e50b2024 (e5903130)

2009-3-25 14:14:28
  
  wlecust06
  
  
  等级:论坛游民
  文章:118
  积分:924
  注册:2008-5-23
[url=][/url]            2

在使用spi驱动前是不是 要
spi_new_device(spi_busnum_to_master(0), &netxdb500_vs1003);
再调用
        result=spi_register_driver(&spi_test_driver);
其中static struct spi_board_info netxdb500_vs1003 =
{
    .modalias    = "VS1003",
    .max_speed_hz    = 500000,
    .bus_num    = 0,
    .chip_select    = 2,
};
还有个不明白的地方 .modailia 是什么意思 属于 哪个模块??

2009-3-25 15:03:40
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             3

http://www.ruijitek.com/bbs/dispbbs.asp?boardID=19&ID=3098&page=1
2009-3-25 15:54:50
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             4

http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=646262&page=0&view=collapsed&sb=5&o=0&fpart=
2009-3-25 17:32:34
  
  wlecust06
  
  
  等级:论坛游民
  文章:118
  积分:924
  注册:2008-5-23
[url=][/url]            5

hn 谢谢
我在driver/char下面的makefile中 加了一句
obj-$(CONFIG_TEST_SPI_DRIVE) += spi_test.o
但是内核运行起来后只看到/proc/devices下面有我的设备但是
/dev下面却没有 每次我要运行我的测试应用程序前都有mknod /dev/spi_test c 240 0这样的命令
怎么样让/dev下面看到我的设备阿???
谢谢了
2009-3-26 8:29:53
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             6

呵呵,你手工mknod这样驱动调试OK啦?
自动的方法,你看看
http://www.ruijitek.com/bbs/dispbbs.asp?boardID=19&ID=1524&page=1
GPIO输出的“驱动+应用程序”实例,
将附件的write_gpio.tar下载后,即可解压。


点击浏览该文件
2009-3-26 9:19:17
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             7

这几天也在看,,补充一点..

其实理解了框架应该很简单的.首先要基本了解下linux的驱动模型,

其次,分两种驱动.一个是master(也就是板子上控制器的驱动). 另一个是device(通过spi接到的设备的驱动,比如接到个nand flash).

对于master驱动, 一般可以挂在platform总线.
device端:
platform_device_register()把控制器注册成一个platform设备.同时把spi_device加到board_info中.

driver端:
platform_driver_register()注册控制器的驱动,在probe中> spi_register_master > scan_board_info > spi_new_device >spi_add_device(). 会把spi_device注册到spi_bus上.当然把spi_device一些结构跟master挂上钩.

对于具体的devcie驱动,得另外写, 比如nandflash.
得注册一个spi_driver到spi_bus,跟我们前面master注册的spi_device匹配.
在probe中 > 注册mtd设备, 并且初始一些函数接口(比如读写,让它调spi层的具体实现函数).


2009-3-27 9:42:23
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             8

认真查看了Document/spi/spi-summary文件,发现里面有这一段话:
The SPI core will autmatically attempt to bind this driver to any SPI
device whose board_info gave a modalias of "CHIP".

比如你的SLAVE DEVICES 定义为:
static struct ads7846_platform_data ads_info = {
.vref_delay_usecs = 100,
.x_plate_ohms = 580,
.y_plate_ohms = 410,
};

static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "ads7846",
.platform_data = &ads_info,
.mode = SPI_MODE_0,
.irq = GPIO_IRQ(31),
.max_speed_hz = 120000 /* max sample rate at 3V */ * 16,
.bus_num = 1,
.chip_select = 0,
},
};

那你的驱动的device可以这样定义:
static struct device_driver CHIP_driver = {
.name = "CHIP",
.bus = &spi_bus_type,
.probe = CHIP_probe,
.remove = __exit_p(CHIP_remove),
.suspend = CHIP_suspend,
.resume = CHIP_resume,
};

关键是这里的“CHIP”要和从设备定义的名字相同,因为内核就是*这个来匹配的,再一次引用文档的话:
The SPI core will autmatically attempt to bind this driver to any SPI
device whose board_info gave a modalias of "CHIP".

所以我把从设备的定义改为:
static struct spi_board_info s3c2410_spi_board[] = {
[0] = {
.modalias = "ads7846", //注意:只要和驱动的名字相同就行,改驱动下的名字也是可以的
.platform_data = NULL,
.irq = IRQ_EINT1,
.chip_select = 1,
.max_speed_hz = 500*1000,
},
};
就行了^_^


看来要提高E文的水平,多看一下内核自带的文档才行~
编辑者: luofuchong (07-04-24 23:33)
2009-3-27 9:42:42
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             9

不被调用的一个原因是spi_register_driver没有找到与 .driver.name 相匹配的资源定义,可能是遗忘了在platform_device []中添加 &s3c_device_spi0 以导出你要使用的资源。往回移植的工作因为新版本具有的特性旧版本上没有,尽量用diff -U 找出相同功能文件的不同点,可以加快解决问题的速度。

2009-3-27 9:43:02
  
  huangning
  
  
  等级:超级版主
  文章:1468
  积分:3269
  注册:2007-6-6
[url=][/url]             10

既然这样,让我们来看看你的第一个问题吧。

如果你需要使用spi驱动的接口,不是去修改驱动的实现代码,因为它只负责完成spi的硬件交互功能。

你使用spi功能的代码只需要用到spi.h中定义的方法就可以了,这就是linux driver layers framework的可人之处。

我们通过一个简单的例子来实际理解一下:

#include <linux/config.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>

#define TEST_REG 0x02

static int test_read_reg(struct spi_device *spi, int reg)
{
char buf[2];
buf[0] = reg << 2;
buf[1] = 0;
spi_write_then_read(spi, buf, 2, buf, 2);
return buf[1] << 8 | buf[0];
}

static int spi_test_probe(struct spi_device *spi)
{
printk("TEST_REG: 0x%02x\n", test_read_reg(spi, TEST_REG));
return 0;
}

static int spi_test_remove(struct spi_device *spi)
{
return 0;
}

static struct spi_driver spi_test_driver = {
.probe = spi_test_probe,
.remove = spi_test_remove,
.driver = {
.name = "testHW",
},
};

static int __init spi_test_init(void)
{
return spi_register_driver(&spi_test_driver);
}

static void __exit spi_test_exit(void)
{
spi_unregister_driver(&spi_test_driver);
}

module_init(spi_test_init);
module_exit(spi_test_exit);

MODULE_DESCRIPTION("spi device test");
MODULE_LICENSE("GPL");


在这个驱动中,你只需要用spi_register_driver向系统进行注册,就可以让系统用你指定的与 .name 相匹配的硬件交互代码
去执行你的读写请求。

几乎在所有与spi相关的函数中都会用到struct spi_device *spi这个指针,probe函数正好把这个指针传给你,保存好这个指针,你就可以在驱动的任何地方通过他去处理与spi设备相关的操作。

ZT by panjet

reply

使用道具 report

creditRule

QQ|wireless surveillance

GMT+8, 2024-4-19 20:23 , Processed in 0.080081 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

QuickReply backToTop BackToList