Попытка передать данные атомарно в течение ограниченного времени - PullRequest
0 голосов
/ 03 сентября 2018

В настоящее время я пишу код для беспроводного клиента на аппаратном уровне (в сборке 8051), в котором данные передаются обратно на сервер, только когда данные отправляются клиенту с того же сервера. Радиомодули, подключенные к клиенту и серверу, работают только в полудуплексном режиме.

Проблема в том, что я пытаюсь сделать данные атомарными.

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

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

Теперь вот часть, которая меня беспокоит.

У меня есть функция магистрали (вне прерывания таймера и последовательного прерывания), которая устанавливает различные значения в локальном буфере передачи.

Проблема в том, что частично через функцию вызывается прерывание, которое может копировать неверные данные. Я постараюсь объяснить в упрощенном коде:

Вот серийное прерывание. Если данные получены, они помещаются в приемный буфер. Аналогично, если данные передаются, они загружаются из буфера передачи:

Serial_interrupt:
   If byte is transmitted then
        If transmit buffer pointer is at end then
            Set transmit complete flag and end
        else
            Read next byte in buffer
        End If
      If byte is received then
        Set byte received flag
        Set Timer Overflow flag
        If received buffer pointer is at end then
            Set receive complete flag and end
        else
            set value in buffer to byte and advance pointer
        End If
 end_interrupt

Timer_interrupt:
     If byte received flag is set then
         clear byte received flag
     else
         reset receive pointer (void old data)
     end if
     If receive complete flag is set then
     clear receive complete flag
     copy data from userspace buffer to data transmit buffer **
     end if
 end_timer_interrupt

 Mainline:
  Set a value of a byte in userspace buffer **
  Set a value of a byte in userspace buffer **
  Set a value of a byte in userspace buffer **
  Do some other irrelevant action
 restart_mainline

Я надеюсь, что мой псевдокод облегчит мой вопрос. Меня интересуют предложения со звездами, потому что в основной процедуре я хочу установить три байта одновременно и отправить их все.

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

Например, вполне вероятно, что это произойдет, чего я не хочу:

 Mainline:
  Set a value of a byte in userspace buffer **
  Set a value of a byte in userspace buffer **
  --system detects byte and calls serial_interrupt function
  --timer function executes and userspace data is copied to transmit buffer
  Set a value of a byte in userspace buffer ****
  Do some other irrelevant action
 restart_mainline

в точке, где вы видите 4 звезды, первые два байта были успешно отправлены в первом пакете по сети, но третий байт не был обработан вовремя, поэтому он был отправлен в следующем пакете.

Есть ли способ, которым я могу настроить полный большой объем данных во времени, не отправляя какую-либо их часть из-за времени?

Пока что единственное, о чем я могу думать, это отключить прерывания во время установки значений и включить их снова после (я думаю, они называют этот критический раздел?), Но могу ли я что-нибудь еще сделать, чтобы решить эту проблему?

Аппаратное обеспечение, которое я использую, - AT89S52 с кристаллом 22.1184 МГц. Для выполнения каждой инструкции требуется не более 1 мкс, а размер фрагмента данных, который я заинтересован в отправке со скоростью 56 Кбит / с, составляет 10 байт.

...