Перейти к содержанию
    

Как правильно объявить extern для typedef?

1 hour ago, Arlleex said:

не получится (в общем случае)

Последние 20 лет получалось всегда.

1 hour ago, Arlleex said:

Кодозависимый протокол с фреймером на таймингах не состыковать практически с любым ПК

Стыкуется без проблем. Правда, китайские RS485-USB не использую.

21 minutes ago, jcxz said:

Или всё-таки - на приоритете пользовательского приложения?

Именно так. Модбас достаточно продуманный протокол, поэтому распознать в сплошном потоке его фреймы не сложно. Делали и на Линукск, и на MiniOS7, и даже на Винде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, artemkad сказал:

Выглядит все там как-то громоздко... На мой взгляд.

У меня так. В любом периодическом процессе вызывается декодер входящего потока

Спойлер
#define MAX_RX_MSG_SIZE 128


static union uRxMsg {
  struct {
  } UserExchangeStruct1;
  
  struct {
  } UserExchangeStruct2;
  
  ...
  
  u8 byte[MAX_RX_MSG_SIZE];
} RxMsg;


static void decodeRxFlow() {
#define READ_BUF_SIZE 16
  static u8        buf[READ_BUF_SIZE];
         u32 const charQnt = nsUART::readRxFIFO(buf, arrdpth(buf));
  
  for(u32 i = 0; i < charQnt; ++i) {
    static bool     isFlowSync = false;
    static u32      msgLen;
    static u8       oldChar;
           u8 const curChar = buf[i];
    
    if(msgLen == MAX_RX_MSG_SIZE && curChar != 0xC0)
      isFlowSync = false;
    
    if(curChar != oldChar && oldChar == 0xC0)
      msgLen = 0, isFlowSync = true;
    
    if(isFlowSync) {
      if(oldChar == 0xDB) {
        if(curChar == 0xDC)
          RxMsg.byte[msgLen++] = 0xC0;
        else if(curChar == 0xDD)
          RxMsg.byte[msgLen++] = 0xDB;
        else isFlowSync = false;
      }
      else if(curChar != 0xC0) {
        if(curChar != 0xDB)
          RxMsg.byte[msgLen++] = curChar;
      }
      else parseRxMsg(&RxMsg, msgLen),
           isFlowSync = false;
    }
    
    oldChar = curChar;
  }
}

Захваченные декодированные данные кладутся в RxMsg и вызывается пользовательская parseRxMsg(), в которой происходит обработка входящих сообщений.

А передача еще проще

Спойлер
static void sendMsg(u8 const *msg, u32 len) {
#define WRITE_BUF_SIZE 16
  static u8  buf[WRITE_BUF_SIZE];
         u32 i = 1;
  
  buf[0] = 0xC0;
  
  for(u32 j = 0; j < len; ++j) {
    u8 const curChar = msg[j];
    u8       escChar = 0;
    
    if(curChar == 0xC0)
      buf[i]  = 0xDB,
      escChar = 0xDC;
    else if(curChar == 0xDB)
      buf[i]  = 0xDB,
      escChar = 0xDD;
    else buf[i] = curChar;
    
    if(++i == arrdpth(buf))
      nsUART::writeTxFIFO(buf, i), i = 0;
    
    if(escChar != 0) {
      buf[i] = escChar;
      
      if(++i == arrdpth(buf))
        nsUART::writeTxFIFO(buf, i), i = 0;
    }
  }
  
  buf[i] = 0xC0;
  
  nsUART::writeTxFIFO(buf, i + 1);
}


Функции кодера/декодера SLIP написаны так, чтобы сократить кол-во обращений к (возможно) тяжелым функциям чтения/записи FIFO UART (чтобы побайтно не теребонить, когда можно разом).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 минуту назад, Arlleex сказал:

Выглядит все там как-то громоздко...

Есть такое. Но там все есть  и даже чуть больше (CRC), достаточно прозрачно, а потому начинающему есть от чего оттолкнуться.

ЗЫ. Кстати, пересмотрел еще раз - не так уж и громоздко. Всего лишь использовали switch вместо if и байт-состояния(что как по мне перспективнее) вместо oldChar.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 часов назад, artemkad сказал:

Есть такое. Но там все есть  и даже чуть больше (CRC), достаточно прозрачно, а потому начинающему есть от чего оттолкнуться.

CRC к SLIP отношения никакого не имеет, добавлять контрольные суммы и сверять их это задача вышестоящего протокола.
 

7 часов назад, artemkad сказал:

ЗЫ. Кстати, пересмотрел еще раз - не так уж и громоздко. Всего лишь использовали switch вместо if и байт-состояния(что как по мне перспективнее) вместо oldChar.

С точки зрения скорости побайтовой обработки не очень перспективно...

P.S. Я ради интереса загнал этот код в онлайн компилятор и сразу же нашел 2 серьезных бага парсера входящих сообщений. Мой же отработал корректно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

59 минут назад, Arlleex сказал:

CRC к SLIP отношения никакого не имеет

Дык потому и "и даже чуть больше". Ему ведь не SLIP надо, а данные передавать

1 час назад, Arlleex сказал:

С точки зрения скорости побайтовой обработки не очень перспективно...

Если не рассматривать DMA - по скорости без особой разницы. Самая медленная там скорость это скорость прихода символов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...