특정 통신 인터페이스를 통해 액세스 할 수있는 하드웨어를 처리하는 코드를 작성하고 있습니다. 전체 장치를 설명하는 개체의 속성으로 특정 레지스터 집합을 정의하고 싶습니다. 하드웨어에 액세스 할 수있는 hw_read(address, size)
및 hw_write(address, size, array_of_values)
기능이 있다고 가정합니다.파이썬 - 하드웨어 처리, 하드웨어 레지스터를 객체의 속성으로 효율적으로 구현하는 방법
주소 10에서 시작하여 길이가 2 인 레지스터 블록이 있으며이를 "reg1"속성에 할당하려고한다고 가정 해 보겠습니다. 나는 다음과 같은 방법으로 작업을 수행 할 수 있습니다
class my_hardware(object):
def __init__(self):
# Perform initialization
return
@property
def reg1(self):
return hw_read(10,2)
@reg1.setter
def reg1(self,value):
hw_write(10,2,value)
위의 구현은 매우 편리하지 않습니다, 나는 두 번 주소와 크기를 제공해야한다. 특히 많은 수의 레지스터를 정의해야하는 경우 오류가 발생하기 쉽습니다.
는dev1.reg1=(0x1234,0x3211)
print dev1.reg2
두 번째 방법도 있습니다 통해에 액세스 한 후
dev1=my_hardware()
dev1.define_register("reg1",10,2)
dev1.define_register("reg2",12,6)
그리고 : 내가 쉽게 은 아래와 같은 몇 가지 레지스터를 설정 정의 할 수 있음을, 같은 방법으로 그것을 구현하는 것이 가능 중요한 장점은 외부 텍스트 파일 (예 : VHDL 합성에도 사용됨)에서 레지스터 목록 (이름, 주소 및 크기)을 읽을 수 있다는 것입니다.
업데이트 가능한 솔루션?
>>> a=my_hardware()
>>> a.add_reg("reg1",10,2)
>>> a.add_reg("reg2",20,3)
>>> a.reg1
read:10, 2
(4660, 4660)
>>> a.reg2
read:20, 3
(4660, 4660, 4660)
>>> a.reg1=(10, 11)
write:10, 2 val=(10, 11)
>>> a.reg2=(10, 11, 12)
write:20, 3 val=(10, 11, 12)
: 더미 hw_read 및 hw_write 기능 def hw_write (first,size,val):
print "write:"+str(first)+", "+str(size)+" val="+str(val)
def hw_read (first,size):
print "read:"+str(first)+", "+str(size)
return (0x1234,)*size
class my_hardware(object):
def __init__(self):
return
def add_reg(self,name,first,size):
setattr(my_hardware,name,property(lambda self : hw_read(first,size), lambda self, x: hw_write(first,size,x)))
이하
있는 샘플 결과 :
성질 추가 동적 관련된 SOE 소식을 연구 한 결과, I는 다음과 같이 코드로 필요한 기능을 달성
위의 해결 방법이 합리적인지 여부를 알려 주시면 감사하겠습니다.
내가 볼 수있는 한 가지 문제점 (또는 특징)은 레지스터가 "클래스 당", "인스턴스별로"정의되어 있지 않다는 것입니다. 동일한 레지스터 세트를 가진 몇 개의 디바이스가있는 경우, 하지만, "my_hardware"클래스를 사용하여 동일한 버스에 연결된 서로 다른 레지스터 세트를 가진 다른 디바이스에 액세스하려는 경우 오해의 소지가있을 수 있습니다.
I 유도 클래스가 특정 장치를 설명 정의하고 클래스 당 레지스터를 정의 할 수있는 용액, 발견 2
업데이트 : 이하
def hw_write (first,size,val):
print "write:"+str(first)+", "+str(size)+"val="+str(val)
def hw_read (first,size):
print "read:"+str(first)+", "+str(size)
return (0x1234,)*size
class my_hardware(object):
def __init__(self, base_address):
self.ba = base_address
return
@classmethod
def add_reg(myclass,name,first,size):
setattr(myclass,name,property(lambda self : hw_read(self.ba+first,size), lambda self, x: hw_write(self.ba+first,size,x)))
가 정확한 동작을 보여주는 샘플 세션이다 :
>>> class dev1(my_hardware):
... pass
...
>>> class dev2(my_hardware):
... pass
...
>>> dev1.add_reg("reg1",10,2)
>>> dev2.add_reg("reg2",15,3)
>>> a=dev1(100)
>>> b=dev2(200)
>>> a.reg1
read:110, 2
(4660, 4660)
>>> a.reg2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dev1' object has no attribute 'reg2'
>>> b.reg1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dev2' object has no attribute 'reg1'
>>> b.reg2
read:215, 3
(4660, 4660, 4660)
자세히 알 수 있듯이 레지스터 reg1은 클래스 "dev1"의 장치에 정의되어 있습니다. w hile 레지스터 reg2는 dev2 클래스의 장치에 정의됩니다. 물론이 경우에는 각 장치에 전달할 기본 주소가 필요하므로 "base_address"를 생성자에 추가해야했습니다.
덕분에, 보이 테크
관련 항목 : http://stackoverflow.com/questions/1325673/how-to-add-property-to-a-python-class-dynamically –