реклама на сайте
подробности

 
 
9 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Коды завершения функции
ViKo
сообщение Apr 24 2018, 05:26
Сообщение #1


Универсальный солдатик
******

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



Иногда приходится придумывать некие коды, информирующие о той или иной ошибке при выходе из функции. К EXIT_SUCCESS и EXIT_FAILURE добавляются дополнительные. Не задавались ли вы целью привести коды в систему, чтобы пользоваться во всех случаях? Если да, поделитесь, пожалуйста идеями.
Go to the top of the page
 
+Quote Post
twix
сообщение Apr 24 2018, 05:37
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 326
Регистрация: 4-11-15
Пользователь №: 89 174



...

Сообщение отредактировал twix - Apr 24 2018, 10:21
Go to the top of the page
 
+Quote Post
arhiv6
сообщение Apr 24 2018, 05:46
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423



Например, есть стандартные системные наборы кодов ошибок: windows, linux.


--------------------
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 05:59
Сообщение #4


Универсальный солдатик
******

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



Хорошие коды. Но для встроенной программы избыточны. Я предполагаю использовать максимум 8, и то не знаю, зачем мне столько. Есть у кубовского HAL 4 значения.
Go to the top of the page
 
+Quote Post
Arlleex
сообщение Apr 24 2018, 06:36
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 07:01
Сообщение #6


Универсальный солдатик
******

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



Меня немного смущает, что имя тип возвращаемого кода выглядит "солиднее" имени самой функции.
fpgaConfigRetcode_t Fpga_config(void)

В HAL имеется следующее:
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 09:47
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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
}
Go to the top of the page
 
+Quote Post
haker_fox
сообщение Apr 24 2018, 10:03
Сообщение #8


Познающий...
******

Группа: Свой
Сообщений: 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-микросхемы*/
};

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


--------------------
Выбор.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 10:12
Сообщение #9


Универсальный солдатик
******

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



Цитата(haker_fox @ Apr 24 2018, 13:03) *
Всё зависит от вашей задачи, если вам хватает, то годится. Посмотрел свои настройки в текущем проекте, большая часть совпадает. Но вот для примера, что у меня

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

Спасибо, изучу. Идентифицировать буду сразу по возвращению из вызываемой функции, не дожидаясь завершения работы вызывающей функции.
Мне столько кодов не нужно. А если случится непредвиденная ошибка, можно выдать код из наиболее подходящих, или unspecified.
Go to the top of the page
 
+Quote Post
one_eight_seven
сообщение Apr 24 2018, 10:19
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664



Цитата
Ну, вот такой набор прикинул, скомпилировал из разных источников. Годится?

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

Сообщение отредактировал one_eight_seven - Apr 24 2018, 10:19
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 10:25
Сообщение #11


Универсальный солдатик
******

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



Цитата(one_eight_seven @ Apr 24 2018, 13:19) *
Если пишете для себя - делайте как угодно. Если есть хоть малейшая вероятность, что с вашим кодом будут работать другие люди, то лучше возьмите любой из стандартов, таким, какой он есть, полностью и без самодельных улучшений.

Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. biggrin.gif
Писал выше, мне много кодов не надо. Сначала хотел 4, потом 8, остановлюсь на 16. Полбайта займет, цэ гарно.
Go to the top of the page
 
+Quote Post
one_eight_seven
сообщение Apr 24 2018, 10:30
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 916
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664



Цитата
Я всегда делаю для себя. Но так, чтобы другим было не стыдно показать. biggrin.gif

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

Сообщение отредактировал one_eight_seven - Apr 24 2018, 10:32
Go to the top of the page
 
+Quote Post
ViKo
сообщение Apr 24 2018, 10:35
Сообщение #13


Универсальный солдатик
******

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



Э, если бы работа в группе заключалась в использовании только стандартных конструкций, сколько бы нервов было спасено. Но это - утопия, пмсм.
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Apr 24 2018, 10:54
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(haker_fox @ Apr 24 2018, 13:03) *
Кстати, у меня ещё вопрос: а как по возвращаемому значению идентифицировать функцию, где произошла ошибка? Так сказать "размотать стек"?

Возвращать PC/LR и по мап файлу смотреть что откуда?
Go to the top of the page
 
+Quote Post
HardEgor
сообщение Apr 24 2018, 11:27
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925



Цитата(ViKo @ Apr 24 2018, 12:26) *
Иногда приходится придумывать некие коды, информирующие о той или иной ошибке при выходе из функции. К EXIT_SUCCESS и EXIT_FAILURE добавляются дополнительные. Не задавались ли вы целью привести коды в систему, чтобы пользоваться во всех случаях? Если да, поделитесь, пожалуйста идеями.

Идея одна - у всех функций коды разные. Тем более функции живут на разных уровнях иерархии. Группировать смысла немного.
Поэтому есть 0 = SUCCESS, остальные коды пишутся и обзываются по порядку появления в функции.
Название формирую из уровня иерархии, например HAL_ плюс библиотека _UART и сокращенное название. Сокращенные названия можно брать из стандартных систем, типа Windows/UNIX
Go to the top of the page
 
+Quote Post

9 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 06:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016