Перейти к содержанию
    

Длина имени указателя IAR AVR

10 часов назад, IF_P сказал:

VladislavS предложил;

1. AT-команды хранить во флэш. Для некоторых команд это подойдёт, тут я согласен. А вот для AT+Cxxx (где х= 0 - 127) все равно придется использовать формирование строки в п/п.

Они у Вас и так хранятся во флешь (инициализаторы для preamb и для BAUD_HC_12):

char preamb[4] = "AT+";
  char *P_IN;
  char BAUD_HC_12[8][7] = {"1200", "2400", "4800", "9600", "19200", "38400",
                           "57600", "115200"};

только зачем-то Вы их на каждом входе в функцию копируете ещё и на стек. Зачем???

Нормально их следует объявлять так:

static char const preamb[] = "AT+";

static char const BAUD_HC_12[][7] = {"1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"};

Возможно для вашего компилятора нужно ещё добавить дополнительный квалификатор __flash (как написал VladislavS).

Цитата

2. Не вычислять длину строки буфера, а воспользоваться нуль-терминированием. Но в программе обработки прерываний UART мне нужно будет передавать не только строки, но и 16-ные данные из другого буфера. В таком случае проще иметь длину буфера данных. Это займет немного машинного времени, но упростится программа обработки прерываний.

Вопрос был: Зачем здесь

strcat (BUF_HC, preamb);

вычислять длину строки, если и так заранее известно, что она ==0? Достаточно сделать: 

memcpy(BUF_HC, preamb, sizeof(preamb) - 1);

И дальше в том же духе. Здесь:

strcat (BUF_HC, "B");
strcat (BUF_HC, BAUD_HC_12[baud_HC]);
count_buf_HC = strlen (BUF_HC);

Вы зачем-то 3-жды(!) вычисляете одну и ту же уже заранее известную длину. :shok:  Хотя это достаточно сделать всего 1 раз. Примерно так:

BUF_HC[sizeof(preamb) - 1] = 'B';
int i = strlen(BAUD_HC_12[baud_HC]);
memcpy(&BUF_HC[sizeof(preamb)], BAUD_HC_12[baud_HC], i);
count_buf_HC = sizeof(preamb) + i;

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

А если у Вас P_OUT_BUF_HC используется ещё где-то в ISR или другой задаче ОС, то также получите в полный рост проблемы с потоко-небезопасным использованием этой переменной. Работать с переменными используемыми разными задачами ОС, или фоновой задачей и ISR, нужно потоко-безопасно. Чего у Вас нет. А значит - получите плавающие ошибки, которые то будут проявляться, то нет.

Ну и наконец: Показателем стиля программирования, является придерживание неких соглашений об именовании переменных/констант/функций/... .

Например (как у меня): переменные обязательно начинаются с маленькой буквы, и содержат в основном маленькие буквы, используя "верблюжий стиль" для выделения слов, например: pOutBufHc либо стиль: p_out_buf_hc;

Константы - большими буквами: P_OUT_BUF_HC;

Функции: аналогично переменным, но первая буква - большая.

У Вас же - разнобой, кто в лес кто по дрова. Это мелочь пока программы маленькие. Но когда попробуете прочитать большой и сложный код, написанный в едином стиле, и без стиля (как у Вас), то поймёте разницу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ответ на вопрос в названии темы:

Цитата

— 63 significant initial characters in an internal identifier or a macro name (each
universal character name or extended source character is considered a single
character)
— 31 significant initial characters in an external identifier (each universal character name
specifying a short identifier of 0000FFFF or less is considered 6 characters, each
universal character name specifying a short identifier of 00010000 or more is
considered 10 characters, and each extended source character is considered the same
number of characters as the corresponding universal character name, if any)

Это из стандарта 99 года.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

to jcxz

Спасибо за Ваш подробный комментарий. Хочу тоже кое-что объяснить.

Quote

Нормально их следует объявлять так:

static char const preamb[] = "AT+";

Я именно так и поступаю. Я выношу описание всех констант флеша в отдельный файл. Здесь же рабочий вариант программы. Я их определил локально, что б можно было оперативно вносить изменения. Потом я перенесу их во флеш __flash char (без static).

Quote

Вы зачем-то 3-жды(!) вычисляете одну и ту же уже заранее известную длину. 

Это я заметил еще вчера и написал в 12 посте. Снова повторюся - программа еще "сырая" и в процессе написания.

Quote

использования локальных переменных вместо глобальных, там где не нужна глобальность

Я тоже стараюсь так делать. Когда-то читал статью о фирме TOYOTA и к чему там привело использование глобальных переменных. Но как в моём случае передать ISR информацию о том, что обрабатывать. Я передаю первый байт в п/п, а остальные уже в ISR.

Quote

придерживание неких соглашений об именовании переменных/констант/функций/

Тут я полностью согласен и стараюсь тоже придерживаться определенных правил:

переменные - все маленькие буквы

функции - первая буква каждого слова прописная

константы, указатели, массивы - все буквы прописные

Также стараюсь придерживаться определенных правил в оформлении кода и комментариев.

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

Изменено пользователем IF_P

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, IF_P said:

Потом я перенесу их во флеш __flash char (без static).

У вас уже не один раз повторяется потом.

Почему потом, а не сразу ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 часов назад, IF_P сказал:

Но как в моём случае передать ISR информацию о том, что обрабатывать.

Стандартный способ взаимодействия фоновой задачи и ISR UART - кольцевой буфер с двумя указателями: один - запись, другой - чтение. Фоновая задача пишет в кольцевой буфер используя указатель записи; ISR - читает из него, используя указатель чтения (это для передачи в UART, если нужен ещё приём - добавляем ещё один такой-же к.буфер). Никто из участников чужой указатель не модифицирует, только читает, модифицирует только свой указатель.

Это стандартный, потоко-безопасный способ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, jcxz said:

Стандартный способ взаимодействия фоновой задачи и ISR UART - кольцевой буфер с двумя указателями: один - запись, другой - чтение.

Соответственно, буфер и указатели глобальные с квалификатором volatile -?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, IF_P сказал:

Соответственно, буфер и указатели глобальные с квалификатором volatile -?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 26.01.2020 в 01:10, IF_P сказал:

все нормально работает, если имя указателя P_OUT_BUF.

Если меняю имя указателя на P_OUT_BUF_HC, то в цикле for ничего не происходит (не записывает в буфер и длина остается = 4) . В чем может быть причина?

При смене имени переменной Вам приходится много комментировать.

Оформите замену имени в одном месте, в коде например _P_OUT_BUF, а в неадере комментируете ненужный вариант.

#define _P_OUT_BUF  P_OUT_BUF 

#define _P_OUT_BUF  P_OUT_BUF_HC.

И попробуйте снова. Если будут различия, выложите пожайлуста asm-ы обоих вариантов.

И версию IAR-а.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 часов назад, jcxz сказал:

 Никто из участников чужой указатель не модифицирует, только читает, модифицирует только свой указатель.

Это стандартный, потоко-безопасный способ.

дык при чтении нужно еще обеспечить атомарность на AVRках, так как платформа 8-битная а указатели 16/32-битные

Не ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, megajohn сказал:

дык при чтении нужно еще обеспечить атомарность на AVRках, так как платформа 8-битная а указатели 16/32-битные

Указатель не обязательно делать адресом в памяти, его можно сделать индексом. 8-битным. Если хватит такого размера буфера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, aiwa said:

При смене имени переменной Вам приходится много комментировать.

Оформите замену имени в одном месте, в коде например _P_OUT_BUF, а в неадере комментируете ненужный вариант.

#define _P_OUT_BUF  P_OUT_BUF 

#define _P_OUT_BUF  P_OUT_BUF_HC.

И попробуйте снова. Если будут различия, выложите пожайлуста asm-ы обоих вариантов.

И версию IAR-а.

Я не сохранил версии программы с ошибкой, а сейчас все работает нормально. Причину установить не удалось. Я несколько раз менял и перекомпилировал. Один раз даже увидел, что оператор for "развернулся" в одну ассемблерную команду??? Возможно, что-то с компилятором. Были случаи неработоспособного кода после очередной компиляции. При рассмотрении листинга увидел, что часть кода не скомпилировалась (как бы закомментирована). При повторной компиляции все уже было нормально.

 

Версия IAR AVR 6.80.5

Изменено пользователем IF_P

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, IF_P сказал:

Были случаи неработоспособного кода после очередной компиляции. При рассмотрении листинга увидел, что часть кода не скомпилировалась (как бы закомментирована). При повторной компиляции все ужк было нормально.

Так обычно бывает если результат работы кода не используется. Нормальное поведение компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 minutes ago, jcxz said:

Так обычно бывает если результат работы кода не используется. Нормальное поведение компилятора.

Тогда как понять, что не меняя ничего в программе, просто еще раз запустив компиляцию, получаю работоспособный код?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 минут назад, IF_P сказал:

Тогда как понять, что не меняя ничего в программе, просто еще раз запустив компиляцию, получаю работоспособный код?

Гадать на кофейной гуще можно сколько угодно. Приведите конкретный пример кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, jcxz said:

Гадать на кофейной гуще можно сколько угодно. Приведите конкретный пример кода.

Если будет такая ситуация, то выложу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...