Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Подскажите как правильно передать строку в функцию?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
mempfis_
Добрый день.
Сижу ламаю голову вот над каким вопросом - есть самописная функция putstring(unsigned char __flash *pData) которая по указателю считывает строку и передаёт её по уарту в терминал.

Если объявить строку и передать указатель на неё в функцию то всё работает правильно:
Код
__flash unsigned char txt[] = "Start Programm\r\n";
putstring(txt)


Хочу сделать запись проще - при использовании функции сразу писать в ней строку:
Код
putstring("Start Programm\r\n")


Компилятор выдаёт ошибку
Код
Error[Pe167]: argument of type "char const *" is incompatible with parameter of type "unsigned char __flash *"


Привожу к типу unsigned char __flash * в надежде что компилятор поймёт что строку надо разместить во флеш а в функцию передать указатель:
Код
putstring( (unsigned char __flash *) "Start Programm\r\n")


Никакой ругани нет но и не работает совсем.
Прогнал в симуляторе - выяснил что во втором случае передаётся неверный указатель на строку и соответственно читается всякая белеберда из памяти программ.

Собственно вопрос как можно сделать чтобы второй вариант записи работал?
Для наглядности программы хочется чтобы строки писались в самой функции.
Andron_
сдается мне, линковщику нужно указать, чтобы он размещал строки во флэш памяти...
Палыч
Вы бы транслятор указали что ли... ИАР? Дело, имхо, в галке "Place string literals and constants in initialized RAM"
mempfis_
Цитата(Палыч @ Sep 9 2009, 18:21) *
Вы бы транслятор указали что ли... ИАР? Дело, имхо, в галке "Place string literals and constants in initialized RAM"


Компилятор IAR AVR 5.20.

Убираю галочку - появляется ошибка:
Код
Error[e16]: Segment NEAR_C (size: 0x8a5 align: 0) is too long for segment definition. At least 0x8a5 more bytes needed. The problem occurred while processing the segment  
placement command "-Z(DATA)NEAR_C=_..X_EXT_ROM_BASE:+_..X_EXT_ROM_SIZE", where at the moment of placement the available memory ranges were  
"DATA:10ff--1"
Error while running Linker


Добавил сегмент STR во флеш, указал размещать в нём эти строки - ситуция та же.
В симуляторе вижу что считывание идёт из флеш, а сама строка расположена в internal sram.
zltigo
Цитата(mempfis_ @ Sep 9 2009, 17:08) *
Хочу сделать запись проще....

Проще, по-гарвардовски, сделали микроконтроллер smile.gif, посему придется Вам перестать хотеть делать проще и делать "сложнее" sad.gif. Насколько смогли, авторы компилятора прикрыли проблему __flash, но дальше ручками sad.gif
mempfis_
Цитата(zltigo @ Sep 9 2009, 19:18) *
Проще, по-гарвардовски, сделали микроконтроллер smile.gif, посему придется Вам перестать хотеть делать проще и делать "сложнее" sad.gif. Насколько смогли, авторы компилятора прикрыли проблему __flash, но дальше ручками sad.gif


Т.е. эта проблема нерешаема на уровне компилятора?
Сделать сложнее смогу smile.gif Жаль программа будет не суперчитабельной sad.gif
Всем спасибо за консультации, буду переделывать код smile.gif
zltigo
Цитата(mempfis_ @ Sep 9 2009, 18:59) *
Т.е. эта проблема нерешаема на уровне компилятора?

Очевидно, что решаема, но решать (маскировать наличие) во всех аспектах ее не стали.
SSerge
Или так:
#define PutString(x) do{static char __flash str[]=x; putstring(str);}while(0)
Rst7
Все там решается.

Ключик "-y" надо вставить, если мне память не изменяет. Завтра точно гляну.
Artem_Petrik
ключ --string_initializers_in_flash (кажись так, сейчас IAR-а под рукой нет, чтоб проверить) нужен для С компилятора.
zltigo
Цитата(Rst7 @ Sep 9 2009, 20:25) *
Ключик "-y" надо вставить, если мне память не изменяет. Завтра точно гляну.

Ну это где-то с точностью до наоборот.
Цитата(Artem_Petrik @ Sep 10 2009, 12:35) *
ключ --string_initializers_in_flash (кажись так, сейчас IAR-а под рукой нет, чтоб проверить) нужен для С компилятора.

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

Цитата(SSerge @ Sep 9 2009, 20:06) *
#define PutString(x) do{static char __flash str[]=x; putstring(str);}while(0)

Для данного случая наиболее нормальный выход
dimka76
Цитата(mempfis_ @ Sep 9 2009, 19:08) *
Добрый день.
Сижу ламаю голову вот над каким вопросом - есть самописная функция putstring(unsigned char __flash *pData) которая по указателю считывает строку и передаёт её по уарту в терминал.
......................................
Собственно вопрос как можно сделать чтобы второй вариант записи работал?
Для наглядности программы хочется чтобы строки писались в самой функции.


Есть еще один вариант.
Перед каждым вызовом
Код
putstring( ... )

Объявлять новую строку
Код
static __flash unsigned char string_1[] = "ha-ha";

Т.е.
Код
static __flash unsigned char string_1[] = "ha-ha";
putstring( string_1 );

static __flash unsigned char string_2[] = "hi-hi";
putstring( string_2 );
mempfis_
Цитата(SSerge @ Sep 9 2009, 21:06) *
Или так:
#define PutString(x) do{static char __flash str[]=x; putstring(str);}while(0)


Спасибо, ваш вариант работает как мне хотелось.
Правда нет худа без добра - одинаковые строки совсем не оптимизируются и каждый раз ложатся во флеш занимая её небескрайние просторы.
Во всяком случае если придётся выводить много неповторяющийся текст то буду пользоваться этой записью smile.gif
Sergey'F
Я бы все-таки придерживался подхода все текстовые строки объявить в одном месте/файле и использовать имена строк. Так удобнее поддержка ПО - при изменении кода не надо лазить и искать строки. Как раз в этом случае __flash unsigned char txt[] = "Start Programm\r\n" идеально подходит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.