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

scanf() без зависания

Пишу на Си под AVR.

Подскажите, пожалуйста, как реализовать функцию, принимающую сообщение из UART, но если сообщения долго нет - функция вернет код ошибки [-1].

Функция должна завершать работу при наступлении хотябы одного события:

- имеется полное сообщение

- прошел таймаут времени

Заранее спасибо.

 

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


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

Конечный автомат. Для отсчета таймаута использовать любой таймер либо считать количество итераций в состоянии ожидания символа.

 

В общем виде задача имеет множество решений. Для правильного выбора надо знать, по какому признаку определять "имеется полное сообщение" и какие еще критерии важны:

- если минимальный размер, то пишем свои узкоспециальные функции, если размер не важен - можно использовать универсальные библиотечные, например sscanf

- важна ли скорость обработки символа, т.е. можно обрабатывать поток "на лету" или времени хватает только на укладывание символа в буфер и проверки признаков конца пакета

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

- сколько доступно ОЗУ, т.е. хватит ли его на буфер для целого входящего пакета, или же этот входящий пакет опять же нужно разбирать на лету, выдергивая только нужные данные.

 

Примерно так.

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


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

Делаем функцию типа getchar, например для avr-libc@gcc

#include <stdio.h>
static FILE my_stdin = FDEV_SETUP_STREAM(NULL, getchar,
                                             _FDEV_SETUP_READ);
int getchar     (     FILE *      __stream    )
{
}

И туда пишем всю обработку. При таймауте или иной бяке должна возвращать -1

 

main() выглядит так

int main(void)
{
  stdin=my_stdin;// теперь можно использовать scanf()
// blah-blah-blah
  return 0;
}

 

В линкере нужно подключить нужную либу (варианты минимальный или полный)

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


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

Доброго времени суток.

Собственно сабж (scanf без зависания), но для Terminal IO в IAR. Как можно реализовать? Неплохо бы найти реализацию LowIO функции __write/__read для её доработки в рамках гибкого использования Terminal IO в IAR.

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


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

11 hours ago, dlsh said:

Собственно сабж (scanf без зависания), но для Terminal IO в IAR. 

Разложите "мух и котлет" отдельно. Используйте вместо scanf sscanf. Собственно scanf не виснет, виснет ожидание по приему, какойнибудь getc() до получения CR.

C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.3\xxxxxx\src\lib\dlib\

__dbg_xxwrite.c, dbg_xxread.c

/* Low-level debugger interface to the "__write" function. */
/* Copyright 2003-2010 IAR Systems AB.  */

#include "__dbg_.h"
#include <yfuns.h>

/*
 * When buf is NULL the handle should be flushed. When the handle is -1 then
 * all open handles should be flushed.
 */

size_t __write(int handle, const unsigned char *buf, size_t size)
{
  if (buf == 0)
  {
    /* Flushing is not supported by the debugger. */
    return 0;
  }
  return __dwrite(handle, buf, size);
}

(пере/до)писываете до полного удовлетворения ТЗ.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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