如何在Jetson Xavier上通过Python访问硬件寄存器并生成定时中断
在Jetson Xavier上用Python配置TKE_AON_TIMER_TMR0生成100ms中断
前提准备
- 必须以root权限运行脚本(硬件寄存器访问需要内核级权限)
- 对照Jetson Xavier的Tegra技术参考手册(TRM)确认寄存器物理地址,以下示例基于公开标准地址(实际需匹配你的硬件版本):
TKE_AON_TIMER_TMR0_TMRCR_0物理地址:0x0c2a0000TKE_AON_TIMER_TMR0_TMR_RLD_0(重载寄存器):0x0c2a0004TKE_AON_TIMER_TMR0_TMR_CNT_0(计数寄存器):0x0c2a0008TKE_AON_TIMER_INT_ENB(中断使能寄存器):0x0c2a0010
核心逻辑
- 内存映射:将寄存器物理地址映射到用户空间,实现Python直接读写
- 计算重载值:AON定时器默认使用32768Hz低功耗时钟,100ms对应的计数值为
32768 * 0.1 = 3277(取整) - 配置流程:先禁用定时器→设置递减计数+溢出中断模式→写入重载值→启用定时器并打开中断
- 中断响应:绑定中断信号,触发时执行传感器读取逻辑
Python代码示例
import mmap import os import signal import time # 寄存器地址配置 TKE_AON_TIMER_BASE = 0x0c2a0000 TMRCR_0_OFFSET = 0x00 # TKE_AON_TIMER_TMR0_TMRCR_0 TMR_RLD_0_OFFSET = 0x04 # 重载寄存器 INT_ENB_OFFSET = 0x10 # 中断使能寄存器 # 定时器参数 CLOCK_FREQ = 32768 INTERVAL_MS = 100 RELOAD_VALUE = int(CLOCK_FREQ * (INTERVAL_MS / 1000)) MAP_SIZE = 0x20 # 覆盖所需寄存器范围 # 中断处理函数 def handle_interrupt(signum, frame): # 替换为你的传感器读取逻辑 print(f"[{time.strftime('%H:%M:%S')}] 触发中断,读取传感器数据") # 清除中断标志 mm_regs[INT_ENB_OFFSET] &= ~(1 << 0) def main(): global mm_regs # 打开/dev/mem并映射寄存器 with open('/dev/mem', 'r+b') as f: mm_regs = mmap.mmap(f.fileno(), MAP_SIZE, offset=TKE_AON_TIMER_BASE, prot=mmap.PROT_READ | mmap.PROT_WRITE) # 初始化定时器 mm_regs[TMRCR_0_OFFSET] = 0x00 # 禁用定时器 # 配置模式:递减计数+溢出中断使能(bit2=中断使能,bit1=0为递减) mm_regs[TMRCR_0_OFFSET] = (1 << 2) | (0 << 1) # 写入重载值 mm_regs[TMR_RLD_0_OFFSET] = RELOAD_VALUE.to_bytes(4, byteorder='little') # 打开定时器中断 mm_regs[INT_ENB_OFFSET] |= (1 << 0) # 启用定时器 mm_regs[TMRCR_0_OFFSET] |= (1 << 0) # 绑定中断信号(需先将硬件中断映射到用户空间信号,示例用SIGUSR1) signal.signal(signal.SIGUSR1, handle_interrupt) print(f"定时器已配置为{INTERVAL_MS}ms中断,等待触发...") try: while True: time.sleep(1) except KeyboardInterrupt: # 清理操作 mm_regs[TMRCR_0_OFFSET] = 0x00 mm_regs[INT_ENB_OFFSET] &= ~(1 << 0) print("\n已停止定时器") if __name__ == "__main__": if os.geteuid() != 0: print("错误:必须以root权限运行脚本(使用sudo)") exit(1) main()
关键注意事项
- 地址验证:务必根据你的Jetson型号TRM确认寄存器地址,不同版本可能有差异
- 中断映射:需先通过sysfs将定时器中断号绑定到用户空间,示例命令(假设中断号为30):
echo 30 > /proc/sys/kernel/irq/30/smp_affinity - 系统风险:直接操作硬件寄存器可能导致系统崩溃,测试前备份数据
- 性能优化:中断处理函数应尽量简短,复杂逻辑可放到单独线程执行
内容的提问来源于stack exchange,提问作者jhorivas07
相关产品推荐
相关产品推荐

