Я пишу драйвер пользовательского пространства для доступа к регистрам FPGA в Python 3.5, который mmap
определяет адресное пространство PCI FPGA, получает memoryview
для обеспечения прямого доступа к отображенному в памяти регистровому пространству, а затем использует struct.pack_into("<I", ...)
для записи 32-битного значения в выбранный 32-битный выровненный адрес.
def write_u32(address, data):
assert address % 4 == 0, "Address must be 32-bit aligned"
path = path.lib.Path("/dev/uio0")
file_size = path.stat().st_size
with path.open(mode='w+b') as f:
mv = memoryview(mmap.mmap(f.fileno(), file_size))
struct.pack_into("<I", mv, address, data)
К сожалению, появляется , что struct.pack_into
делает memset(buf, 0, ...)
, который очищает регистр раньшефактическое значение написано.Изучив операции записи в FPGA, я вижу, что регистр установлен в 0x00000000 до того, как задано истинное значение, поэтому по крайней мере две записи по шине PCI (фактически для 32-битного доступа есть три, два нуляпишет, а затем фактические данные. 64-битные включает в себя шесть записей).Это вызывает побочные эффекты для некоторых регистров, которые подсчитывают количество операций записи, или для некоторых, которые «очищают при записи» или инициируют какое-либо событие при записи.
Я хотел бы использовать альтернативный метод для записи регистраданные за одну запись в отображаемое в память регистровое пространство.Я посмотрел на ctypes.memmove
, и это выглядит многообещающе (пока не работает), но мне интересно, есть ли другие способы сделать это.
Обратите внимание, что регистр читает , используяstruct.unpack_from
отлично работает.
Обратите внимание, что я также исключил FPGA из этого с помощью драйвера QEMU, который регистрирует все обращения - я вижу такой же двойной доступ с нулевой записью до записи данных.