基于Linux的ARM与FPGA SPI驱动,中断函数调用spidev_sync_read(),出现错误

TouchLJ 2015-02-26 07:18:19
BUG: scheduling while atomic: spidev_test/1034/0x00010003
Modules linked in: spidev fpga

Pid: 1034, comm: spidev_test
CPU: 0 Tainted: G W (2.6.35.3-571-gcca29a0 #131)
PC is at __setup_irq+0x258/0x378
LR is at mxs_gpio_unmask_irq+0x38/0x40
pc : [<c007c710>] lr : [<c003b944>] psr: 60000013
sp : c7efbd68 ip : c7efbd40 fp : c7efbd94
r10: c7e6b400 r9 : 00000000 r8 : c03fa89c
r7 : 60000013 r6 : 000000bb r5 : c7e6be40 r4 : c03fa87c
r3 : 00000000 r2 : 00000000 r1 : f0018010 r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 0005317f Table: 47f14000 DAC: 00000015
[<c002b044>] (show_regs+0x0/0x50) from [<c003efd8>] (__schedule_bug+0x4c/0x60)
r5:c7efa000 r4:c7efbd20
[<c003ef8c>] (__schedule_bug+0x0/0x60) from [<c02e87f0>] (schedule+0x78/0x36c)
r5:c7efa000 r4:c7cc1cc0
[<c02e8778>] (schedule+0x0/0x36c) from [<c02e91a4>] (schedule_timeout+0x20/0x1f4
)
[<c02e9184>] (schedule_timeout+0x0/0x1f4) from [<c02e8fe0>] (wait_for_common+0x1
04/0x1d4)
r6:c7efbc04 r5:7fffffff r4:c7efa000
[<c02e8edc>] (wait_for_common+0x0/0x1d4) from [<c02e9158>] (wait_for_completion+
0x18/0x1c)
[<c02e9140>] (wait_for_completion+0x0/0x1c) from [<bf0062e0>] (spidev_sync+0xc8/
0xe4 [spidev])
[<bf006218>] (spidev_sync+0x0/0xe4 [spidev]) from [<bf006364>] (fpga_irq+0x68/0x
8c [spidev])
r6:c7e6b400 r5:c7efbc30 r4:00000001
[<bf0062fc>] (fpga_irq+0x0/0x8c [spidev]) from [<c007bbfc>] (handle_IRQ_event+0x
2c/0xfc)
r8:00000001 r7:000000bb r6:00000000 r5:00000000 r4:c7e6be40
[<c007bbd0>] (handle_IRQ_event+0x0/0xfc) from [<c007df38>] (handle_level_irq+0xd
c/0x188)
r7:c03f956c r6:c7e6be40 r5:000000bb r4:c03fa87c
[<c007de5c>] (handle_level_irq+0x0/0x188) from [<c003b9b8>] (mxs_gpio_irq_handle
r+0x6c/0xa0)
r7:c03f956c r6:0000007e r5:000000bb r4:00000001
[<c003b94c>] (mxs_gpio_irq_handler+0x0/0xa0) from [<c0029074>] (asm_do_IRQ+0x74/
0x94)
r7:00000002 r6:000000bb r5:00000000 r4:0000007e
[<c0029000>] (asm_do_IRQ+0x0/0x94) from [<c02eae44>] (__irq_svc+0x44/0x8c)
Exception stack(0xc7efbd20 to 0xc7efbd68)
bd20: 00000000 f0018010 00000000 00000000 c03fa87c c7e6be40 000000bb 60000013
bd40: c03fa89c 00000000 c7e6b400 c7efbd94 c7efbd40 c7efbd68 c003b944 c007c710
bd60: 60000013 ffffffff
r5:f0000000 r4:ffffffff
[<c007c4b8>] (__setup_irq+0x0/0x378) from [<c007c8ec>] (request_threaded_irq+0xb
c/0x104)
[<c007c830>] (request_threaded_irq+0x0/0x104) from [<bf0061d4>] (spidev_open+0x1
0c/0x150 [spidev])
[<bf0060c8>] (spidev_open+0x0/0x150 [spidev]) from [<c00bf39c>] (chrdev_open+0x1
e8/0x208)
r6:c7e6b8c0 r5:c7f2c280 r4:c7a7b128
[<c00bf1b4>] (chrdev_open+0x0/0x208) from [<c00ba584>] (__dentry_open+0x19c/0x2b
8)
r8:c00bf1b4 r7:c7a7b128 r6:c7a7ac00 r5:c7cdbb00 r4:c7f2c280
[<c00ba3e8>] (__dentry_open+0x0/0x2b8) from [<c00ba778>] (nameidata_to_filp+0x48
/0x60)
[<c00ba730>] (nameidata_to_filp+0x0/0x60) from [<c00c6fa4>] (do_last+0x4a8/0x604
)
r4:c7efbed0
[<c00c6afc>] (do_last+0x0/0x604) from [<c00c8c28>] (do_filp_open+0x188/0x4f0)
[<c00c8aa0>] (do_filp_open+0x0/0x4f0) from [<c00ba304>] (do_sys_open+0x64/0xec)
[<c00ba2a0>] (do_sys_open+0x0/0xec) from [<c00ba3c4>] (sys_open+0x24/0x28)
[<c00ba3a0>] (sys_open+0x0/0x28) from [<c0029a00>] (ret_fast_syscall+0x0/0x2c)
...全文
691 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Sir_wang 2015-09-10
  • 打赏
  • 举报
回复
是我啊,WLW,感觉我这问题很大
TouchLJ 2015-03-23
  • 打赏
  • 举报
回复
static ssize_t
spidev_sync(struct spidev_data *spidev, struct spi_message *message)
{
	DECLARE_COMPLETION_ONSTACK(done);	// 声明并初始化一个完成量
	int status;

	message->complete = spidev_complete;		//spi_message上挂接的所有数据段传输完毕时该函数调用函数complete(arg);通知数据传输完成。
	message->context = &done;

	spin_lock_irq(&spidev->spi_lock);
	if (spidev->spi == NULL)
		status = -ESHUTDOWN;
	else
		status = spi_async(spidev->spi, message);		 //调用spi核心中的函数进行数据传输
	spin_unlock_irq(&spidev->spi_lock);

	if (status == 0) {
		wait_for_completion(&done);		//等待完成量被唤醒
		status = message->status;		//获取spi消息传输事务状态
		if (status == 0)
			status = message->actual_length;		 /*返回发送的字节数*/
	}
	return status;
}
自己回复,因为函数中有等待阻塞函数,所以在中断函数中调用会出问题,后发现在linux里,中断处理分为顶半(top half),底半(bottom half),在顶半里处理优先级比较高的事情,要求占用中断时间尽量的短,在处理完成后,就激活底半,有底半处理其余任务,可以执行sleep的操作。使用request_threaded_irq注册中断,可以调用底部中断函数,在里面进行阻塞调用
happy小文字 2015-03-16
  • 打赏
  • 举报
回复
你这直接上这么一段崩溃信息都不知道你这代码逻辑,直接上代码请?
TouchLJ 2015-02-28
  • 打赏
  • 举报
回复
引用 5 楼 Huntercao 的回复:
你的中断是怎么触发的? 能介绍一下你的中断系统和spidev_test之间的关系么?
spidev_test 是应用层程序,在open中注册中断,外部触发中断后读取spi,调用spidev_sync_read()读取spi数据
TouchLJ 2015-02-27
  • 打赏
  • 举报
回复
引用 2 楼 Huntercao 的回复:
你怎么确定是spidev_sync_read()出了问题? 你的spidev_test是怎么调用驱动模块的?
我的中断函数中只有调用spidev_sync_read(),进入中断函数就报错,不调用就没有
TouchLJ 2015-02-27
  • 打赏
  • 举报
回复
引用 1 楼 xuweiwei1860 的回复:
中断处理函数好像有问题
我现在确定问题就是中断函数问题,想知道为什么会报错
曹大夯 2015-02-27
  • 打赏
  • 举报
回复
你怎么确定是spidev_sync_read()出了问题? 你的spidev_test是怎么调用驱动模块的?
fly 100% 2015-02-27
  • 打赏
  • 举报
回复
中断处理函数好像有问题
曹大夯 2015-02-27
  • 打赏
  • 举报
回复
你的中断是怎么触发的? 能介绍一下你的中断系统和spidev_test之间的关系么?

21,597

社区成员

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

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