先上一个测试代码来说明一下:
#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