Python3. Байтовые последовательности

Питон в своём подходе к обработке данных ни разу не походит на классические языки программирования типа Си/C++, и этим объясняется одна из трудностей, почему Си-шники его не очень жалуют.

Тем, кто хочет сразу узнать суть, я рекомендую не читать всё, а сразу прокрутить в конец статьи.

В Си всё просто. Например, у вас есть какие-то байты, которые лежат на своих адресах в памяти, и а уж как их интерпретировать — это зависит от контекста задачи. Эти байты могут представлять собой коды печатных символов (буквы, цифры, знаки препинания). А могут быть составляющими элементами (младший байт, старший байт) чисел.

Ещё пример. Последовательный порт передаёт байты. Просто байты. Обезличенные. Это задача программы — как их понимать и как с ними работать. То есть вы сначала набираете (принимаете из последовательного порта) последовательность этих байтов, а потом эту последовательность представляете как целое число или число с плавающей точкой. А может быть это будет ASCIIZ-строка символов. Всё просто!

В Питоне всё намного запутаннее.

Мне тут намедни понадобилось написать небольшую прогу для работы с микросхемой трансмиттера CC2520 по последовательному каналу — комп должен был играть роль терминала для этой микросхемы. Задача ни о чём!

Я взял микроконтроллер STM32, с одной стороны подключил к нему CC2520 по SPI, с другой — подключил CH340G по USART.

На стороне компа у меня работает прога, которая по нажатию на кнопки отправляет заданные байтовые последовательности в микроконтроллер.

Байтовые последовательности — это, так называемые, пакеты. Пакеты имеют незатейливую структуру. Первым байтом у них идёт размер пакета (без учёта этого самого байта), далее — собственно сама последовательность байт, составляющих команду и её параметры.

В обратном направлении (от STM32 в комп) поступают ответы. Структура ответных пакетов похожа на командные пакеты.

Сложность (если так можно выразиться!) стояла в том, как сформировать данные, которые представляют собой команды.

Ещё одна сложность была в том, что уровень бизнес-логики программы общается не напрямую с последовательным портом, а через класс-посредник. В этом классе посреднике нужно из последовательности байт, представляющих собой команду, сформировать пакет для передачи в микроконтроллер.

Суть.

Где-то в программе формируем такой код:

  # Создаем команду СС2520 (MEMRD) для чтения регистра VERSION (адрес 0x0042)
  cmd = b"\x10\x42\x00"

  # Отправляем команду в МК
  send_cmd(cmd)

...

  # В классе-посреднике:
  def onSend(self, cmd):

    pack = bytearray(1) # Создаём байтовый массив длиной один байт
    pack[0] = len(cmd) # В нулевой байт массива помещаем длину

    # Копируем в массив байты команды.
    # При этом размер массива будет автоматически увеличиваться.
    # При желании в конец пакета можно также дописать контрольную сумму.
    pack[1:] = cmd

    ser.write(pack)  # Теперь пакет можно отправлять

Это довольно просто решение, но оно не очевидно для Си-шников. Да и я, сам о нём не всегда помню. Особенно после длительных перерывов по работе с Питоном.

Ладно. Пусть будет! Может кому-нибудь сгодится.

3 responses to “Python3. Байтовые последовательности

  1. В 12 строке очепятка: bytearray.
    В 18 строке можно просто присваивать cmd.

  2. крутое))

Оставьте комментарий