am335x硬件定时器使用

 

 

在使用am335x硬件定时器的时候,需要操作物理地址,如果直接按照裸跑时操作寄存器的话会报错,Unable to handle kernel paging request at virtual address 44e0007c。

原因是linux系统的时候使用的是虚拟地址,如果需要使用物理地址需要映射到虚拟地址才能操作。需要用到 ioremap() 函数进行地址映射。

Disabling lock debugging due to kernel taint
HR Timer module installing
Unable to handle kernel paging request at virtual address 44e0007c
pgd = cf35c000
[44e0007c] *pgd=00000000
Internal error: Oops: 805 [#1]
Modules linked in: hrtimer_drv(O+)
CPU: 0    Tainted: G           O  (3.2.0 #572)
PC is at my_hrtimer_drv_init+0x38/0xec [hrtimer_drv]
LR is at console_unlock+0x170/0x1fc
pc : [<bf002038>]    lr : [<c003d9a0>]    psr: 60000013
sp : cf6bfe70  ip : cf6bfd78  fp : cf6bfe9c
r10: bf002000  r9 : c006ed54  r8 : 0000001c
r7 : cf6be000  r6 : bf000538  r5 : bf0003d0  r4 : bf0002dc
r3 : 44e00000  r2 : bf000368  r1 : 00000002  r0 : 00000000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: 8f35c019  DAC: 00000015
Process insmod (pid: 1205, stack limit = 0xcf6be2f0)
Stack: (0xcf6bfe70 to 0xcf6c0000)
fe60:                                     bf0003d0 c005f04c fffffffc bf0003d0
fe80: bf0003d0 c0737dc0 cf6be000 0000001c cf6bfef4 cf6bfea0 c00087a4 bf00200c
fea0: c005e72c c0203134 cf6bfedc 00000000 c005f3ac c005e720 00000000 cf6bfec8
fec0: bf0003d0 bf0003d0 cf325700 bf0003d0 bf0003d0 cf325700 00000001 0000001c
fee0: c006ed54 0000029a cf6bffa4 cf6bfef8 c007062c c0008680 bf0003dc c0016464
ff00: 00000000 c006ee7c d090d980 d090e1d0 00000000 bf000418 cf318d40 c05fb728
ff20: 00000000 00000000 00000000 00000000 00000000 00000000 d090d000 00001c6a
ff40: d090dca8 d090db49 d090e9d0 cf659940 000008a8 00000998 00000000 00000000
ff60: 00000020 00000021 00000018 00000015 00000011 00000000 00000002 403c2b08
ff80: 00000000 00021d80 00000080 c000f268 cf6be000 00000000 00000000 cf6bffa8
ffa0: c000f000 c007024c 403c2b08 00000000 400fe000 00001c6a 402d9230 00000002
ffc0: 403c2b08 00000000 00021d80 00000080 00021088 00001c6a 402d9230 00000000
ffe0: 403725a0 be8f4b98 402d1b24 403725b0 80000010 400fe000 00000000 00000000
[<bf002038>] (my_hrtimer_drv_init+0x38/0xec [hrtimer_drv]) from [<c00087a4>] (do_one_initcall+0x130/0x1b0)
[<c00087a4>] (do_one_initcall+0x130/0x1b0) from [<c007062c>] (sys_init_module+0x3ec/0x1c2c)
[<c007062c>] (sys_init_module+0x3ec/0x1c2c) from [<c000f000>] (ret_fast_syscall+0x0/0x30)
Code: e34434e0 e59f40a8 e3a01002 e3a00000 (e583107c) 
---[ end trace f80a40936e181261 ]---
Segmentation fault

 

am335x linux下Timer7配置例子,上半部分为映射到虚拟地址对Timer7进行配置的代码,下半部分注释掉的代码为裸跑时的地址操作,两部分一一对应。具体功能配置我也不太熟,怎么配置看am335x手册吧

oid Timer7_config(void)
{
    volatile unsigned int *var1 = 0;
    volatile unsigned int *var2 = 0;
    volatile unsigned int *var3 = 0;
    volatile unsigned int *var4 = 0;
    volatile unsigned int *var5 = 0;

    var1 = (volatile unsigned int *)ioremap(0x44E00000+0x7C, sizeof(var1));
    writel(0x00000002, var1);
    printk("0x44E00000 + 0x7C = %x\n", *var1);
    var2 = (volatile unsigned int *)ioremap(TIMER7_BASE + 0x10, sizeof(var2));
    writel(0x00000002, var2);
    printk("TIMER7_BASE + 0x10 = %x\n", *var2);
    var3 = (volatile unsigned int *)ioremap(TIMER7_BASE + 0x40, sizeof(var3));
    writel(0x00000000, var3);
    printk("TIMER7_BASE + 0x40 = %x\n", *var3);
    var4 = (volatile unsigned int *)ioremap(TIMER7_BASE + 0x38, sizeof(var4));
    writel(0x00000003, var4);
    printk("TIMER7_BASE + 0x38 = %x\n", *var4);
    var5 = (volatile unsigned int *)ioremap(TIMER7_CLKSEL_BASE + 0x04, sizeof(var5));
    writel(0x00000001, var5);
    printk("TIMER7_CLKSEL_BASE + 0x04 = %x\n", *var5);
    
    // writel(0x00000002, 0x44E00000 + 0x7C);//CM_PER->M_PER_TIMER7_CLKCTRL,开启定时器
    // printk("OCP Configuration Register = %x\n", readl(TIMER7_BASE + 0x10));
    // writel(0x00000002, TIMER7_BASE + 0x10);//DMTIMER7->Timer OCP Configuration Register,定时器自由运行
    // writel(0x00000000, TIMER7_BASE + 0x40);//DMTIMER7->Timer Load Register, timer counter register start value after overflow
    // writel(0x00000003, TIMER7_BASE + 0x38);//DMTIMER7->Timer Control Register,Auto-Reload,& Start Timer

    // //时钟选择,默认为高速晶振
    // writel(0x00000001, TIMER7_CLKSEL_BASE + 0x04);//CM_DPLL->CLKSEL_TIMER7_CLK,时钟源选择,默认复位即为选贼高速晶振
}

//读取Timer7计数值
unsigned int GetTimer7Count(void)
{
    unsigned int *var1, value;
    var1 = (unsigned int *)ioremap(TIMER7_BASE+0x3C, sizeof(var1));
    value = *var1;
    //重置计数值
    *var1 = 0;
    return value;
}

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值