реклама на сайте
подробности

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Передача параметров в функцию., AVR-GCC/ATMega2560
Tuma
сообщение Aug 12 2011, 12:40
Сообщение #1





Группа: Новичок
Сообщений: 6
Регистрация: 12-08-11
Пользователь №: 66 695



Добрый день, коллеги!
Возможно я что-то недопонимаю или не знаю в C, посему возник такой вопрос:
Код
#include <stdio.h>
void SendString (const char _String[])
{
  unsigned int i = 0;
  while (_String[i] != '\0')
  {
    printf ("%c\n", _String[i]);
    i++;
  }
}

int main (void)
{
  SendString ("LaLa");
  return 0;
}

Прекрасно работает на i386.
Но ни одна из
Код
void SendString (const char _String[])
{
  unsigned int i = 0;
  while (_String[i] != '\0')
  {
    SendChar (_String[i]);
    i++;
  }
  return;
}

void SendString2 (const char *_String)
{
  while (*_String)
  {
    SendChar (*_String++);
  }
}
...
  SendString ("1234567890");
  SendString2 ("1234567890");
...

функций не работает - в функцию SendChar передаётся мусор.
Самостоятельный вызов SendChar ('a'); работает прекрасно.

Как нужно правильно передавать параметры на ATMega/AVR-GCC.

Сообщение отредактировал Tuma - Aug 12 2011, 12:43
Go to the top of the page
 
+Quote Post
Mareng
сообщение Aug 12 2011, 12:51
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 19-02-07
Пользователь №: 25 487



Код
void SendString (char String[])
{
  unsigned int i = 0;
  while (String[i])
    SendChar (String[i++]);
  return;
}
Go to the top of the page
 
+Quote Post
Tuma
сообщение Aug 12 2011, 12:58
Сообщение #3





Группа: Новичок
Сообщений: 6
Регистрация: 12-08-11
Пользователь №: 66 695



Mareng, увы, не помогло.
Упорно присылает только первый символ, а далее - мусор.
Go to the top of the page
 
+Quote Post
Mareng
сообщение Aug 12 2011, 13:03
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 19-02-07
Пользователь №: 25 487



Цитата(Tuma @ Aug 12 2011, 19:40) *
Самостоятельный вызов SendChar ('a'); работает прекрасно.

А если подряд 5-10 раз вызвать SendChar() с разными аргументами?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2011, 13:17
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Ответьте себе на два вопроса:
- Какая архитектура у AVR и как это отражается на процедуре доступа к данным размещенным во Flash и RAM;
- А Ваша функция SendChar() обеспечивает ожидание окончания процесса передачи символа.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Tuma
сообщение Aug 12 2011, 13:21
Сообщение #6





Группа: Новичок
Сообщений: 6
Регистрация: 12-08-11
Пользователь №: 66 695



Цитата
А если подряд 5-10 раз вызвать SendChar() с разными аргументами?

О, что вы! С этого всё начиналось. sm.gif Всё прекрасно работает.

Я заметил что параметр gcc -O - влияет. void SendChar (char _Char) работает всегда.
А вот void SendString (char String[]) показывает первый символ только при -O2 или -O3.
При -O1 и -Os не показывается даже первый символ - только мусор.
При -O2 или -O3 вместо двух символов SendString ("32"); приходит четыре символа: 3???, вместо четырёх - шесть: 3?????.
Замена первого символа влияет, т.е. первый символ приходит корректно.
При попытке послать один символ приходит один корректный символ.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Aug 12 2011, 15:17
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Исходники функци передачи символа покажите.
0) не очень хорошая идея свои переменные (имена) начинать с подчёркиваний. Теоретически можно нарваться. В заголовочных файлах такое применяется для того, чтоьы с пользовательскими define не пересечься.

Все приведённые Вами примеры располагают массив символов в ОЗУ.
Формулу зависимости количества мусорных символов от параметра -O выводить не надо. Надо с причиной разбираться. Имейте в виду, что у других всё работает.

Сообщение отредактировал Genadi Zawidowski - Aug 12 2011, 18:25
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2011, 16:07
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Genadi Zawidowski @ Aug 12 2011, 18:17) *
Все приведённые Вами примеры располагают массив символов в ОЗУ.

Однако с точностью до наоборот - в приведенных примерах для AVR "массивы символов", ака строки, расположены в ROM. Прикольно?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 12 2011, 16:56
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(zltigo @ Aug 12 2011, 22:07) *
Однако с точностью до наоборот - в приведенных примерах для AVR "массивы символов", ака строки, расположены в ROM. Прикольно?

Нет, в winavr строки по умолчанию располагаются в ОЗУ.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2011, 17:32
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (AHTOXA @ Aug 12 2011, 19:56) *
Нет, в winavr строки по умолчанию располагаются в ОЗУ.

Фу, какой моветон sad.gif. Имеем строчку в ROM для инициализации строчки в RAM. При этом строки в общем-то явно тяготеют к константам. Тогда переходим к ответу на второй вопрос.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 12 2011, 19:56
Сообщение #11


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zltigo @ Aug 12 2011, 20:32) *
Фу, какой моветон sad.gif.

К сожалению, просто const ничего ГЦЦ не говорит про то, что надо в ROM складывать. Но концептуально правильно: указать секцию progmem надо явно, иначе мыж тупые, не знаем, в каком проце как чего... Так что, Вас IAR тоже зомбировал sm.gif, подсадив на удобную фичу. Шучу.
Код
printf_P("1234567890");

Знаменит тем, что форматную строку держит в РОМ адназначна, но при этом putchar() все-таки прописать придется sm.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 12 2011, 20:47
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (_Pasha @ Aug 12 2011, 22:56) *
К сожалению, просто const ничего ГЦЦ не говорит про то, что надо в ROM складывать.

А const тут совсем ни причем - там все чисто все даже по умолчанию вполне разумно во flash класть.
QUOTE
Так что, Вас IAR тоже зомбировал

так к хорошему мгновенно привыкаешь sm.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Tuma
сообщение Aug 15 2011, 12:32
Сообщение #13





Группа: Новичок
Сообщений: 6
Регистрация: 12-08-11
Пользователь №: 66 695



Цитата
не очень хорошая идея свои переменные (имена) начинать с подчёркиваний.

Меня ещё мой куратор на первой работе научил так выделять передаваемые в функцию параметры.

Цитата
В заголовочных файлах такое применяется для того, чтоьы с пользовательскими define не пересечься.

Я как-то даже не задумывался что умудрюсь пересечься с какими либо объявлениями. Хотя теоретически это реально.

Всем спасибо, всё переложено в память программы, всё работает.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Aug 15 2011, 13:17
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Tuma @ Aug 15 2011, 15:32) *
Меня ещё мой куратор на первой работе научил так выделять передаваемые в функцию параметры.


Очень плохой у вас куратор. Обычно с подчеркивания начинаются служебные зарезервированные имена компилятора, типа __DATE__, __FILE__ , __noop и прочее.
Go to the top of the page
 
+Quote Post
Tuma
сообщение Aug 16 2011, 11:32
Сообщение #15





Группа: Новичок
Сообщений: 6
Регистрация: 12-08-11
Пользователь №: 66 695



Цитата
Обычно с подчеркивания начинаются служебные зарезервированные имена компилятора, типа __DATE__, __FILE__ , __noop и прочее.

Вы же сами написали "__DATE__, __FILE__ , __noop" - всё с двумя подчёркиваниями, а я использую одно и всегда с заглавной буквы - _String, _UARTData и пр..
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 19:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01484 секунд с 7
ELECTRONIX ©2004-2016