Jump to content

    

Длина имени указателя 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;

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

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

Share this post


Link to post
Share on other sites

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

Цитата

— 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 года.

Share this post


Link to post
Share on other sites

to jcxz

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

Quote

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

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

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

Quote

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

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

Quote

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

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

Quote

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

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

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

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

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

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

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

Edited by IF_P

Share this post


Link to post
Share on other sites
1 hour ago, IF_P said:

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

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

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

Share this post


Link to post
Share on other sites
5 часов назад, IF_P сказал:

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

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

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

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

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

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

Share this post


Link to post
Share on other sites
3 минуты назад, IF_P сказал:

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

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

Share this post


Link to post
Share on other sites
В 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-а.

Share this post


Link to post
Share on other sites
10 часов назад, jcxz сказал:

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

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

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

Не ?

Share this post


Link to post
Share on other sites
1 минуту назад, megajohn сказал:

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

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

Share this post


Link to post
Share on other sites
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

Edited by IF_P

Share this post


Link to post
Share on other sites
7 минут назад, IF_P сказал:

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

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

Share this post


Link to post
Share on other sites
31 minutes ago, jcxz said:

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

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

Share this post


Link to post
Share on other sites
17 минут назад, IF_P сказал:

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

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

Share this post


Link to post
Share on other sites
2 minutes ago, jcxz said:

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

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now