IF_P 1 25 января, 2020 Опубликовано 25 января, 2020 · Жалоба Вот подпрограмма, которая формирует AT-команду. void Form_AT (void) { uchar i; char preamb[4] = "AT+"; char *P_IN; char BAUD_HC_12[8][7] = {"1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"}; // P_OUT_BUF = BUF_HC; P_OUT_BUF_HC = BUF_HC; for(i = 0; i < 15; i++) BUF_HC[i] = 0x00; strcat (BUF_HC, preamb); switch (command) { case 3: strcat (BUF_HC, "B"); strcat (BUF_HC, BAUD_HC_12[baud_HC]); count_buf_HC = strlen (BUF_HC); break; case 4: strcat (BUF_HC, "C"); Bin_To_ASCII(channel_HC); P_IN = Rab.symv6.symv3; // P_OUT_BUF += 4; P_OUT_BUF_HC += 4; // for(i = 0; i < 3; i++) *P_OUT_BUF++ = *P_IN++; for(i = 0; i < 3; i++) *P_OUT_BUF_HC++ = *P_IN++; count_buf_HC = strlen (BUF_HC); break; } } В хидерном файле есть описание указателя char BUF_HC[15]; //char *P_OUT_BUF; char *P_OUT_BUF_HC; все нормально работает, если имя указателя P_OUT_BUF. Если меняю имя указателя на P_OUT_BUF_HC, то в цикле for ничего не происходит (не записывает в буфер и длина остается = 4) . В чем может быть причина? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 6 часов назад, IF_P сказал: В чем может быть причина? В стиле программирования. Ты по что так AVR-ку мучаешь? Для поиска проблемы попроси компилятор сделать ассемблерный листинг и смотри что там происходит. Насчёт "мучать AVR-ку". Сравни использование RAM (особенно стека) в твоём и в этом коде. Да и FLASH в итоге меньше потребуется, так как не нужен код для формирования строк и "гоняния" их по RAM. #include <stdint.h> #include "pgmspace.h" __flash const char at_br[8][11] = {"AT+B1200", "AT+B2400", "AT+B4800", "AT+B9600", "AT+B19200", "AT+B38400", "AT+B57600", "AT+B115200"}; char buf_hc[15]; void AT_BR(char *dst, uint8_t br) { strcpy_P(dst,at_br[br]); } int main() { uint8_t command = 3; uint8_t br = 4; switch(command) { case 3: AT_BR(buf_hc,br); break; case 4: // .... break; } for(;;); } И длину строки не надо по сто раз считать и хранить. Зачем тратить на это время и место? Она же нультерминированная, там где её выводишь пользуйся этим. И зачем PU_OUT_BUF глобальная? Как можно локальней надо делать переменные. Так и ошибок меньше будет, и компилятору проще оптимизировать. Сделай ты её локальной, она просто в регистрах прокрутится и умрёт там же не заняв SRAM вообще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 10 hours ago, VladislavS said: Ты по что так AVR-ку мучаешь? А что б не расслаблялась. Пусть свои деньги отрабатывает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 (изменено) · Жалоба 11 hours ago, VladislavS said: В стиле программирования. И зачем PU_OUT_BUF глобальная? Как можно локальней надо делать переменные. Так и ошибок меньше будет, и компилятору проще оптимизировать. Сделай ты её локальной, она просто в регистрах прокрутится и умрёт там же не заняв SRAM вообще. Ну во-первых, у каждого свой стиль программирования. Во-вторых , тут только часть кода. Поэтому вам не видно весь алгоритм. Скорости тут описаны как локальные для отладки. Но в будущем я их перенесу во флэш, т.к. они буду использоваться еще в другом месте. А там мне "AT+" ни к чему. В-третьих, для этой команды можна так использовать флэш. А как быть с командой "AT+Cxxx", где ххх вводится с пульта от 0 до 127. Не буду же я прописывать все варианты во флэш. Вот поэтому и остановился на таком варианте. Ну и наконец, указатель PU_OUT_BUF нужен именно глобальный, т.к. массив BUF_HC в этой п/п будет выдаваться в UART: UCSRB &=~ ( 1 << RXCIE ); UCSRB |= ( 1 << TXCIE ); P_OUT_BUF_HC = BUF_HC; UDR = *P_OUT_BUF_HC; P_OUT_BUF_HC++; А далее по прерыванию с использованием данного указателя. А что касается первого поста, то сейчас все работает. По шагам все менял и заработало. Причину пока не установил. Изменено 26 января, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 1 час назад, IF_P сказал: А далее по прерыванию с использованием данного указателя. Используется в прерывании, а volatile не наблюдается. Впрочем, мне всё равно - отрабатывайте свои деньги :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 2 hours ago, VladislavS said: Используется в прерывании, а volatile не наблюдается. А зачем volatile? Я не использую здесь оптимизацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 26 минут назад, IF_P сказал: Я не использую здесь оптимизацию. Этому есть хоть какое-то разумное объяснение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 15 minutes ago, VladislavS said: Этому есть хоть какое-то разумное объяснение? Программа простая и не ограничивает меня ни по коду, ни по времени исполнения. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 23 минуты назад, IF_P сказал: Программа простая и не ограничивает меня ни по коду, ни по времени исполнения Браво. Это пять. Продолжайте сами создавать себе трудности и героически их преодолевать. На ум приходит переписка о варке яиц в микроволновке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 20 minutes ago, Сергей Борщ said: Браво. Это пять. Продолжайте сами создавать себе трудности и героически их преодолевать. На ум приходит переписка пользователя и производителя микроволновок о варке яиц. Может я чего-то не понимаю. Чем я создаю себе трудности? Зачем везде сунуть оптимизацию? Объясните, пожалуйста, зачем в моём случае нужна оптимизация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 26 января, 2020 Опубликовано 26 января, 2020 · Жалоба 1 час назад, IF_P сказал: Программа простая и не ограничивает меня ни по коду, ни по времени исполнения. Отсутствие volatile тоже никак не ограничивает компилятор в расстановке команд. И может оказаться, что такая расстановка будет давать совсем не тот результат, какой вы ожидали. PS: Вам дают советы, Вы - спорите с ними. Совершенно не понимая и не пытаясь понять смысла советов. Зачем тогда задавали вопрос? По стилю (а скорее - его отсутствию) я согласен с VladislavS. 27 минут назад, IF_P сказал: Объясните, пожалуйста, зачем в моём случае нужна оптимизация. Оптимизация всегда полезна. Вне зависимости от простоты программы. Она позволяет выявить многие скрытые ошибки. Если у вас без оптимизации работает, а с ней - нет, значит - код кривой и надо искать баги. 5 часов назад, IF_P сказал: По шагам все менял и заработало. Причину пока не установил. Это не "заработало", это - "перестало проявляться". А завтра, послезавтра или позже - опять начнёт проявляться. Вы просто замели проблему под ковёр. Когда на неё в следующий раз наступите, вонять будет уже гораздо сильнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IF_P 1 26 января, 2020 Опубликовано 26 января, 2020 (изменено) · Жалоба 1 hour ago, jcxz said: Отсутствие volatile тоже никак не ограничивает компилятор в расстановке команд. И может оказаться, что такая расстановка будет давать совсем не тот результат, какой вы ожидали. PS: Вам дают советы, Вы - спорите с ними. Совершенно не понимая и не пытаясь понять смысла советов. Зачем тогда задавали вопрос? По стилю (а скорее - его отсутствию) я согласен с VladislavS. Я как раз пытаюсь понять. Что касается volatile, я спорить не буду, возможно Вы правы. А вот по стилю хотел бы кое-что уточнить. VladislavS предложил; 1. AT-команды хранить во флэш. Для некоторых команд это подойдёт, тут я согласен. А вот для AT+Cxxx (где х= 0 - 127) все равно придется использовать формирование строки в п/п. 2. Не вычислять длину строки буфера, а воспользоваться нуль-терминированием. Но в программе обработки прерываний UART мне нужно будет передавать не только строки, но и 16-ные данные из другого буфера. В таком случае проще иметь длину буфера данных. Это займет немного машинного времени, но упростится программа обработки прерываний. Возможно, я в чем-то ошибаюсь. Буду рад выслушать Ваш комментарий. P.S. Вот только что посмотрел, что длину строки можно вычислять один раз перед выдачей в UART. Изменено 26 января, 2020 пользователем IF_P Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 6 hours ago, IF_P said: А зачем volatile? Я не использую здесь оптимизацию. Правильно. Вместо вас, её использует компилятор. Настоятельно присоединяюсь к советам выше, и рекомендую вам прочитать, что такое volatile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба 12 часов назад, IF_P сказал: т.к. они буду использоваться еще в другом месте. А там мне "AT+" ни к чему Адрес строки без "AT+B" будет at_br[br]+4 . Это не потребует ни одного дополнительного байта кода, так как для доступа к такой подстроке будет просто использоваться другая константа начального адреса. // С AT+B LDI R30, LOW(at_br) LDI R31, HIGH(at_br) // Без AT+B LDI R30, LOW((at_br + 4)) LDI R31, HIGH((at_br + 4)) Дарю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 27 января, 2020 Опубликовано 27 января, 2020 · Жалоба А вообще, мой посыл по стилю был в том, что переменные надо как можно локальней делать. Та же глобальная P_OUT_BUF зачем используется в функции там где можно было обойтись локальной переменной? Да ещё потом оказывается, что она в каком-то прерывании используется. Ужас! Вот смотри, в С++17 даже ввели вот такую возможность if(int i=0; x<y) { ... } else { ... } И это сделано отнюдь не для того чтобы экономить строки в коде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться