|
|
  |
Коды завершения функции |
|
|
|
Apr 24 2018, 06:36
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Я обычно пишу модульно. То есть есть драйвер, допустим, 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-ами. В отладчике проще жить станет. Ну а вот так, допустим, у меня выглядит заголовочный файл драйвера обмена: CODE #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 Я обычно в коде логгирую все исключительные ситуации или просто поведение системы в критических участках или интересующих меня местах, поэтому в коде довольно просто писать лог (см. первый блок кода). Но это все дело вкуса, ИМХО.
Сообщение отредактировал Arlleex - Apr 24 2018, 06:41
|
|
|
|
|
Apr 24 2018, 09:47
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? 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 }
|
|
|
|
|
Apr 24 2018, 10:03
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (ViKo @ Apr 24 2018, 17:47)  Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? Всё зависит от вашей задачи, если вам хватает, то годится. Посмотрел свои настройки в текущем проекте, большая часть совпадает. Но вот для примера, что у меня CODE 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-микросхемы*/ }; И всё равно не редки ситуации, когда выясняется, что какому-то уникальному модулю нужен свой код ошибки, которого ещё нет. И приходится добавлять. Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"?
--------------------
Выбор.
|
|
|
|
|
Apr 24 2018, 10:12
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(haker_fox @ Apr 24 2018, 13:03)  Всё зависит от вашей задачи, если вам хватает, то годится. Посмотрел свои настройки в текущем проекте, большая часть совпадает. Но вот для примера, что у меня
И всё равно не редки ситуации, когда выясняется, что какому-то уникальному модулю нужен свой код ошибки, которого ещё нет. И приходится добавлять. Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"? Спасибо, изучу. Идентифицировать буду сразу по возвращению из вызываемой функции, не дожидаясь завершения работы вызывающей функции. Мне столько кодов не нужно. А если случится непредвиденная ошибка, можно выдать код из наиболее подходящих, или unspecified.
|
|
|
|
|
Apr 24 2018, 10:19
|
Знающий
   
Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664

|
Цитата Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится? Если пишете для себя - делайте как угодно. Если есть хоть малейшая вероятность, что с вашим кодом будут работать другие люди, то лучше возьмите любой из стандартов, таким, какой он есть, полностью и без самодельных улучшений.
Сообщение отредактировал one_eight_seven - Apr 24 2018, 10:19
|
|
|
|
|
Apr 24 2018, 10:25
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(one_eight_seven @ Apr 24 2018, 13:19)  Если пишете для себя - делайте как угодно. Если есть хоть малейшая вероятность, что с вашим кодом будут работать другие люди, то лучше возьмите любой из стандартов, таким, какой он есть, полностью и без самодельных улучшений. Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. Писал выше, мне много кодов не надо. Сначала хотел 4, потом 8, остановлюсь на 16. Полбайта займет, цэ гарно.
|
|
|
|
|
Apr 24 2018, 10:30
|
Знающий
   
Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664

|
Цитата Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. biggrin.gif То, что вы для себя скомпилировали - совсем не стыдно. Просто при передаче кода другим людям хорошо использовать стандартные библиотеки - эти самые другие люди не изучают то, что не надо изучать, и даже не задумываются об этом - они просто видят знакомое, и работают без лишних затрат времени.
Сообщение отредактировал one_eight_seven - Apr 24 2018, 10:32
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|