Salamander 2 6 апреля, 2021 Опубликовано 6 апреля, 2021 (изменено) · Жалоба Господа, ситуация такая. Есть массив из 100 строк char* strings_buffer[10]={"1","2","3","4","5","6","7","8","9","10"}; Есть массив из обычных байт, в который принимаются данные по UART uint8_t rx_buffer[RX_BUFFER_SIZE] = {0,}; Когда ловится символ конца строки, то все содержимое rx_buffer с нулевого символа до того, где был пойман конец строки, должно копироваться в массив строк, точнее в один из его элементов под номером str_buffer_write_position. Я не стал заморачиваться с классическим кольцевым буфером, так как длина принимаемых строк гарантированно не превышает RX_BUFFER_SIZE, после захвата последовательности r\n индекс записи просто переносится на нулевой элемент rx_buffer for (uint8_t i=0;i<rx_write_buffer_position;i++) *strings_buffer[str_buffer_write_position]++=rx_buffer[i]; не работает, вылетает в хард (контроллер STM32) Что я делаю не так? Изменено 6 апреля, 2021 пользователем Salamander Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 60 6 апреля, 2021 Опубликовано 6 апреля, 2021 · Жалоба char* strings_buffer[10]={"1","2","3","4","5","6","7","8","9","10"}; Это массив указателей на строки во флэш или озу ? *strings_buffer[str_buffer_write_position]++ = rx_buffer[i]; Что тут хотели сделать ? Каша какая то. 22 minutes ago, Salamander said: Что я делаю не так? Не читаете книг. Не пользуетесь отладчиком. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 6 апреля, 2021 Опубликовано 6 апреля, 2021 · Жалоба 2 часа назад, Salamander сказал: Когда ловится символ конца строки, то все содержимое rx_buffer с нулевого символа до того, где был пойман конец строки, должно копироваться в массив строк, точнее в один из его элементов под номером str_buffer_write_position. Массив байт копируете в массив строк??? Советую почитать учебник по си по теме "стандартные типы данных". 2 часа назад, Salamander сказал: for (uint8_t i=0;i<rx_write_buffer_position;i++) *strings_buffer[str_buffer_write_position]++=rx_buffer[i]; не работает, вылетает в хард (контроллер STM32) И правильно делает, потому что код выше пытается делать запись в одну из строк "1","2","3","4","5","6","7","8","9","10", которые слишком короткие для этого. А возможно что ещё и находятся во флешь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrBearManul 0 7 апреля, 2021 Опубликовано 7 апреля, 2021 · Жалоба 9 часов назад, Salamander сказал: Есть массив из 100 строк А у вас код из 10. И это не массив строк. Это массив указателей. 9 часов назад, Salamander сказал: Что я делаю не так? Вы делаете не так то, что объявляете массив указателей, а не строк. Соответственно, каждый элемент такого массива - 4 байта на архитектуре Cortex-Mx. И хранит такой элемент не строку (N байт), а всего лишь адрес из четырёх байт. При этом данные, на которыу указывает адрес могут быть вообще в разных участках разной памяти (NOR, FLASH, SRAM, SDRAM и т.п.). Скомпилируйте свой проект без оптимизации, запустите отладчик и поглядите что у вас за типы данных. Вам станет всё понятнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 8 апреля, 2021 Опубликовано 8 апреля, 2021 (изменено) · Жалоба 07.04.2021 в 08:09, MrBearManul сказал: И это не массив строк. Это массив указателей. Это массив из десяти строк. const char *str[] = {"message 1", "message 2", "message 3"}; - это массив сообщений... или массив строк. Понятно, что char *str[] - это массив указателей, Hо на практике такой массив называют "массив строк" и это подразумевает, что каждый эл-нт массива есть указатель на char и в 32-х битной архит-ре каждый эл-нт занимает 4 байта и каждый элемент указывает на строку. Двумя словами - массив строк. 06.04.2021 в 22:21, Salamander сказал: for (uint8_t i=0;i<rx_write_buffer_position;i++) *strings_buffer[str_buffer_write_position]++=rx_buffer[i]; не работает, вылетает в хард (контроллер STM32) Что я делаю не так? 1) "5" - строковая константа константная строка. Никогда не пишите код char *str = "5"; По мойму, на это компилятор должен выдать ворнинг. Если инициализируете строкой указатель, то всегда пишите const char *str = "5"; Избежите много ошибок на этапе компиляции. 2) Даже, если массив строк в озу, то у вас длинна каждой строки в в массиве строк strings_buffer два байта. 4-ая строка состоит из символа '5' и символа '\0'. Если индекс массива равен 4, т0 вы копируете 4 байта (судя по коду). Вы первый раз в цикле for записали в *strings_buffer[4] = rx_buffer[0]. Хорошо. Перетерли символ '5'. *strings_buffer[4]++ - теперь этот указатель указывает на следующий символ, на символ '\0'. Второй раз *strings_buffer[4] = rx_buffer[1]. Перетёрли символ '\0'. Строка "5" кончилась. Больше выделенной памяти для строки strings_buffer[4] нет. Ещё инкримент *strings_buffer[4]++ - теперь этот указатель указывает за пределы строки "5". Далее, при попытки записать в *strings_buffer[4] = rx_buffer[j] будет неопределённое поведение. HF - получите и распишитесь. 3)Где, после копирования, сброс указателя strings_buffer[4] на начало строки "5"? 4)Как вы скопируете массив байт в строку strings_buffer[0] таким кодом? Ведь для этого str_buffer_write_position должен быть равен 0, но тогда вы не разу не зайдете в тело for. 5)for (uint8_t i=0;i<rx_write_buffer_position;i++) *strings_buffer[str_buffer_write_position]++=rx_buffer; Это что за дичь? Что такое str_buffer_write_position? Может вам всетаки нужен не массив строк, а строка (или массив символов)? char strings_buffer[10]={'1','2','3','4','5','6','7','8','9','0'};//строка "1234567890" в ОЗУ, размером в 10 байт/символов, без символа "конец строки" ('\0') for (uint8_t i=0;i<rx_write_buffer_position;i++) if(i < 10) //защита от выхода за границы строки strings_buffer strings_buffer[i]=rx_buffer[i]; ps не путайте одинарные кавычки и двойные. pps К моератору..... что сделали с редактором? Раньше, выделил текст, нажал "I" - в начале и в конче текста в окне редактора появились символы [_i_] [\_i_] - текст в окне редатора не наклонный, видны таги. После публикации таги не видны, текст наклонный. Сейчас в редакторе таги не видны, сразу наклон. По мне, так менее удобно, раньше было лучше. Но да бохсним... Это ИМХО ни кого не интересуещее.... но сейчас выделил несколько слов в середине текста, нажал I, - в окне редактора наклонились нужные слова. Опубликовал - наклонился ВЕСЬ текст после этого слова. Раз 5 уже переправлял сообщение из-за этого глюка. ppps я понял в чем глюк. я хочу написать текст rx_buffer[тут "и" с точкой]. Т.е. если написать "эр Икс буффер итое, то индекс массива редактор воспринимает как открывающий таг наклонного текста. Мне кажется это косяк редактора, Как набрать текст "rx_buffer[j]", только вместо 'j' должна быть 'i'? Изменено 8 апреля, 2021 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 8 апреля, 2021 Опубликовано 8 апреля, 2021 · Жалоба 2 часа назад, razrab83 сказал: ppps я понял в чем глюк. я хочу написать текст rx_buffer[тут "и" с точкой]. Т.е. если написать "эр Икс буффер итое, то индекс массива редактор воспринимает как открывающий таг наклонного текста. Мне кажется это косяк редактора, Как набрать текст "rx_buffer[j]", только вместо 'j' должна быть 'i'? Просто оформляйте такое как блок кода. В нём тэги не обрабатываются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 8 апреля, 2021 Опубликовано 8 апреля, 2021 · Жалоба char strings_buffer[10][RX_BUFFER_SIZE]={"asd","qwe","zxc"}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 8 апреля, 2021 Опубликовано 8 апреля, 2021 (изменено) · Жалоба 4 часа назад, jcxz сказал: Просто оформляйте такое как блок кода. В нём тэги не обрабатываются. что значит "блок кода"? Это то что раньше было обрамлено в [с0de] [\c0de]? Так такой блок кода будет в рамке, с подсветкой, с подсветкой индекса. У меня это не код с/с++, у меня это текст.... поспрашивал веберов - те накидали подобных костылей. Например, в си/с++, строка пишется в обрамлении кавычек "это строка 123", но если текст строки должен включать кавычку, есть управляющие символы "это строка \"123\"", где '\' - это управляющий символ. В этом редакторе WysiBB (или другое, поправте), [и] - это управляющи таг. Но должны же быть какие-то способы, чтобы редактору сказать - "этот текст не воспринимай как таг, а просто как текст". Веберы такого не знают. Кто знает как редактору сказать что "[и]" - это текст? Изменено 8 апреля, 2021 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 8 апреля, 2021 Опубликовано 8 апреля, 2021 · Жалоба 2 ТС: язык С не занимается самостоятельным управлением динамической памятью. Строки (за исключением констант в программе) по своей природе сущности динамические, т.к. могут менять свой размер. Так что у вас 3 выхода: Управлять памятью самому (malloc/free) Выделить сразу массивы достаточного размера, и смериться с потерями памяти, если строки будут короче, и с ограничением на макимальную длинну строк Сменить язык (например на С++ и std::string) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 8 апреля, 2021 Опубликовано 8 апреля, 2021 · Жалоба 1 час назад, razrab83 сказал: что значит "блок кода"? Это то что раньше было обрамлено в [с0de] [\c0de]? да. Цитата Так такой блок кода будет в рамке, с подсветкой, с подсветкой индекса. У меня это не код с/с++, у меня это текст.... Подсветку синтаксиса можно выключить - там есть соответствующий combobox: "это строка \"123\"" "[и]" - это текст? ку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 8 апреля, 2021 Опубликовано 8 апреля, 2021 (изменено) · Жалоба 42 минуты назад, jcxz сказал: да. Подсветку синтаксиса можно выключить - там есть соответствующий combobox: "это строка \"123\"" "[и]" - это текст? ку? да так-то ку. можно сделать так "array[ i]" - тоже ку. Это всё костыли. Можно текст в ворде написать, вырезать ножницами скрин и сюда вставить картинку. Но интересно не как на этом форуме показать "[ i]", а как сказать вьюверу/редактору, что ЭТО НЕ УПРАВЛЯЮЩИЙ ТАГ наклонного текста? Как это делается правильно? Как, авторы этой разметки предусмотрели вывод текста "[ i]"? Через подобные костыли? 2 часа назад, xvr сказал: язык С не занимается самостоятельным управлением динамической памятью .... Сменить язык (например на С++ и std::string) Язык с++ тоже самостоятельно не занимается управлением динамической памятью. Этим занимаются всякие аля-контейнеры, например std::string/vector/.... Но контейнеры можно и на СИ организовать. Изменено 8 апреля, 2021 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 8 апреля, 2021 Опубликовано 8 апреля, 2021 · Жалоба 3 hours ago, razrab83 said: Язык с++ тоже самостоятельно не занимается управлением динамической памятью. Этим занимаются всякие аля-контейнеры, например std::string/vector/.... Но контейнеры можно и на СИ организовать. В языке С++ эти контейнеры входят в стандартную библиотеку. Причем настолько входят, что под неё были сделаны расширения в синтаксисе языка. В С придётся писать самому, или брать какие то готовые со стороны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 9 апреля, 2021 Опубликовано 9 апреля, 2021 · Жалоба В общем я сделал вот так: #define RX_BUFFER_SIZE 256 uint8_t rx_buffer[RX_BUFFER_SIZE]; char TERMINAL_TEXT[100][256]; for(uint8_t i=0;i<255;i++) TERMINAL_TEXT[str_buffer_write_position][i]=rx_buffer[i]; Работает. Дальше мне понадобился скроллинг. То есть, есть 100 строк, появляется 101-я, я в цикле переписываю содержимое строки n+1 в строку n, и лишь потом пишу 101ю строку в ячейку №100. Сделал переписывание грубо, топорно, чтобы хотя бы посмотреть на текст на экране for(uint8_t i=0;i<100;i++) { for(uint8_t j=0;j<256;j++) TERMINAL_TEXT[i][j]=TERMINAL_TEXT[i+1][j] } Вопрос такой - сопряжен ли такой способ копирования с существенным замедлением быстродействия? Есть более быстрые способы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 9 апреля, 2021 Опубликовано 9 апреля, 2021 · Жалоба 3 hours ago, Salamander said: Вопрос такой - сопряжен ли такой способ копирования с существенным замедлением быстродействия? Да. но насколько существенным зависит от процессора Quote Есть более быстрые способы? Да. как минимум используйте функцию memmove - она оптимизирована для копирования массивов памяти. Если надо ещё быстрее - делайте промежуточный массив указателей на строки - char TERMINAL_TEXT_BUF[256][100]; char* TERMINAL_TEXT[256]; for(i=0;i<256;++i) TERMINAL_TEXT[i] = TERMINAL_TEXT_BUF[i]; Потом копируете указатели в TERMINAL_TEXT (не забудьте их зациклить по исходному массиву - иначе затрёте память) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salamander 2 9 апреля, 2021 Опубликовано 9 апреля, 2021 · Жалоба 26 minutes ago, xvr said: Потом копируете указатели в TERMINAL_TEXT (не Идея не совсем понятна. Точнее понятна задцэумка - делать скроллинг не строк по 256 байт, а только указателей на них. Но дальше что? Сам исходный буфер тоже надо обновлять... А.. Погодите, кажется понял. Исходгэный буфер сделать кольцевым, а массивом указателей по нему как бы скользить. Чтобы последний элемент массива указателей всегда указывал на только что обновлённый элемент исходного буфера? Ещё есть сопутствующие вопрос. Скажите а что происходит, если при возникновении прерывания по приёму UART, оно успевает обработаться аппаратно, но не успевает программно? У меня пока что код скроллинг а находится в обработчике прерывания. Знаю, это не рационально, но скорость позволяла, между входящими посылка и времени достаточно. Но иногда бывает, что приходит две посылки подряд. Чтение из регистров UART я успеваю сделать, строку тоже успеваю, а вот когда идёт скроллинг - приходит следующая посылка. Выносить скроллинг за пределы обработчик прерывания? Хм... В принципе, с описанным вами вариантом кольцевого буфера это несложно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться