ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Иногда приходится придумывать некие коды, информирующие о той или иной ошибке при выходе из функции. К EXIT_SUCCESS и EXIT_FAILURE добавляются дополнительные. Не задавались ли вы целью привести коды в систему, чтобы пользоваться во всех случаях? Если да, поделитесь, пожалуйста идеями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
twix 0 24 апреля, 2018 Опубликовано 24 апреля, 2018 (изменено) · Жалоба ... Изменено 24 апреля, 2018 пользователем twix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arhiv6 18 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Например, есть стандартные системные наборы кодов ошибок: windows, linux. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Хорошие коды. Но для встроенной программы избыточны. Я предполагаю использовать максимум 8, и то не знаю, зачем мне столько. Есть у кубовского HAL 4 значения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 24 апреля, 2018 Опубликовано 24 апреля, 2018 (изменено) · Жалоба Я обычно пишу модульно. То есть есть драйвер, допустим, EEPROM-памяти. Он оформлен парой файлов EEPROM.c и EERPOM.h. Ну и для каждого драйвера свои сигнатуры завершения функций. unsigned int ReturnValue = EEPROM_LoadParameters(&EEPROM); if(ReturnValue == EEPROM_LOAD_ERROR_CRC) printf("WARNING! The EEPROM checksum does not match!\n\n\r"); else if(ReturnValue == EEPROM_LOAD_ERROR_ID) printf("WARNING! Installed someone else's EEPROM. Read and write operations will be invalid!\n\n\r"); В файле EEPROM.h при этом где-то в самом верху: #define EEPROM_LOAD_OK 0 #define EEPROM_LOAD_ERROR_CRC 1 #define EEPROM_LOAD_ERROR_ID 2 Но еще лучше сделать их не #define-ми, а enum-ами. В отладчике проще жить станет. Ну а вот так, допустим, у меня выглядит заголовочный файл драйвера обмена: #ifndef _EXCHANGE_H_ #define _EXCHANGE_H_ #define EXCHANGE_RECEIVE_BUFFER_SIZE 32 #define EXCHANGE_RECEIVE_OK 0 #define EXCHANGE_RECEIVE_ERROR 1 #define EXCHANGE_TRANSMIT_OK 0 #define EXCHANGE_TRANSMIT_ERROR 1 #define EXCHANGE_MESSAGE_HANDLING_OK 0 #define EXCHANGE_MESSAGE_HANDLING_ERROR 1 // структура дескриптора транзакций typedef struct { void *Data; volatile unsigned int Size; }TExchangeDescriptor; // структура принимаемых сообщений typedef struct { #define EXCHANGE_RECEIVE_COMMAND_SYSTEM_RESET 0x12345678 unsigned int Command; }TExchangeReceiveMessage; // функция приема данных по внешнему каналу обмена unsigned int EXCHANGE_ReceiveData(TExchangeDescriptor *ExchangeRxDescriptor, unsigned int Timeout); // функция отправки данных по внешнему каналу обмена unsigned int EXCHANGE_TransmitData(TExchangeDescriptor *ExchangeTxDescriptor); // функция обработки принятых сообщений unsigned int EXCHANGE_ReceiveMessageHandler(TExchangeReceiveMessage *ExchangeReceiveMessage); #endif Я обычно в коде логгирую все исключительные ситуации или просто поведение системы в критических участках или интересующих меня местах, поэтому в коде довольно просто писать лог (см. первый блок кода). Но это все дело вкуса, ИМХО. Изменено 24 апреля, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Меня немного смущает, что имя тип возвращаемого кода выглядит "солиднее" имени самой функции. fpgaConfigRetcode_t Fpga_config(void) В HAL имеется следующее: typedef enum { HAL_OK = 0x00U, HAL_ERROR = 0x01U, HAL_BUSY = 0x02U, HAL_TIMEOUT = 0x03U } HAL_StatusTypeDef; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? typedef enum { SUCCESS_OK, // 0 ERROR_GENERAL_FAILURE, // 1 _UNSPECIFIED ERROR_INVALID_FUNCTION, // _INVALID_HANDLE, _NOT_IMPLEMENTED ERROR_INVALID_PARAMETER, // _INVALID_ARGUMENT, _BAD_COMMAND ERROR_NOT_FOUND, // _FILE, _PATH ERROR_DEVICE_FAILED, // _DEVICE_NOT_EXIST ERROR_INVALID_ACCESS, // _ACCESS_DENIED, _LOCK ERROR_NOT_READY, // _BUSY, _LOCK ERROR_TIMEOUT, ERROR_MEMORY, // _OUT_OF_MEMORY, _BUFFER_EXCEEDED ERROR_POINTER, ERROR_INVALID_DATA, // _READ_FAULT ERROR_WRITE_FAULT, ERROR_PROTECT, // _WRITE_PROTECT ERROR_VERIFY, // _INVALID_CRC, _INVALID_PASSWORD ERROR_UNEXPECTED // _ABORT } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? Всё зависит от вашей задачи, если вам хватает, то годится. Посмотрел свои настройки в текущем проекте, большая часть совпадает. Но вот для примера, что у меня enum TRetVal { /* Common result values */ rvOK = 0x00, // Операция завершена без ошибок rvFAILED = 0x01, // Операция завершена с ошибкой (общая ошибка) rvCRC_FAILED = 0x02, // Подсчитанная КС неверна rvSETTING_ERROR = 0x03, // Параметры настроек заданы неверно rvTIME_OUT = 0x05, // Операция завершена с таймаутом rvUSER_CANCEL = 0x06, // Выполнение операции прервано пользователем rvPARAM_INCORRECT = 0x0b, /** В функцию переданы неверные параметры */ rvVIRT_FUNC = 0x0c, /** Функция виртуальная, нет реализации */ rvNULL_POINTER = 0x0d, /** Попытка обратиться по нулевому указателю */ rvBUSY = 0x0f, /** Процесс занят */ rvNOT_CONNECTED = 0x11, /* Соединение не установлено */ rvOUT_OF_MEMORY = 0x12, /* Закончилась память в куче */ /*CIRCLE BUFFER*/ rvBUFFER_OVERFLOW = 0x57, /** Переполнение буфера */ rvBUFFER_EMPTY = 0x58, /** Буфер данных пуст */ rvBUFFER_FULL = 0x59, /** Буфер данных заполнен */ /* Measure core */ rvOFFSET_ERROR = 0x60, /** Погрешность смещения в одном из токовых каналов */ rvCANT_CALIBRATE = 0x61, /** Невозможно откалибровать */ rvNOT_CALIBRATED = 0x62, // Прибор не откалиброван rvALRDY_RUN = 0x63, /** Сбор данных уже запущен */ rvALRDY_STOPPED = 0x64, /** Сбор данных уже остановлен */ /* Non-Volatile Memory */ rvDISK_WRITE_ERROR = 0x70, /** Ошибка записи в микросхему памяти */ rvDISK_NOT_FOUND = 0x71, /** Не найдена микросхема памяти */ /* Drivers */ rvCLOSE = 0x80, /* Устройство закрыто */ rvOPEN_ERROR = 0x81, /* Ошибка открытия драйвера, например не можем считать ID-микросхемы*/ }; И всё равно не редки ситуации, когда выясняется, что какому-то уникальному модулю нужен свой код ошибки, которого ещё нет. И приходится добавлять. Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Всё зависит от вашей задачи, если вам хватает, то годится. Посмотрел свои настройки в текущем проекте, большая часть совпадает. Но вот для примера, что у меня И всё равно не редки ситуации, когда выясняется, что какому-то уникальному модулю нужен свой код ошибки, которого ещё нет. И приходится добавлять. Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"? Спасибо, изучу. Идентифицировать буду сразу по возвращению из вызываемой функции, не дожидаясь завершения работы вызывающей функции. Мне столько кодов не нужно. А если случится непредвиденная ошибка, можно выдать код из наиболее подходящих, или unspecified. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 24 апреля, 2018 Опубликовано 24 апреля, 2018 (изменено) · Жалоба Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? Если пишете для себя - делайте как угодно. Если есть хоть малейшая вероятность, что с вашим кодом будут работать другие люди, то лучше возьмите любой из стандартов, таким, какой он есть, полностью и без самодельных улучшений. Изменено 24 апреля, 2018 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Если пишете для себя - делайте как угодно. Если есть хоть малейшая вероятность, что с вашим кодом будут работать другие люди, то лучше возьмите любой из стандартов, таким, какой он есть, полностью и без самодельных улучшений. Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. Писал выше, мне много кодов не надо. Сначала хотел 4, потом 8, остановлюсь на 16. Полбайта займет, цэ гарно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 24 апреля, 2018 Опубликовано 24 апреля, 2018 (изменено) · Жалоба Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. biggrin.gif То, что вы для себя скомпилировали - совсем не стыдно. Просто при передаче кода другим людям хорошо использовать стандартные библиотеки - эти самые другие люди не изучают то, что не надо изучать, и даже не задумываются об этом - они просто видят знакомое, и работают без лишних затрат времени. Изменено 24 апреля, 2018 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Э, если бы работа в группе заключалась в использовании только стандартных конструкций, сколько бы нервов было спасено. Но это - утопия, пмсм. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"? Возвращать PC/LR и по мап файлу смотреть что откуда? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 78 24 апреля, 2018 Опубликовано 24 апреля, 2018 · Жалоба Иногда приходится придумывать некие коды, информирующие о той или иной ошибке при выходе из функции. К EXIT_SUCCESS и EXIT_FAILURE добавляются дополнительные. Не задавались ли вы целью привести коды в систему, чтобы пользоваться во всех случаях? Если да, поделитесь, пожалуйста идеями. Идея одна - у всех функций коды разные. Тем более функции живут на разных уровнях иерархии. Группировать смысла немного. Поэтому есть 0 = SUCCESS, остальные коды пишутся и обзываются по порядку появления в функции. Название формирую из уровня иерархии, например HAL_ плюс библиотека _UART и сокращенное название. Сокращенные названия можно брать из стандартных систем, типа Windows/UNIX Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться