main_ubi_sdk v 0.1.3
This is UBI4 documentation
Ресивер: описание команд и запросов параметров.

Receiver ссылка на топик
В UBI есть два типа запросов:

  • Запрос параметра
  • Команда
    • Базовая команда (main receiver)
    • Специфичная для устройства команда (custom receiver) (Может не быть совсем)

Список базовых команд

Эту картинку можно посмотреть как эксель в !documentation/Список команд.xlsx, либо открыть в отдельном окне. Отправив команду, программа попадает в DeviceMainReceiver(). Там можно посмотреть граф вызываемых функций в соответствии с картинкой выше.

Attention
Общий принцип:
Базовая структура команды запроса: command - комманда, data[0] - подкомманда, data[1] - аргумент, data[2] - аргумент(иногда).
Возвращается обратно буффер data из прошлой строчки и после этого запрашиваемая структура/структуры.
Warning
Исключение для команды DATA_MANAGER : READ_DATA. В этом случае data[1] = DataCode, но он не возвращается, только data[0].
Исправление этой ошибки запланировано

Весь список базовых команд находится в Command_enum. Вот подробное описание каждой команды: (пока что не все команды описаны)
switch(command)

  1. DEVICE_INFORMATION - Запрос базовой информации девайса
    data[0] содержит тип запроса базовой информации в соотетствии с DeviceInformationCommand_enum.
    switch(data[0])
    1. INICIALIZE_INFORMATION - Запрос базовой информации устройства
      Входящие параметры:
      Parameters
      data[1]Если 1, то ответ short_inicialize_connection_struct, если 2, то full_inicialize_connection_struct
      Returns
      data[0] INICIALIZE_INFORMATION
      data[1] 1 или 2 (в зависимости от запроса)
      data[2:2+sizeof(short_inicialize_connection_struct)] или data[2:2+sizeof(full_inicialize_connection_struct)] - структура с информацией об устройстве
    2. READ_DEVICE_PARAMETERS - Запрос параметров устройства. Возвращает base_parameter_info_struct всех параметров
      Входящие параметры:
      Parameters
      data[1]ID параметра, с которого начинаем вычитывать
      data[2]Количество параметров Выходные параметры:
      Returns
      data[0] READ_DEVICE_PARAMETERS
      data[1] param_start_index (ID параметра, с которого начинаем вычитывать)
      data[2] param_count (количество параметров)
      data[3:3+sizeof(base_parameter_info_struct)*param_count] - буффер с параметрами
    3. READ_DEVICE_ADDITIONAL_PARAMETER - Запрос дополнительных параметров устройства
      Входящие параметры:
      Parameters
      data[1]ID параметра, с которого начинаем вычитывать Выходные параметры:
      Returns
      data[0] READ_DEVICE_ADDITIONAL_PARAMETER
      data[1] paramID (ID параметра)
      data[2 : 2 + (addInfoNum*sizeof(base_parameter_addinfoseg_struct)] - буффер с дополнительными параметрами
    4. READ_DEVICE_ADDITIONAL_PARAMETER_SIZE - Запрос размера буффера всех дополнительных параметров устройства
      Входящие параметры:
      Parameters
      data[1]ID параметра Выходные параметры:
      Returns
      data[0] READ_DEVICE_ADDITIONAL_PARAMETER_SIZE
      data[1] paramID (ID параметра)
      data[2 : 3] uint16_t размер буффера для всех addinfo
    5. Custom_device_information_command - TODO

  2. DATA_MANAGER - Работа с Data_slots
    DataCode слота можно посмотреть здесь data_table_slots_code_enum
    data[0] содержит тип запроса data slot информации в соотетствии с DataManagerCommand_enum.
    1. READ_AWAILABLE_DATA_SLOTS - Запрос всех доступных data slot (todo сделать запрос не всех, как в параметрах). Возвращает структуры data_table_slot_struct по количеству слотов
      Выхдные параметры:
      Returns
      data[0] READ_AWAILABLE_DATA_SLOTS
      data[2 : 2 + sizeof(data_table_slot_struct) * slots_num] - структура с информацией о data_slot
    2. READ_DATA - Чтение данных из data slot (data[1] не возращается)
      Входящие параметры:
      Parameters
      data[1]DataCode

      Выходные параметры:
      Returns
      data[0] READ_DATA
      data[1 :] Буффер данных data_slot размера data_table_slot_struct.data_size
    3. WRITE_DATA - Запись данных в data slot по DataCode
      Входящие параметры:
      Parameters
      data[1]DataCode
      Выходные параметры:
      Returns
      data[0] WRITE_DATA
      data[1 : ] Буффер данных data_slot размера data_table_slot_struct.data_size
    4. RESET_TO_FACTORY - Сброс данных к заводским настройкам
      Входящие параметры:
      Parameters
      data[1]0xFF (подтверждение сброса)
    5. SAVE_DATA - Сохранение данных в флеш
    6. READ_SLOT - Чтение данных из data slot по DataCode
      Входящие параметры:
      Parameters
      data[1]DataCode Выходные параметры:
      Returns
      data[0] READ_SLOT
      data[1] DataCode
      data[2 : 2 + sizeof(data_slot_struct)] - структура с информацией о data_slot


  3. (!NOT IMPLEMENTED) WRITE_FW_COMMAND - Запись команды во флеш
  4. (!NOT IMPLEMENTED) DEVICE_ACCESS_COMMAND - Управление доступом к устройству
  5. ECHO_COMMAND - Эхо команда Входящие параметры:
    Parameters
    data[]массив данных данных Выходные параметры:
    Returns
    data[] массив данных данных
  6. (!NOT IMPLEMENTED) SUB_DEVICE_MANAGER - Управление поддевайсами
  7. (!NOT IMPLEMENTED) GET_DEVICE_STATUS - Получение статуса устройства
  8. DATA_TRANSFER_SETTINGS - Настройка передачи данных
  9. COMPLEX_PARAMETER_TRANSFER - Передача сложных параметров
  10. (!NOT IMPLEMENTED) POWER_CONTROL - Управление питанием
  11. (!NOT IMPLEMENTED) PROTOCOL_PING - Проверка протокола

Специфичные для устройства команды

Для того, чтобы добавить custom receiver,

  1. Нужно написать функцию обработчика custom command. Например:
    {
    if(receive_str.request_type == BPRT_COMMAND) // Проверяем, что это команда (по идее так и должно быть, но проверить не помешает)
    {
    if(receive_str.command == 13) // Проверяем, что это наша команда. Нумерация команд единая с @ref Command_enum, так что номер принимаемой команды не может пересекаться с базовыми командами
    {
    // Здесь реализуем логику обработки команды, например работа с буфером
    if(receive_str.data_buf[0] != 10 && receive_str.size > 10) return; // Работаем с принятыми данными. В data_buf лежат данные, а size - их размер.
    // Если нужно отправить ответ на команду, то делаем так:
    // Выделяем память под данные, которые мы хотим отправить (если на команду ожидается ответ)
    base_protocol_data_segment_struct* data_segment = protocol_str->get_data_segment_func(protocol_str, 8);
    if(!data_segment) return; // Если память не выделена, то выходим
    // Заполняем данные
    data_segment->pData[0] = 0x11;
    data_segment->pData[1] = 0x22;
    data_segment->pData[2] = 0x33;
    data_segment->pData[3] = 0x44;
    data_segment->pData[4] = 0x55;
    data_segment->pData[5] = 0x66;
    data_segment->pData[6] = 0x77;
    data_segment->pData[7] = 0x88;
    // Отправка ответа на команду, если нужно
    if(protocol_str->protocol_answer_obj_data_func && receive_str.pack_info && data_segment)
    protocol_str->protocol_answer_obj_data_func(protocol_str, receive_str.pack_info, data_segment);
    }
    }
    }
    @ BPRT_COMMAND
    Definition a_protocol.h:53
    bool(* custom_receiver_callback)(uint8_t *Buf, uint16_t size, ports_enum port)
    Definition main_receiver.h:135
    Definition a_protocol.h:205
    uint8_t * pData
    Definition a_protocol.h:210
    Definition a_protocol_struct.h:18
    uint8_t command
    Definition a_protocol_struct.h:20
    uint8_t * data_buf
    Definition a_protocol_struct.h:23
    void * pack_info
    Definition a_protocol_struct.h:19
    uint16_t size
    Definition a_protocol_struct.h:24
    bool request_type
    Definition a_protocol_struct.h:21
    Definition a_protocol.h:313
    get_data_segment_func_t get_data_segment_func
    Definition a_protocol.h:345
    protocol_answer_obj_data_func_t protocol_answer_obj_data_func
    Definition a_protocol.h:350
  2. Инициализировать custom receiver
    void main()
    {
    }
    int main(int argc, char *argv[])
    Definition CMakeCCompilerId.c:853
    void set_device_custom_main_receiver(device_custom_receiver_callback custom_receiver)
    Definition main_receiver.c:40

Работа с параметрами

Обращение к параметрам идет по локальным ID
Флаг того, что параметр нужно записать - 8 бит в байте с номером параметра. То есть 0x80 - записать, 0x00 - не записывать.
Например:

  • 0x00 считать параметр 0
  • 0x01 cчитать параметр 1
  • 0x80 записать параметр 0
  • 0x81 записать параметр 1
  1. Чтение параметра Для того, чтобы прочитать параметр, нужно отправить команду с
    • request_type = PARAMETER (1)
    • wait_answer = 1
    • номером параметра в package_code.
  2. Запись параметра Для того, чтобы записать параметр, нужно отправить команду с
    • request_type = PARAMETER (1)
    • номером параметра в package_code c 0x80
    • data[] с данными для записи.