2013-07-02 54 views
2

我有一個C函數,它可以通過打開設備描述符(nf10)完美地讀/寫硬件寄存器。我正在嘗試使用Python來做同樣的事情。我能夠讀取寄存器,但我無法寫入寄存器。爲什麼我無法寫作?有沒有更好的方式來讀/寫硬件中的寄存器?如何使用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; 

}

+0

它是否返回任何特定的錯誤? – mariosangiorgio

+0

當我調用該函數時,它沒有寫入任何錯誤。但它不寫寄存器。當我在python中一行一行地運行wraxi函數時,它表示struct.error:'q'格式代碼的整數超出範圍 – user2532296

+0

如果您已經用C語言編寫代碼,那麼總是會選擇擴展Python並調用你的C代碼直接。 –

回答

0

我認爲這是最好的實現上用C寄存器低級操作,並編譯C到。所以。然後在python中加載.so。

+0

這正是我最終做的。出於某種原因,寫入操作在執行struct.pack時似乎沒有經過。 – user2532296

0

我懷疑「endianness」可能是你的問題。不過,如果不知道您要寫入的硬件,很難說清楚。我注意到你從pack函數調用中遺漏了字節順序說明符。大多數硬件寄存器都是大端的,這意味着他們期望最低內存地址的位0和最高地址的最高有效位。

如果沒有字節順序說明符,Python將打包您的本地字節序,這在英特爾系統上是小端的。嘗試使用big-endian說明符進行打包,以便所有內容都保持與開始時相同的順序:

arg = pack(">q", arg)