Add shared waveform processing, generation and firmware image support
This commit is contained in:
48
python/firmware_image/native.py
Normal file
48
python/firmware_image/native.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Models for the C99 Intel HEX parser. No Python parser fallback."""
|
||||
import ctypes as ct
|
||||
from functools import lru_cache
|
||||
from protocan.native import _load_library
|
||||
|
||||
class Cell(ct.Structure):
|
||||
_fields_ = [('address', ct.c_uint32), ('value', ct.c_uint8)]
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def library():
|
||||
lib = _load_library()
|
||||
try:
|
||||
lib.firmware_hex_parse.argtypes = [ct.c_char_p, ct.c_size_t, ct.POINTER(Cell),
|
||||
ct.c_size_t, ct.c_size_t, ct.POINTER(ct.c_size_t), ct.POINTER(ct.c_size_t)]
|
||||
lib.firmware_hex_parse.restype = ct.c_int
|
||||
lib.firmware_hex_segment_size.argtypes = [ct.POINTER(Cell), ct.c_size_t, ct.c_size_t]
|
||||
lib.firmware_hex_segment_size.restype = ct.c_size_t
|
||||
except AttributeError as exc:
|
||||
raise RuntimeError('Rebuild SETProtocol: native firmware image API is missing') from exc
|
||||
return lib
|
||||
|
||||
def parse_segments(text, max_records, error_type, segment_type):
|
||||
try:
|
||||
raw = bytes(text) if isinstance(text, (bytes, bytearray)) else str(text or '').encode('ascii')
|
||||
except UnicodeError as exc:
|
||||
raise error_type('Intel HEX должен состоять из ASCII') from exc
|
||||
if max_records < 1 or len(raw) > 64 * 1024 * 1024:
|
||||
raise error_type('Файл Intel HEX превышает допустимый размер')
|
||||
cells = (Cell * max(1, len(raw) // 2))()
|
||||
count, line = ct.c_size_t(), ct.c_size_t()
|
||||
lib = library()
|
||||
status = lib.firmware_hex_parse(raw, len(raw), cells, len(cells), max_records,
|
||||
ct.byref(count), ct.byref(line))
|
||||
if status:
|
||||
messages = {1: 'неверный формат', 2: 'неверная checksum записи',
|
||||
3: 'неизвестный тип или неверная длина записи', 4: 'нет данных/EOF или данные после записи EOF',
|
||||
5: 'адрес описан повторно', 6: 'адрес выходит за uint32',
|
||||
7: 'превышено допустимое число записей',
|
||||
8: "запись должна начинаться с ':'", 9: 'запись содержит не пары HEX-символов',
|
||||
10: 'длина записи не совпадает с полем count'}
|
||||
raise error_type('Intel HEX, строка %d: %s' % (line.value, messages.get(status, 'ошибка')))
|
||||
result, offset = [], 0
|
||||
while offset < count.value:
|
||||
size = lib.firmware_hex_segment_size(cells, count.value, offset)
|
||||
result.append(segment_type(cells[offset].address,
|
||||
bytes(cells[i].value for i in range(offset, offset + size))))
|
||||
offset += size
|
||||
return result
|
||||
Reference in New Issue
Block a user