linux内核的水很深,分享一下关于__raw_writel()出错的问题

本文探讨了在Linux内核驱动开发过程中遇到的一个问题,即使用__raw_writel函数导致的错误。作者在尝试加载和卸载PWM驱动时,发现错误源于该函数。经过调试,排除了地址定义错误的可能性,但具体原因仍未解决。最后通过修改代码,错误得以消除,提示读者内核开发的复杂性,鼓励深入讨论。
摘要由CSDN通过智能技术生成
先上一个测试代码来说明一下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/io.h>

#define at91_pwm_read(reg)                  __raw_readl(reg)   
#define at91_pwm_write(reg, val)            __raw_writel((val), reg)

#define PWMC_BASE 0xfffb8000
#define PWM_MR_OFF              0x00000000    ///< PWM Mode Register offset.
//#define PWM_MR     __phys_to_pfn(PWMC_BASE + PWM_MR_OFF) ///< PWM Mode Register.  //这里是关键
#define PWM_MR     (PWMC_BASE + PWM_MR_OFF) ///< PWM Mode Register.

static int __init my_led_init(void)
{
	unsigned long value;
	

	
	value = at91_pwm_read(PWM_MR);
	printk("0xfffb8000 = %x", value);
	at91_pwm_write(PWM_MR, 0xA2); 
	value = at91_pwm_read(PWM_MR);
	printk("0xfffb8000 = %x", value);
	
	at91_set_gpio_output(AT91_PIN_PD15, 0);
	at91_set_gpio_value(AT91_PIN_PD15, 0);
    return 0;
}
static void __exit my_led_exit(void)
{
   
	//at91_set_gpio_output(AT91_PIN_PD15, 0);
	at91_set_gpio_value(AT91_PIN_PD15, 1);

    return;
}

module_init(my_led_init)
module_exit(my_led_exit)

MODULE_LICENSE("GPL");


其实这就是一个简单的加载和卸载驱动的模块,因为我昨天做的pwm的驱动下载到开发板的时候总是报错,在代码里面找了很久都没有找到原因,

今天早上我把模块单独拿出来试试,最后确定是__raw_writel和__raw_readl的原因, 开始以为是我定义的地址出错了.后来调试了很久还是没有找到.上一个出错的信息;

<1>Unable to handle kernel paging request at virtual address fffb8000
pgd = c6c14000
[fffb8000] *pgd=705a5031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
Modules linked in: myled(+) [last unloaded: myled]
CPU: 0    Not tainted  (2.6.30 #28)
PC is at my_led_init+0x10/0x58 [myled]
LR is at do_one_initcall+0x4c/0x17c
pc : [<bf00f010>]    lr : [<c01222d4>]    psr: 60000013
sp : c6c2df08  ip : 00000000  fp : bec68c94
r10: 00000000  r9 : c6c2c000  r8 : c0483140
r7 : bf00f000  r6 : 001e5060  r5 : bf00c01c  r4 : fffb8fff
r3 : 00000000  r2 : c6c2c000  r1 : 00000001  r0 : bf00f000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 76c14000  DAC: 00000015
Process insmod (pid: 450, stack limit = 0xc6c2c268)
Stack: (0xc6c2df08 to 0xc6c2e000)
df00:                   00000000 00000ae4 bf00c320 c01222d4 c888e2ce c79cf420 
df20: c888ea10 00000016 00000018 c888e3d0 bf00c32c c888e768 c6c14000 00000000 
df40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
df60: 00000ae4 bf00c320 001e5060 00000ae4 bf00c320 001e5060 00000000 c0122ea8 
df80: 00000000 c0157f24 c7815740 ffffffff 001e44c0 00000ae4 bec68db1 000002ec 
dfa0: 00000080 c0122d00 00000ae4 bec68db1 001e5060 00000ae4 001e5050 bec68db1 
dfc0: 00000ae4 bec68db1 000002ec 00000080 00000000 00000002 00000000 bec68c94 
dfe0: bec68ab8 bec68aa8 0002cdbc 00009300 20000010 001e5060 00000000 00000000 
[<bf00f010>] (my_led_init+0x10/0x58 [myled]) from [<c01222d4>] (do_one_initcall+0x4c/0x17c)
[<c01222d4>] (do_one_initcall+0x4c/0x17c) from [<c0157f24>] (sys_init_module+0x90/0x194)
[<c0157f24>] (sys_init_module+0x90/0x194) from [<c0122d00>] (ret_fast_syscall+0x0/0x2c)
Code: e92d4030 e59f5048 e3e04a47 e24dd004 (e5141fff) 
---[ end trace 55d98dffd0e5be81 ]---
Segmentation fault
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值