Jump to content

    
Sign in to follow this  
kadrum

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

Recommended Posts

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

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

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

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

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

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

 

Share this post


Link to post
Share on other sites

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

 

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

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

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

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

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

 

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

Share this post


Link to post
Share on other sites

Делаем функцию типа 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;
}

 

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
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);
}

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this