Перейти к содержанию
    

Подскажите как правильно передать строку в функцию?

Добрый день.

Сижу ламаю голову вот над каким вопросом - есть самописная функция 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")

 

Никакой ругани нет но и не работает совсем.

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

 

Собственно вопрос как можно сделать чтобы второй вариант записи работал?

Для наглядности программы хочется чтобы строки писались в самой функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сдается мне, линковщику нужно указать, чтобы он размещал строки во флэш памяти...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы транслятор указали что ли... ИАР? Дело, имхо, в галке "Place string literals and constants in initialized RAM"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы транслятор указали что ли... ИАР? Дело, имхо, в галке "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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хочу сделать запись проще....

Проще, по-гарвардовски, сделали микроконтроллер :), посему придется Вам перестать хотеть делать проще и делать "сложнее" :(. Насколько смогли, авторы компилятора прикрыли проблему __flash, но дальше ручками :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проще, по-гарвардовски, сделали микроконтроллер :), посему придется Вам перестать хотеть делать проще и делать "сложнее" :(. Насколько смогли, авторы компилятора прикрыли проблему __flash, но дальше ручками :(

 

Т.е. эта проблема нерешаема на уровне компилятора?

Сделать сложнее смогу :) Жаль программа будет не суперчитабельной :(

Всем спасибо за консультации, буду переделывать код :)

Изменено пользователем mempfis_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. эта проблема нерешаема на уровне компилятора?

Очевидно, что решаема, но решать (маскировать наличие) во всех аспектах ее не стали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все там решается.

 

Ключик "-y" надо вставить, если мне память не изменяет. Завтра точно гляну.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ключ --string_initializers_in_flash (кажись так, сейчас IAR-а под рукой нет, чтоб проверить) нужен для С компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ключик "-y" надо вставить, если мне память не изменяет. Завтра точно гляну.

Ну это где-то с точностью до наоборот.

ключ --string_initializers_in_flash (кажись так, сейчас IAR-а под рукой нет, чтоб проверить) нужен для С компилятора.

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

 

#define PutString(x) do{static char __flash str[]=x; putstring(str);}while(0)

Для данного случая наиболее нормальный выход

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день.

Сижу ламаю голову вот над каким вопросом - есть самописная функция 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 );

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или так:

#define PutString(x) do{static char __flash str[]=x; putstring(str);}while(0)

 

Спасибо, ваш вариант работает как мне хотелось.

Правда нет худа без добра - одинаковые строки совсем не оптимизируются и каждый раз ложатся во флеш занимая её небескрайние просторы.

Во всяком случае если придётся выводить много неповторяющийся текст то буду пользоваться этой записью :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы все-таки придерживался подхода все текстовые строки объявить в одном месте/файле и использовать имена строк. Так удобнее поддержка ПО - при изменении кода не надо лазить и искать строки. Как раз в этом случае __flash unsigned char txt[] = "Start Programm\r\n" идеально подходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...