Хранение управляющей структуры в вызывающем объекте
От: cppguard  
Дата: 08.08.23 22:20
Оценка:
Пытаюсь реализовать полность асинхронную обработку I2C без выделения памяти. Нюанс этой шины в том, что чтобы что-то прочитать, нужно сперва записать адрес регистра, из которого нужно выполнить чтение. И с точки зрения машины состояний, эти два шага — независимые. Если бы сиутация была как с UART, то достаточно было бы завести кольцевой буфер и все запросы на чтение и запись сваливать туда. А тут требуется разбивать запросы логически на блоки, иначе как понять, что после записи очередной порции данных, теперь нужно считывать?

Я подумал, что задачу можно решить следующим образом. Пусть инициаторы запросов сами формируют структуру сообщения, а драйвер I2C будет лишь связывать структуры в список и исполнять машину состояний для очередного сообщения. После очередного достижения терминального состония, текущее сообщение удаляется из списка (для связного списка это просто переприсваивание указателей), и в обработку берётся следующее, если оно есть.

Например, структура сообщения может иметь вид:
struct msg {
  int type; // 0 - READ, 1 - WRITE
  int size;
  char *data;
  msg *prev;
  msg *next;
  void (*callback)(); // вызывается драйвером из прерывания, когда данные прочитаны/записаны
};


Тогда инициатор запроса будет заполнят нужные поля сам и отправлять сообщение драйверу. Драйвер добавляет сообщение в начало списка, а обрабатывает список с конца (или наоборот, это неважно). Весь код является последовательным, и только прерывания добавляют асинхронности, поэтому каждому пользователю шины достаточно хранить одну структуру сообщения в статической памяти. Таким образом достигается и потокобезопасность, и отсутствие необходимости в динамической мапяти.

Как идея — имеет право на жизнь?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.