Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Коды завершения функции
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2, 3
jcxz
Цитата(AlexandrY @ May 3 2018, 20:46) *
большинство переменных глобальные сейчас 393654 строки, около 20 разных задач, 1100 файлов.
...
Практически любую ошибку могу найти в течении дня.

Ага... сказочник..... Языком все горазды находить. biggrin.gif
Хотя.... используете только глобальные переменные... а как же функции? все рабочие переменные в них - тоже глобальные??? wacko.gif а как же тогда многозадачность? для каждой из 20и задач своя копия всех функций со всеми переменными? А то может и функций нет, а только копипаст? biggrin.gif
Пожалуй тогда поиск ошибки за день в таком коде выглядит менее сказочно... и становится понятным откуда такое количество строк... biggrin.gif
AlexandrY
Цитата(haker_fox @ May 4 2018, 04:22) *
А как бы вы поступили, к примеру в следующем случае: пользователь жмёт кнопку запуска двигателя, а у двигателя отказал датчик (любой). Запуск без датчика невозможет в принципе, либо возможен, но в ограниченном режиме. Как передать эту "мелкую" ошибку от платы датчика к плате управления двигателем, а затем - наверх скаде?

Ну что, я как раз таким занимаюсь.
Тут надо отделить стандартные решения на PLC и решения на собственных контроллерах.
Приходилось проектировать и то и другое.
Буквально несколько дней назад в новом аэропорту около Мельбурна мужики взяли и никого не спросив переставили местами управляющие ящики с электрикой и PLC.
Ящики внешне похожи, но имеют разный состав модулей ввода-вывода.
Нажмите для просмотра прикрепленного файла
Честно на такую ошибку я не рассчитывал. Ящики то были пронумерованы.
Так вот в PLC все переменные глобальные! Програма там содержала под два десятка программных модулей, более 500 глобальных переменных.
В то что можно назвать SCADA ( а точнее удаленный HMI) по EtherCAT не передавались в моем случае никакие коды ошибок.
PLC содержат глобальные переменные счетчиков ошибок и регистров ошибок. К ним имеют доступ все HMI в сети. Т.е. имеем вид связи поставщик-подписчик или как-то так.
Ошибок вылезло не одна, а куча.
Но мужики посмотрели в окне HMI состояния переменных разных ошибок (ну они были выведены в виде анимации) и довольно быстро сообразили в чем дело.

В собственных контроллерах у меня практически также. Моя, так назовем, SCADA на базе пакета FreeMaster читает из дивайса базу публикуемых глобальных! переменных.
И сама уже в зависимости от конфигурации HMI читает эти переменные прямо из памяти устройства. Т.е. опять коммуникация по принципу поставщик-подписчик.

Итог - все ошибки есть глобальные переменные. Да они могут кодироваться. А иногда я просто их реализую как строки содержащие текст описания ошибки.
Таким образом я давно уже не пишу функций передающих коды ошибок. Максимум мои функции отдают OK или ERROR.

Передача кодов ошибок из функции в функцию куда-то наверх, немодно и несовременно.
А еще усложняет отладку поскольку ставить брекпойнт вам надо не в функции источнике ошибки, а где то наверху.
Иначе получите переизбыток брекпойнтов и они будут во Flash, а такие брекпойнты небезопасны. Вообщем одни проблемы с вашим подходом.
haker_fox
Остаюсь при своём мнении: передавать коды ошибок наверх для меня удобно)
Кстати, можно сделать такой тип для ошибки
CODE
typedef struct {
    bool ok; /// true if everything is ok
    void * extparams; /// pointer to whatever you imagine
}CodeResult;


т.е. в простейшем варианте поле ok показывает была ли ошибка вообще, и если была, то можно указатель extparams привести к любому типу, расшифровывающему ошибку (variadic, string и т.п.). А можно сделать его 0, тогда это значит, что параметров нет.
Forger
Цитата(haker_fox @ May 7 2018, 17:25) *
то можно указатель extparams привести к любому типу, расшифровывающему ошибку (variadic, string и т.п.)

Ага, значит функция возвращающая ошибку, еще и должна сообщить каким-то раком какого именно типа данных и где именно эти данные лежат.
А принимающая часть кода должна при это точно знать о чем идет речь.
Тогда в эту структуру ошибку нужно добавлять поле, которое определяет тип данных, а потом по switch-case разобрать не только код ошибки, но еще и что за указатель "прилетел"
Также нужно быть уверенных, что указатель указывает на существующие актуальные данные - не дай бог вызывающая функция положит туда указатель на структуру, размещенную локально (в стеке).

Не проще ли сразу через любимые глобальные переменные передать и код ошибки и указатель и т.п?
Например, функция возвращает true/false, а код ошибки с прочей требухой класть в глобальную структуру. Нет ошибок, нет смысла и лезть в эту структуру.
Если нужно извращаться дальше, то недалеко и до журнала ошибок - массив подобных структур.



haker_fox
QUOTE (Forger @ May 7 2018, 22:55) *
Не проще ли сразу через любимые глобальные переменные передать и код ошибки и указатель и т.п?
Например, функция возвращает true/false, а код ошибки с прочей требухой класть в глобальную структуру. Нет ошибок, нет смысла и лезть в эту структуру.
Если нужно извращаться дальше, то недалеко и до журнала ошибок - массив подобных структур.

Я лишь идею предложил, а реализацией не занимался. Вполне возможно, что не всё так гладко на первый взгляд. Зато - гибко. Можно к любому типу привести.
Forger
Цитата(haker_fox @ May 7 2018, 17:59) *
Я лишь идею предложил, а реализацией не занимался.

Сначала нужно описать идею "от" и "до". Хотя бы на бумажке (ворде, паинте и т. п.), а уже потом браться за реализацию.
А пока будете "рисовать" все эти идеи, куча из них "отвалятся" сами собой еще до реализации wink.gif
Вангую, что останется самая простая и примитивная из них. Либо выйдут несколько вариантов разной сложности под разные случаи применения.
А универсальное решение в любой области - утопия.
demiurg_spb
Цитата(Forger @ May 7 2018, 18:05) *
Вангую, что останется самая простая и примитивная из них.
Ага))) и звать её ssize_t
подробнее тут
AlexandrY
Цитата(haker_fox @ May 7 2018, 17:25) *
Остаюсь при своём мнении: передавать коды ошибок наверх для меня удобно)

С другой стороны откуда у вас так много ошибок?
Почему вы не можете их исправить?
Или это по сути не ошибки, а некие маркеры разных состостояний и вы просто имеете дело с неявными автоматами состояний.
Тогда лучше привести их к явному виду.

Настоящие ошибки - это ценная находка.
Когда такие случаются я собираю о них максимум информации.
Там и их количество с момента перезапуска, и место(имя функции и номер строки) где возникла,
и точное время в микросекундах когда возникла или какая-либо другая сопутствующая статистика связанных сигналов.
Это там где я жду ошибки. Очень часто безрезультатно, но зато когда ловлю я уже почти знаю их причину.
Forger
Мне кажется, что опять пошла путаница с рабочими ошибками и критическими сбоями.
Обработка рабочих ошибок - штатный режим работы приложения.
А задача программиста предусмотреть реакцию на все задокументированные ошибки.
Чем меньше предусмотрено различных рабочих ошибок, тем проще их обработка.
Иначе велик риск наплодить новых ошибок, заметьте, на абсолютно ровном месте smile3046.gif

А вот критические/аварийные сбои, при которых работа дальше уже невозможна или невозобновима, нужно журналировать, писать в логи и т.п, собирая максимум информации в стиле "где/что/когда".
Но для этого уже существую готовые открытые сторонние решения, в т. ч. встроенные даже в среду. Нужно лишь освоить готовые продукты.

И получается, что нагромождение чудовищных надстроек над банальным кодами ошибок той или иной банальной функции - аки "Сизифов труд" cranky.gif
AlexandrY
Цитата(Forger @ May 7 2018, 22:40) *
Мне кажется, что опять пошла путаница с рабочими ошибками и критическими сбоями.

Интересный термин "рабочие ошибки"
Ну какие могут быть ошибки в глубоко встраиваемой системе.
Нет, если у вас некий инструмент, который без участия человека-оператора не работает, то еще понятно.
А если у вас силовой инвертер, контроллер квадрокоптера или робота, то какие там могут быть "рабочие ошибки"?
Если они не приводят к аварии или деградации - это не ошибки, а штатная передача состояний.
one_eight_seven
Цитата
контроллер квадрокоптера или робота, то какие там могут быть "рабочие ошибки"?

Обрыв канала связи.
Ошибка данных в памяти, которую обнаруживает, но не исправляет ECC.
Forger
Цитата(AlexandrY @ May 7 2018, 22:53) *
Интересный термин "рабочие ошибки"

Я уж не знаю как еще проще разжевать такие очевидные вещи, но попробую еще раз: "рабочие ошибки" - в моем понимании ошибки, возвращаемые вызываемыми функциями,
т.е. ошибки, которые приложение может обработать самостоятельно - именно так, как это предусмотрел программист.
Или по-другому: речь про ВСЕ коды, возвращаемые своими или сторонними функциями.

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

Или вы скажите, что отсутствие реакции на хотя бы на одну задокументированную ошибку (код, возвращаемый любой фукцией) - это нормально и можно дальше работать?
AlexandrY
Цитата(Forger @ May 7 2018, 23:15) *
Или вы скажите, что отсутствие реакции на не предусмотренную в коде ошибку - это нормально и можно дальше работать?

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

Ошибка - это то что реально наносит системе ущерб. Я так себе представляю.
exception - это не ошибка, как вы понимаете, а такой способ раннего выхода из функций по специальным состояниям.

Т.е. я предлагаю отделять чисто программистское понятие ошибки от ошибки с точки зрения разработчика дивайса.
Forger
Цитата(AlexandrY @ May 7 2018, 23:41) *
Если вы задаетесь вопросом как же перечислить все эти состояния, то у вас проблема с неполнотой автомата либо с неправильной его архитектурой.
У меня нет проблем " с неполнотой автомата либо с неправильной его архитектурой".
Не путайте "теплое" с "мягким" - еще раз прочитайте название этой темы.

Цитата
Ошибка - это то что реально наносит системе ущерб. Я так себе представляю.

Код завершения функции обычно несет в себе код некой ошибки, причину, почему функция не отработала правильно.
Если функция не отработала правильно, то это - ошибка. Или для вас это не ошибка, а что-то другое?



Цитата
Т.е. я предлагаю отделять чисто программистское понятие ошибки от ошибки с точки зрения разработчика дивайса.
Программисткие ошибки (или ошибки разработчика всего "дивайса") исправляются еще на этапе отладки и разработки, и речь в этой теме явно не про них. bb-offtopic.gif
haker_fox
QUOTE (Forger @ May 7 2018, 23:05) *
А универсальное решение в любой области - утопия.

Если оно претендует на универсальность во всём, то да, возможно, что и утопия.

QUOTE (AlexandrY @ May 8 2018, 03:12) *
Почему вы не можете их исправить?

Например, закорочена шина данных. Значит возникла ошибка передачи данных между микроконтроллером, и, к примеру, АЦП. Я считаю, что это именно ошибка, ане состояние. И вот как её исправить? Это же аппаратная проблема. И чтобы её проще было локаллизовать, и исправить, я и передаю коды ошибок "наверх".
ViKo
Мне интнересна вся дискуссия, явно вышедшая за пределы начальной темы. Вопрос был про коды, какие может выдавать функция. В простейшем случае, действительно, хватило бы true и false. Но мне показалось правильным иметь более широкий диапазон ответов. Например, функция, выполняющая деление, может выдать ошибку "деление на ноль". Или "не хватает памяти" для создания временного массива. Это - универсальные ответы, и о них был вопрос. Их не нужно документировать, а просто использовать в вызывающей функции.
Другое дело - ошибки, события, возникающие в работе конкретного устройства. Которые нужно неким образом донести до потребителя или разработчика. Здесь, понятно, универсальности быть не может. Глобальные переменные в данном случае не кажутся мне неправильным решением.
AlexandrY
Цитата(haker_fox @ May 8 2018, 03:46) *
Например, закорочена шина данных. Значит возникла ошибка передачи данных между микроконтроллером, и, к примеру, АЦП. Я считаю, что это именно ошибка, ане состояние. И вот как её исправить? Это же аппаратная проблема. И чтобы её проще было локаллизовать, и исправить, я и передаю коды ошибок "наверх".

Да это безусловно ошибка и она фатальная. Неизбежно приведет к деградации работы системы.
В риалтайме не исправляется, или вы знаете как это сделать?
Поэтому о ней надо собрать максимум информации.
Для этого, как говорится, организуется комплекс мероприятий, после того как появилось подозрение на такую ошибку. Именно после!
Самым невинным из которых будет рефакторинг кода. А самым тяжелым тюнинг всех выпущенных плат.

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

Или вот живой пример.
У меня RTOS. В ней есть такой неслабый список ошибок.
Он не полный. Относится только к ядру
CODE
#define MQX_INVALID_POINTER (MQX_ERROR_BASE|0x01)
#define MQX_INVALID_SIZE (MQX_ERROR_BASE|0x02)
#define MQX_NOT_RESOURCE_OWNER (MQX_ERROR_BASE|0x03)
#define MQX_OUT_OF_MEMORY (MQX_ERROR_BASE|0x04)
#define MQX_CORRUPT_MEMORY_SYSTEM (MQX_ERROR_BASE|0x05)
#define MQX_CORRUPT_STORAGE_POOL (MQX_ERROR_BASE|0x06)
#define MQX_CORRUPT_STORAGE_POOL_FREE_LIST (MQX_ERROR_BASE|0x07)
#define MQX_CORRUPT_STORAGE_POOL_POINTERS (MQX_ERROR_BASE|0x08)
#define MQX_INVALID_CHECKSUM (MQX_ERROR_BASE|0x09)
#define MQX_OUT_OF_TASK_DESCRIPTORS (MQX_ERROR_BASE|0x0A)
#define MQX_INVALID_MEMORY_BLOCK (MQX_ERROR_BASE|0x0B)
#define MQX_INVALID_PARAMETER (MQX_ERROR_BASE|0x0C)
#define MQX_CANNOT_CALL_FUNCTION_FROM_ISR (MQX_ERROR_BASE|0x0D)
#define MQX_INVALID_TASK_PRIORITY (MQX_ERROR_BASE|0x0E)
#define MQX_TASK_QUEUE_EMPTY (MQX_ERROR_BASE|0x0F)
#define MQX_NO_TASK_TEMPLATE (MQX_ERROR_BASE|0x10)
#define MQX_INVALID_TASK_STATE (MQX_ERROR_BASE|0x11)
#define MQX_INVALID_TASK_ID (MQX_ERROR_BASE|0x12)
#define MQX_INVALID_PROCESSOR_NUMBER (MQX_ERROR_BASE|0x13)
#define MQX_INVALID_VECTORED_INTERRUPT (MQX_ERROR_BASE|0x14)
#define MQX_INVALID_TEMPLATE_INDEX (MQX_ERROR_BASE|0x15)
#define MQX_INVALID_CONFIGURATION (MQX_ERROR_BASE|0x16)

/* Kernel component error codes */
#define MQX_COMPONENT_EXISTS (MQX_ERROR_BASE|0x17)
#define MQX_COMPONENT_DOES_NOT_EXIST (MQX_ERROR_BASE|0x18)
#define MQX_INVALID_COMPONENT_HANDLE (MQX_ERROR_BASE|0x19)
#define MQX_INVALID_COMPONENT_BASE (MQX_ERROR_BASE|0x1A)
#define MQX_INVALID_COMPONENT_NAME (MQX_ERROR_BASE|0x1B)
#define MQX_INVALID_HANDLE (MQX_ERROR_BASE|0x1C)

/* Test error codes */
#define MQX_CORRUPT_QUEUE (MQX_ERROR_BASE|0x1D)
#define MQX_INVALID_TASK_QUEUE (MQX_ERROR_BASE|0x1E)
#define MQX_INVALID_LWSEM (MQX_ERROR_BASE|0x1F)
#define MQX_CORRUPT_INTERRUPT_STACK (MQX_ERROR_BASE|0x20)

/* Initialization error return codes */
#define MQX_KERNEL_MEMORY_TOO_SMALL (MQX_ERROR_BASE|0x21)
#define MQX_COULD_NOT_CREATE_IPC_TASK (MQX_ERROR_BASE|0x22)
#define MQX_TOO_MANY_PRIORITY_LEVELS (MQX_ERROR_BASE|0x23)
#define MQX_TOO_MANY_INTERRUPTS (MQX_ERROR_BASE|0x24)
#define MQX_DUPLICATE_TASK_TEMPLATE_INDEX (MQX_ERROR_BASE|0x25)
#define MQX_TIMER_ISR_INSTALL_FAIL (MQX_ERROR_BASE|0x26)

/* Scheduler error codes */
#define MQX_SCHED_INVALID_POLICY (MQX_ERROR_BASE|0x27)
#define MQX_SCHED_INVALID_PARAMETER_PTR (MQX_ERROR_BASE|0x28)
#define MQX_SCHED_INVALID_PARAMETER (MQX_ERROR_BASE|0x29)
#define MQX_SCHED_INVALID_TASK_ID (MQX_ERROR_BASE|0x2A)

/* I/O error codes */
#define MQX_INVALID_IO_CHANNEL (MQX_ERROR_BASE|0x2B)
#define MQX_IO_OPERATION_NOT_AVAILABLE (MQX_ERROR_BASE|0x2C)

/* IPC error codes */
#define MQX_INTER_PROCESSOR_INIT_FAILED (MQX_ERROR_BASE|0x2D)
#define MQX_IPC_INVALID_MESSAGE (MQX_ERROR_BASE|0x2E)
#define MQX_IPC_SERVICE_NOT_AVAILABLE (MQX_ERROR_BASE|0x2F)
#define MQX_IPC_ROUTE_EXISTS (MQX_ERROR_BASE|0x30)

/* User memory error codes */
#define MQX_MEM_POOL_TOO_SMALL (MQX_ERROR_BASE|0x31)
#define MQX_MEM_POOL_INVALID (MQX_ERROR_BASE|0x32)

/* MMU error codes */
#define MQX_OUT_OF_MMU_PAGE_TABLES (MQX_ERROR_BASE|0x33)
#define MQX_MMU_CONTEXT_EXISTS (MQX_ERROR_BASE|0x34)
#define MQX_MMU_CONTEXT_DOES_NOT_EXIST (MQX_ERROR_BASE|0x35)
#define MQX_MMU_PARENT_TASK_CANNOT_BE_MMU (MQX_ERROR_BASE|0x36)

/* LWSEM wait timeout error codes */
#define MQX_LWSEM_WAIT_TIMEOUT (MQX_ERROR_BASE|0x37)

/* LWMEM error codes */
#define MQX_LWMEM_POOL_INVALID (MQX_ERROR_BASE|0x38)

/* LWEVENT error codes */
#define MQX_LWEVENT_INVALID (MQX_ERROR_BASE|0x39)

/* LWTIMER error codes */
#define MQX_LWTIMER_INVALID (MQX_ERROR_BASE|0x40)

/* UNHANDLED error codes */
#define MQX_UNHANDLED_INTERRUPT (MQX_ERROR_BASE|0x41)

/* RTC error codes */
#define MQX_RTC_UNLOCK_FAILED (MQX_ERROR_BASE|0x42)

#define MQX_NO_USER_TASKS (MQX_ERROR_BASE|0x43)
#define MQX_TOO_MANY_USER_TASKS (MQX_ERROR_BASE|0x44)
#define MQX_ACCESS_ERROR (MQX_ERROR_BASE|0x45)

#define MQX_INVALID_DEVICE (MQX_ERROR_BASE|0x46)
#define MQX_TASKQ_CREATE_FAILED (MQX_ERROR_BASE|0x47)

/* TLSF error codes */
#define MQX_TLSF_POOL_INVALID (MQX_ERROR_BASE|0x48)
#define MQX_TLSF_TOO_LARGE_BLOCK (MQX_ERROR_BASE|0x49)

/* MMU error codes - continued*/
#define MQX_MMU_ERROR (MQX_ERROR_BASE|0xfe)

#define MQX_ERROR (MQX_ERROR_BASE|0xff)


И что вы думаете делается с этими кодами ошибок в самой RTOS?
Ничего! Часто функции вызываются без проверки возвращаемого значения, а в лучшем случае все передается по цепочке вверх до самого пользовательского API.
И я там эти коды тоже не проверяю. Ну максимум код таймаута у некоторых объектов синхронизации.
Потому как безполезно. Т.е. как правило уже поздно и ничего исправить нельзя.
Но авторов RTOS понять можно, у них не было других средств.
А вот авторов приложений над RTOS уже понять нельзя, потому как у них есть куча других эффективных средств.
Forger
Цитата(ViKo @ May 8 2018, 06:59) *
Например, функция, выполняющая деление, может выдать ошибку "деление на ноль".

Это - уже критическая ошибка, ее можно избежать еще на этапе создания кода, добавив перед делением соотв. проверку.
Если этого не делать, то придется ставить ловушку для ВСЕГО кода с соотв. реакцией на подобное событие.

Цитата
Или "не хватает памяти" для создания временного массива.

Это - тоже критическая ошибка, обрабатывается также, как и деление на ноль (см. выше).
Но, правильно, имхо, вообще не использовать штатный механизма выделения памяти (malloc/free), а, использоваться специализированные решения, под конкрентные задачи.

Цитата
Это - универсальные ответы, и о них был вопрос.

На подобные ответы уже есть готовые решения, для этого не нужно создавать новую тему sm.gif
one_eight_seven
Цитата
Да это безусловно ошибка и она фатальная. Неизбежно приведет к деградации работы системы.
В риалтайме не исправляется, или вы знаете как это сделать?
Поэтому о ней надо собрать максимум информации.
Для этого, как говорится, организуется комплекс мероприятий, после того как появилось подозрение на такую ошибку. Именно после!


А если шина не закорочена? А просто обрыв канала связи, например, радиоканала с пультом управления. И канал связи может восстановиться. Или датчик в сети теряет базу (orphaning). Это всё ошибки в работе системы. С точки зрения автомата - это рабочие ситуации, но они все начинаются с возврата ошибок. То же получение Nack - ситуация стандартная, но ошибочная, в том, смысле, что это ошибка работы системы.
Forger
Цитата(one_eight_seven @ May 8 2018, 08:58) *
А просто обрыв канала связи, например, радиоканала с пультом управления. И канал связи может восстановиться.

Это - не критическая ошибка, не фатальная. Т.е. "рабочая" ошибка. Поэтому и работать с ней нужно иначе (зависит от проекта, точнее от его ТЗ).

one_eight_seven
Цитата(Forger @ May 8 2018, 09:01) *
Это - не критическая ошибка, не фатальная. Т.е. "рабочая" ошибка. Поэтому и работать с ней нужно иначе (зависит от проекта, точнее от его ТЗ).

Товарищ, если вы внимательнее пересмотрите посты дискусии, вы увидите, что чуть выше я эти же ситуации привёл именно в качестве примера "рабочих ошибок", как ответ на вопрос
Цитата
...контроллер квадрокоптера или робота, то какие там могут быть "рабочие ошибки"?
AlexandrY
Цитата(one_eight_seven @ May 8 2018, 08:58) *
А если шина не закорочена? А просто обрыв канала связи, например, радиоканала с пультом управления. И канал связи может восстановиться. Или датчик в сети теряет базу (orphaning). Это всё ошибки в работе системы. С точки зрения автомата - это рабочие ситуации, но они все начинаются с возврата ошибок. То же получение Nack - ситуация стандартная, но ошибочная, в том, смысле, что это ошибка работы системы.

Блин у меня пульсометр постоянно теряет связь с часами.
Если я пожалуюсь на это производителю и скажу что это ошибка там чья-то, они будут смеяться мне в лицо.
Т.е. понимаете, на Верхнем уровне не нужны никому такие ошибки и с ними никто не будет разбираться. biggrin.gif
haker_fox
QUOTE (AlexandrY @ May 8 2018, 13:39) *
А с вашим понятием верха, создается ощущение как будто на верху вы только и ждете сбоев АЦП и там уже все готово к потере или искажению данных.

Зато, если произойдёт сбой, то я буду знать, где искать.

QUOTE (AlexandrY @ May 8 2018, 14:07) *
Если я пожалуюсь на это производителю и скажу что это ошибка там чья-то, они будут смеяться мне в лицо.

Ну у каждого свой подход)
one_eight_seven
Цитата(AlexandrY @ May 8 2018, 09:07) *
Блин у меня пульсометр постоянно теряет связь с часами.
Если я пожалуюсь на это производителю и скажу что это ошибка там чья-то, они будут смеяться мне в лицо.
Т.е. понимаете, на Верхнем уровне не нужны никому такие ошибки и с ними никто не будет разбираться. biggrin.gif

У вас как, связь с реальностью не потеряна?
1. Вы купили некачественный товар, и вы имеете право требовать нормальной его работы.
2. Обрыв датчика нужно видеть на верхнем уровне. Потерю связи с беспилотником нужно видеть на пульте. Но обе эти вещи обработаются локально, поскольку они видны на обоих концах.
3. Возвращаясь к теме дискуссии, если беспилотник потерял связь с пультом, то функция, которая ждёт Ack (условно говоря), не должна возвращать OK, она должна вернуть либо FAIL, либо NO_ACK, либо NACK (в зависимости от того, что произошло), и это коды ошибочного завершения работы функции. Что с этим будет дальше - не дело функции, она вообще не должна "знать" что там дальше. Абстракции - это же основное, что должен знать разработчик.
ViKo
Цитата(Forger @ May 8 2018, 08:53) *
Это - уже критическая ошибка, ее можно избежать еще на этапе создания кода, добавив перед делением соотв. проверку.

Положим, так и делается. Америку не открыли.
Цитата
На подобные ответы уже есть готовые решения, для этого не нужно создавать новую тему sm.gif

Это мне решать.
juvf
Цитата(Forger @ May 8 2018, 10:53) *
вообще не использовать штатный механизма выделения памяти (malloc/free)
временные массивы обычно на стеке выделяются, типа int tempArray[1024]; конечно если стека не фватит - то фолаут! малоком можно избежать фалаута, но делать времянки в куче - мовитон. Как решение alloca - динамическое выделение памяти на стеке. Тут наверно будет это полезно, и организовать возврат ошибки вместо фалаута.
Forger
Цитата(one_eight_seven @ May 8 2018, 09:05) *
Товарищ...

Дискуссия постепенно ведет к холивару
juvf
ещё по теме..... вот функция объявлена как

ErCodeF1 myFunc1();

ErCodeF1 - тип енум из 3-х кодов. Я глянул этот енум и я понимаю, что может вернуть myFunc1(). Во первых, мне не нужно писать документацию на возвращаемые значения, всё понятно по именам в енуме, в крайнем случае комент на код ошибки в енуме. Во вторых я могу сделать обработку для каждого кода ошибок. Их всего 3 (один из них будет NO_ERROR, т.е. даже 2 кода ошибки.)

Тоже самое могу сказать про ErCodeF2 myFunc2();, ErCodeF4 myFunc4();, ErCodeF3 myFunc3() и т.д. у каждой функции только необходимое кол-во кодов ошибок.

Теперь делаем общий енум ошибок ErCode (или адский, как у AlexandrY), вызываем функцию ErCode yourFunc1(); какие возможные коды она вернёт? На какие коды ошибок писать обработчик? Нужно лезть в какие-то мануалы, читать описания....

неудобно. имхо.
Forger
Цитата(juvf @ May 8 2018, 09:42) *
неудобно. имхо.


Это еще мягко сказано wacko.gif
ViKo
Цитата(juvf @ May 8 2018, 09:42) *
...
Тоже самое могу сказать про ErCodeF2 myFunc2();, ErCodeF4 myFunc4();, ErCodeF3 myFunc3() и т.д. у каждой функции только необходимое кол-во кодов ошибок.
Теперь делаем общий енум ошибок ErCode (или адский, как у AlexandrY), вызываем функцию ErCode yourFunc1(); какие возможные коды она вернёт? На какие коды ошибок писать обработчик? Нужно лезть в какие-то мануалы, читать описания....

неудобно. имхо.

Не вижу разницы между первым и вторым. По мне, проще сложить все универсальные ошибки в одно перечисление, чем для каждой функции создавать свое. И в обоих случаях придется лезть как в описание ошибок, так и в функции, их порождающие.
Forger
Цитата(ViKo @ May 8 2018, 14:21) *
Не вижу разницы между первым и вторым. По мне, проще сложить все универсальные ошибки в одно перечисление,

А как тогда отделить "мух от котлет": какие ошибки функция может возвращать, а какие нет?
Например, как в коде, где применяется примитивная функция, которая возвращает лишь два значения, понять, на какие возвращаемые значения реагировать, а на какие нет?
Каждый раз при создании или чтении кода лезть в ее описание?

Все наверняка сталкивались с книгами, перегруженными поясняющими комментариями внизу страницы. Хорошо, если они внизу страницы, а если все собраны в одну кучу в конце книги?
one_eight_seven
Цитата
Все наверняка сталкивались с книгами, перегруженными поясняющими комментариями внизу страницы. Хорошо, если они внизу страницы, а если все собраны в одну кучу в конце книги?

Обратная аналогия. А если глоссарий будет не в конце книги, а в конце каждого раздела?
ViKo
Я предполагаю 2 перечисления - универсальные коды завершения функций и ошибки аппаратные.
Первое перечисление я показал в начале темы. Это некие перестраховки от неправильно полученных аргументов.
А второе - это то, что будет требовать выдачи пользователю или регулировщику. Например, "неисправен контроллер ЖКИ". Их еще "выпискивать" буду при включении. С этими ошибками прибор работать не может.
Как на основе первых переходить ко вторым - частное дело в каждом случае.
Forger
Цитата(one_eight_seven @ May 8 2018, 14:46) *
Обратная аналогия. А если глоссарий будет не в конце книги, а в конце каждого раздела?

© "Хрен редьки не слаще"
k155la3
Цитата(haker_fox @ May 7 2018, 17:59) *
Я лишь идею предложил, а реализацией не занимался. Вполне возможно, что не всё так гладко на первый взгляд. Зато - гибко. Можно к любому типу привести.
Реализация активно используется в Windows, один параметр используется как код события (коих множество типов), второй - указатель на евойные даннные (типо-зависимые).

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.