【问题标题】:How do I write to registers in hardware using Python?如何使用 Python 写入硬件中的寄存器?
【发布时间】:2013-06-29 21:36:01
【问题描述】:

我有一个 C 函数,它可以通过打开设备描述符 (nf10) 完美地读取/写入硬件寄存器。我正在尝试使用 Python 做同样的事情。我能够读取寄存器,但无法写入寄存器。为什么我不能写?有没有更好的方法对硬件中的寄存器进行读/写?

相关Python代码:

#! /usr/bin/env python
import os
from fcntl import *
from struct import *

SIOCDEVPRIVATE = 35312
NF10_IOCTL_CMD_READ_STAT = SIOCDEVPRIVATE + 0
NF10_IOCTL_CMD_WRITE_REG = SIOCDEVPRIVATE + 1
NF10_IOCTL_CMD_READ_REG = SIOCDEVPRIVATE + 2

def rdaxi(addr):

    f = open("/dev/nf10", "r+")
    arg = pack("q", int(addr, 16))
    value = ioctl(f, NF10_IOCTL_CMD_READ_REG, arg)
    value = unpack("q", value)
    value = value[0]
    value = hex(value & int("0xffffffff", 16))
    f.close()
    return value

def wraxi(addr, value):

    f = open("/dev/nf10", "r+")
    arg = (int(addr, 16) << 32) + int(value, 16)
    arg = pack("q", arg)
    ioctl(f, NF10_IOCTL_CMD_WRITE_REG, arg)
    f.close()

相关C代码

#include <fcntl.h>
#include <sys/ioctl.h> 
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define NF10_IOCTL_CMD_READ_STAT (SIOCDEVPRIVATE+0)
#define NF10_IOCTL_CMD_WRITE_REG (SIOCDEVPRIVATE+1)
#define NF10_IOCTL_CMD_READ_REG (SIOCDEVPRIVATE+2)

int main(int argc, char* argv[]){
   int f;
   uint64_t v;
   uint64_t addr;
   uint64_t val;

   if(argc < 3){
       printf("usage: rdaxi reg_addr(in hex) reg_val(in_hex)\n\n");
       return 0;
   }
   else{
    sscanf(argv[1], "%llx", &addr);
    sscanf(argv[2], "%llx", &val);
  }

//----------------------------------------------------
//-- open nf10 file descriptor for all the fun stuff
//----------------------------------------------------
f = open("/dev/nf10", O_RDWR);
if(f < 0){
    perror("/dev/nf10");
    return 0;
}

printf("\n");

// High 32 bits are the AXI address,
// low 32 bits are the value written to that address
v = (addr << 32) + val;
if(ioctl(f, NF10_IOCTL_CMD_WRITE_REG, v) < 0){
    perror("nf10 ioctl failed");
    return 0;
}
printf("\n");

close(f);

return 0;

}

【问题讨论】:

  • 它是否返回任何特定错误?
  • 当我调用该函数时,它没有写入任何错误。但它不写寄存器。当我在 python 中逐行运行 wraxi 函数时,它显示 struct.error : integer out of range for 'q' format code
  • 如果您已经用 C 编写过代码,则始终可以选择扩展 Python 并直接调用您的 C 代码。
  • 我尝试扩展 python 以使用共享库调用 C。有用。但我不确定如何参数化函数以便它可以接受参数。
  • 我已经分享了C代码。

标签: python c hardware cpu-registers


【解决方案1】:

我认为最好在 C 中对寄存器实现较低级别的操作,并将 C 编译为 .so。然后在python中加载.so。

【讨论】:

  • 这正是我最终所做的。出于某种原因,在执行 struct.pack 时,写入操作似乎没有通过。
【解决方案2】:

我怀疑“字节顺序”可能是您的问题。但是,如果不知道您正在写入的硬件,就很难说清楚。我注意到你已经从你的包函数调用中删除了字节顺序说明符。大多数硬件寄存器都是大端的,这意味着它们期望位 0 位于最低内存地址,最高有效位位于最高地址。

如果没有字节顺序说明符,Python 将使用您的本机字节序进行打包,这在英特尔系统上是 little-endian。尝试使用 big-endian 说明符打包它,以使所有内容保持与开始时相同的顺序:

arg = pack(">q", arg)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2020-06-08
    • 1970-01-01
    相关资源
    最近更新 更多