- Pandas обладает большой гибкостью для обработки больших данных.
- Named_bitfield (https://github.com/not-napoleon/named_bitfield/blob/master/named_bitfield.py) имеет возможность обрабатывать поля уровня битов.
Объединение Pandas с named_bitfield создает мощное решение для карты памяти некоторых встроенных систем. Например, Raspberry Pi 4 / Nvidia JETSON TX2 может иметь 4 ГБ памяти и может использовать эту функцию для связи с ИС с большой гибкостью. Приведенный ниже код демонстрирует способ объединения полей Pandas и named_bit для создания тестовой карты памяти из файла csv.
import pandas as pd
from io import StringIO
import ast
from functools import partial
from named_bitfield import named_bitfield
# define register offset as regOffset, name as regName, bit fields ad regFields
# define register default value as regDefault, mode as regMode, description as regDescription
memorymapFile = '''
regOffset,regName,regFields,regDefault,regMode,regDescription
0,test_regin1,"('bit7_4', 4), ('bit3_2', 2), ('bit1_0',2)",0x0,R/W,Test input register 1
1,test_regin2,"('bit7_1',7), ('bit_0',0)",0x0,R/W,Test input register 2
'''
def _bitFields(bitFields, value, bitwidth):
""" format the regFields content to be used in the named_bitbitFields
:param bitFields: the coloumn in the regMap contains the bit bitFields definition
:param value: the default value for this register
:param bitwidth: 8/16/32 bits in a register if bitFields is empty,
:return named_bitbitFields with the default value
"""
if pd.isna(bitFields):
bitFields = [('rsvd', bitwidth)]
else:
bitFields = ast.literal_eval(bitFields) # convert string to list
namedbf = named_bitfield('nbf', bitFields, mutable=True)
return pd.Series(namedbf.fromint(value))
def readRegMapFile(csvfile, index_col='regName', reg_bitFields='regFields', reg_default='regDefault', bitwidth=8):
regPd = pd.read_csv(csvfile, index_col=index_col, converters={reg_default: partial(int, base=16)})
regPd['content'] = regPd.apply(lambda x: _bitFields(bitFields=x[reg_bitFields],
value=x[reg_default], bitwidth=bitwidth), axis=1)
return regPd
if __name__ == '__main__':
baseAddr = 0 # memory map defines offset, assume baseAddr is 0
testMemMapPd = (readRegMapFile(StringIO(memorymapFile)).assign(regAddr = lambda x: x['regOffset'] + baseAddr))
for column in testMemMapPd.columns: # print all the properties associated with a register
print(f"{column}: {testMemMapPd.loc['test_regin1', column]}")
# use register name as index to address each register
testMemMapPd.loc['test_regin1', 'content'].bit7_4 = 0xF # assigned 15 to bit7_4
print(testMemMapPd.loc['test_regin1'].content) # print 240
testMemMapPd.loc['test_regin1', 'content'].bit1_0 = 0x3 # assigned 3 to bit1_0
print(testMemMapPd.loc['test_regin1'].content) # print 243
testMemMapPd.loc['test_regin1', 'content'] = testMemMapPd.loc['test_regin1'].content.fromint(155)
print(testMemMapPd.loc['test_regin1'].content) # print 155, 0x9B, 10011011
print(testMemMapPd.loc['test_regin1'].content.bit7_4) # print 9
print(testMemMapPd.loc['test_regin1'].content.bit3_2) # print 2
print(testMemMapPd.loc['test_regin1'].content.bit1_0) # print 3