COBS
Модуль для кодирования и декодирования данных с использованием алгоритма COBS (Consistent Overhead Byte Stuffing). COBS используется для фреймирования бинарных данных при передаче по последовательным каналам связи, гарантируя отсутствие нулевых байтов в передаваемых данных.
cobs.encode(data [, mode])
Кодирует данные с использованием COBS.
Аргументы:
- data: строка с бинарными данными для кодирования
- mode (опционально): режим кодирования
- nil или false - стандартный COBS
- true или “tinyframe” - режим TinyFrame (payload до 254 байт)
- “raw” или “standard” - стандартный COBS
Возвращает: закодированную строку
local cobs = require("cobs")
-- Стандартное кодирование
local encoded = cobs.encode("Hello\0World")
-- Кодирование в режиме TinyFrame
local encoded = cobs.encode("data", true)
local encoded = cobs.encode("data", "tinyframe")
cobs.decode(data [, mode])
Декодирует COBS-закодированные данные.
Аргументы:
- data: закодированная строка
- mode (опционально): режим декодирования (аналогично encode)
Возвращает: декодированную строку
Одноразовая функция принимает ровно один полный кадр: нулевой разделитель
должен быть последним байтом data. Хвост после первого разделителя, в том
числе второй склеенный кадр, считается ошибкой. Для потока из нескольких
кадров используйте cobs.new() и buffer:feed().
local cobs = require("cobs")
local original = "Hello World"
local encoded = cobs.encode(original)
local decoded = cobs.decode(encoded)
print(decoded) -- Hello World
cobs.encode_tinyframe(data)
Кодирует данные в режиме TinyFrame. Эквивалентно cobs.encode(data, true).
Аргументы:
- data: строка для кодирования (максимум 254 байта)
Возвращает: закодированную строку
local encoded = cobs.encode_tinyframe("short data")
cobs.decode_tinyframe(data)
Декодирует данные из режима TinyFrame. Эквивалентно cobs.decode(data, true).
Аргументы:
- data: закодированная строка (минимум 2 байта)
Возвращает: декодированную строку
local decoded = cobs.decode_tinyframe(encoded)
cobs.new(maxlen [, mode])
Создает буфер для потокового декодирования COBS-фреймов. Полезно при приеме данных по частям через UART или другой последовательный интерфейс.
Аргументы:
- maxlen: максимальный размер буфера в байтах
- mode (опционально): режим декодирования (см. encode)
Возвращает: объект буфера
local cobs = require("cobs")
-- Создание буфера на 256 байт
local buffer = cobs.new(256)
-- Создание буфера в режиме TinyFrame
local buffer = cobs.new(256, true)
buffer:feed(chunk)
Добавляет данные в буфер и возвращает все полностью принятые фреймы.
Аргументы:
- chunk: строка с данными для добавления (может быть nil)
Возвращает: таблицу с декодированными фреймами (может быть пустой)
local cobs = require("cobs")
local buffer = cobs.new(256)
-- Симуляция приема данных по частям
local frames = buffer:feed(chunk1)
for _, frame in ipairs(frames) do
print("Received frame: " .. frame)
end
local frames = buffer:feed(chunk2)
-- ...
buffer:reset()
Сбрасывает буфер, очищая все накопленные данные.
buffer:reset()
buffer:pending()
Возвращает количество байтов, ожидающих обработки в буфере.
Возвращает: число байтов
local pending = buffer:pending()
print("Pending bytes: " .. pending)
Пример: прием данных через UART
local cobs = require("cobs")
local uart = require("uart")
-- Создаем буфер для приема
local buffer = cobs.new(512)
-- Настраиваем UART
uart.attach(uart.UART1, 115200, 8, uart.PARNONE, uart.STOP1)
while true do
-- Читаем данные из UART
-- *cl возвращает данные вместе с нулевым COBS-разделителем.
-- *l здесь не подходит: он использует нулевой байт как конец строки,
-- но не передаёт его buffer:feed().
local data = uart.read(uart.UART1, "*cl", 100, 512, 0)
if data then
-- Добавляем в буфер и получаем готовые фреймы
local frames = buffer:feed(data)
for _, frame in ipairs(frames) do
-- Обрабатываем каждый принятый фрейм
print("Frame received: " .. #frame .. " bytes")
end
end
end
Пример: отправка данных
local cobs = require("cobs")
local uart = require("uart")
-- Подготовка данных для отправки
local data = "sensor:temperature:25.5"
local encoded = cobs.encode(data)
-- Отправка через UART
uart.write(uart.UART1, encoded)