jcxz 241 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 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-жды(!) вычисляете одну и ту же уже заранее известную длину. Хотя это достаточно сделать всего 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; Функции: аналогично переменным, но первая буква - большая. У Вас же - разнобой, кто в лес кто по дрова. Это мелочь пока программы маленькие. Но когда попробуете прочитать большой и сложный код, написанный в едином стиле, и без стиля (как у Вас), то поймёте разницу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба Ответ на вопрос в названии темы: Цитата — 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 года. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 27 января, 2020 Опубликовано 27 января, 2020 (изменено) · Жалоба to jcxz Спасибо за Ваш подробный комментарий. Хочу тоже кое-что объяснить. Quote Нормально их следует объявлять так: static char const preamb[] = "AT+"; Я именно так и поступаю. Я выношу описание всех констант флеша в отдельный файл. Здесь же рабочий вариант программы. Я их определил локально, что б можно было оперативно вносить изменения. Потом я перенесу их во флеш __flash char (без static). Quote Вы зачем-то 3-жды(!) вычисляете одну и ту же уже заранее известную длину. Это я заметил еще вчера и написал в 12 посте. Снова повторюся - программа еще "сырая" и в процессе написания. Quote использования локальных переменных вместо глобальных, там где не нужна глобальность Я тоже стараюсь так делать. Когда-то читал статью о фирме TOYOTA и к чему там привело использование глобальных переменных. Но как в моём случае передать ISR информацию о том, что обрабатывать. Я передаю первый байт в п/п, а остальные уже в ISR. Quote придерживание неких соглашений об именовании переменных/констант/функций/ Тут я полностью согласен и стараюсь тоже придерживаться определенных правил: переменные - все маленькие буквы функции - первая буква каждого слова прописная константы, указатели, массивы - все буквы прописные Также стараюсь придерживаться определенных правил в оформлении кода и комментариев. Может где-то и ошибся, но по ходу отладки программы я это исправляю. Изменено 27 января, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 63 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 1 hour ago, IF_P said: Потом я перенесу их во флеш __flash char (без static). У вас уже не один раз повторяется потом. Почему потом, а не сразу ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 5 часов назад, IF_P сказал: Но как в моём случае передать ISR информацию о том, что обрабатывать. Стандартный способ взаимодействия фоновой задачи и ISR UART - кольцевой буфер с двумя указателями: один - запись, другой - чтение. Фоновая задача пишет в кольцевой буфер используя указатель записи; ISR - читает из него, используя указатель чтения (это для передачи в UART, если нужен ещё приём - добавляем ещё один такой-же к.буфер). Никто из участников чужой указатель не модифицирует, только читает, модифицирует только свой указатель. Это стандартный, потоко-безопасный способ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 1 hour ago, jcxz said: Стандартный способ взаимодействия фоновой задачи и ISR UART - кольцевой буфер с двумя указателями: один - запись, другой - чтение. Соответственно, буфер и указатели глобальные с квалификатором volatile -? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 3 минуты назад, IF_P сказал: Соответственно, буфер и указатели глобальные с квалификатором volatile -? volatile - да, глобальные - не обязательно. Если весь код использующий к.буфера находится в одном файле - их лучше объявить с квалификатором static. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба В 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-а. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 8 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 10 часов назад, jcxz сказал: Никто из участников чужой указатель не модифицирует, только читает, модифицирует только свой указатель. Это стандартный, потоко-безопасный способ. дык при чтении нужно еще обеспечить атомарность на AVRках, так как платформа 8-битная а указатели 16/32-битные Не ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 1 минуту назад, megajohn сказал: дык при чтении нужно еще обеспечить атомарность на AVRках, так как платформа 8-битная а указатели 16/32-битные Указатель не обязательно делать адресом в памяти, его можно сделать индексом. 8-битным. Если хватит такого размера буфера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 28 января, 2020 Опубликовано 28 января, 2020 (изменено) · Жалоба 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 Изменено 28 января, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 7 минут назад, IF_P сказал: Были случаи неработоспособного кода после очередной компиляции. При рассмотрении листинга увидел, что часть кода не скомпилировалась (как бы закомментирована). При повторной компиляции все ужк было нормально. Так обычно бывает если результат работы кода не используется. Нормальное поведение компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 31 minutes ago, jcxz said: Так обычно бывает если результат работы кода не используется. Нормальное поведение компилятора. Тогда как понять, что не меняя ничего в программе, просто еще раз запустив компиляцию, получаю работоспособный код? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 17 минут назад, IF_P сказал: Тогда как понять, что не меняя ничего в программе, просто еще раз запустив компиляцию, получаю работоспособный код? Гадать на кофейной гуще можно сколько угодно. Приведите конкретный пример кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 28 января, 2020 Опубликовано 28 января, 2020 · Жалоба 2 minutes ago, jcxz said: Гадать на кофейной гуще можно сколько угодно. Приведите конкретный пример кода. Если будет такая ситуация, то выложу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться