|
или глюк в IAR, или я что- то упускаю, вопрос по массиву |
|
|
|
Jan 22 2011, 18:29
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
вот код Код void main (void) { __enable_interrupt(); uint32_t timeStamp =CntT1_ms;
char data [15]; uint8_t num = 0; putString("AT+CSQ\r"); //уровень приема сигнала
for(;;){ if ((CntT1_ms-timeStamp) >= LED_BLINK_PERIOD) { //off (LED); putString("AT\r"); timeStamp =CntT1_ms; } if ( hasinput() ) { data [num] = getchar(); cpl (LED); }
} } во- первых, странно, что ИАР ругается на варнинг на объявление массива char data[15]; Warning[Pe550]: variable "data" was set but never used D:\works\projects\Blink_LED mega8 +HT\main.c 102 И как только часть кода data [num] = getchar(); включаю в работу (убираю комментарии), отказывается работать часть кода между main (); и for (;;) т.е. putString("AT+CSQ\r"); Что за странное поведение?
Сообщение отредактировал Метценгерштейн - Jan 22 2011, 18:30
|
|
|
|
|
Jan 22 2011, 19:29
|

Местный
  
Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639

|
Цитата(Метценгерштейн @ Jan 22 2011, 20:29)  Цитата Warning[Pe550]: variable "data" was set but never used D:\works\projects\Blink_LED mega8 +HT\main.c 102 1. Ничего странного - ведь написано же что переменная объявленна, но не используется - Вы же сами ее закоментировали. 2. А Вы не пробовали объявлять char data [15] глобальной переменной по отношению к функции void main (void) ?
|
|
|
|
|
Jan 22 2011, 20:10
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
что значит не беру, еще как беру, смотрите Код if ( hasinput() ) { data [num] = getchar(); } если есть что- то из данных (ф-я hasinput вернула 1- это внешний файл), я вызываю ф-ю getchar, и ее значение кладу в массив. Не про то речь. Это все прекрасно работает, но не в этом месте у меня- тут мне и не понятно почему. Объявление массива как глобального помогло- сейчас буду проверять в железе. Тогда вопрос- а почему нельзя было локально на всю ф-ю main() ее объявлять?
Сообщение отредактировал Метценгерштейн - Jan 22 2011, 20:12
|
|
|
|
|
Jan 22 2011, 20:16
|

Местный
  
Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639

|
Цитата(Метценгерштейн @ Jan 22 2011, 22:10)  что значит не беру, еще как беру, смотрите ... тут мне и не понятно почему. Уважаемый Dog Pawlowa, имел ввиду, что у Вас не видно что data [ num] меняет значение. Может нам не видно, а где-то " но не в этом месте " - значение num все таки изменяется ?
|
|
|
|
|
Jan 22 2011, 22:21
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата он ругается на переменную data [], а это массив у меня, а не переменная. И с чего- это я его не использую? а массив типа не переменная что ли? )) и всё-же где инициализация порта? как-то немного странно... Код и, что он в данном случае наоптимизировал? Выкинул мой массив? Посчитал, что он мне не нужен? ну а зачем он нужен, если вы всё кладете в нулевой элемент? его в таком случае можно заменить одной переменной типа char, но это ведь всё равно не объясняет почему перестаёт исполняться putString("AT+CSQ\r"); //уровень приема сигнала что-то тут не то... может таки по прерыванию проц прыгает Бог знает куда? Не думаю, что IAR на столько плох, что даёт Warning просто так... что там с hasinput() ? Может быть она сразу, на этапе компиляции, разворачивается в false и весь if ( hasinput() ) выкидывается? Это может произойти, к примеру, если флаг(который, как я понимаю, проверяет hasinput()) не объявлен с volatile(поднимается то флажок в прерывании). В общем, кажется, вы запамятовали, что все глобальные переменные, с которыми ведется работа в обработчике прерывания - должны быть volatile... Но всё это не объясняет исчезновения putString("AT+CSQ\r");.... тут надо как-то повнимательнее посмотреть что к чему...
--------------------
The truth is out there...
|
|
|
|
|
Jan 22 2011, 22:51
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
на самом деле интересно и не понятно, зачем ИАР выкинул код. Вот весь проект целиком. http://files.mail.ru/6WP6WHя имел ввиду, что если сделать запись data [0] = getchar(); то программа отказывается выполнять то, что записано сразу после main() т.е. она сразу глючит. Ещё раз, глюки прошли как только вынес массив из вне main() ИАР последней версии 5.51
|
|
|
|
|
Jan 22 2011, 23:38
|

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

|
QUOTE (Метценгерштейн @ Jan 23 2011, 01:51)  Ещё раз, глюки прошли как только вынес массив из вне main() Не из main() а из стека. Перед тем, как начинать программировать следует ТВЕРДО усвоить,.что такое стеки и как они используются и соответственно, перед тем, как пихать что попало в стек, надо подумать, сколько памяти для стека/стеков выделить.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 22 2011, 23:48
|

Местный
  
Группа: Свой
Сообщений: 386
Регистрация: 1-12-05
Пользователь №: 11 639

|
Цитата(zltigo @ Jan 23 2011, 01:38)  Перед тем, как начинать программировать следует ТВЕРДО усвоить,.что такое стеки и как они используются и соответственно, Я бы уточнил: усвоить что такое переменные, их область видимости, время жизни. И как вызываемые программой функции используют те самые стеки для работы с этими переменными. Как пример: если б нужно (по каким-то причинам - ограничить область видимости) оставить переменную char data[15] внутри функции main но при этом обозначить ее как static char data[15]. Программа тоже б работала стабильно в указанном случае
|
|
|
|
|
Jan 23 2011, 12:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
хорошо, простой пример: есть некий Код void main(void) { char mass [10]; int a = 3; int b = 5;
if (a < b) { mass [0] = 'D'; } } и, получается, здесь тоже надо массив как статик указывать? все- равно не понятно.
|
|
|
|
|
Jan 23 2011, 12:58
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Метценгерштейн @ Jan 23 2011, 15:32)  все- равно не понятно. Чем этот пример отличается от того, что приводилось раньше? Если Вы не используете данные массива, какое значение имеет, как определен массив ? Вы бы книжки прочитали, чтобы постичь те несколько десятков правил программирования дополнительно к синтаксису операторов.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jan 23 2011, 13:14
|

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

|
QUOTE (Метценгерштейн @ Jan 23 2011, 15:32)  и, получается, здесь тоже надо массив как статик указывать? Надо делать так, как Вам надо. При этом, если Вам надо размещать массив в стеке то надо иметь в стеке достаточно места. Где Вам надо размещать массив Вы не знаете, что такое стек Вы не знаете. Размера стека который Вам нагенерил какой-нибудь безумный визард по умолчанию Вы тоже не знаете (подсказываю он у Вас в проекте 32 бвйта из которых Вы лихо 15 отдали под массив). Рановато взялись программировать  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 23 2011, 13:24
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Мне как- то лет в 18 инструктор по вождению говорил, что рано я за руль сел... И, что? послушать его надо было? И больше не садиться? Тогда и не научился бы никогда. Сейчас я довольно неплохо езжу- практика, практика... Так что неуместно Ваше замечание. Тем не менее, за помощь спасибо.
Я знаю что такое стек, писал на асме под авры.
То, что таким образом, объявляя массив, загоняю его в стек- признаю, упустил.
Сейчас читаю литературу, пытаюсь найти то, где это написано, что стек у меня 32 байта.
И, напомню, мы в разделе для начинающих... Думаю, многие начинающие на подобные грабли да наступали.
|
|
|
|
|
Jan 23 2011, 13:36
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Метценгерштейн @ Jan 23 2011, 16:24)  И, напомню, мы в разделе для начинающих... Это не освобождает Вас от необходимости осмысливать вопросы, если Вы хотите получить ответы. Надеюсь, за рулем Вы более адекватны. Тут пытаются Вам помочь, но не очень понятно, что Вам нужно. Массив создать? - зачем, если он не используется? Что Вы пытаетесь понять, наобум придумывая такие примеры? Переменные должны разместиться в предназначенной для них памяти. Все.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Jan 23 2011, 13:41
|

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

|
QUOTE (Метценгерштейн @ Jan 23 2011, 16:24)  То, что таким образом, объявляя массив, загоняю его в стек- признаю, упустил. Теперь знаете. QUOTE Сейчас читаю литературу, пытаюсь найти то, где это написано, что стек у меня 32 байта. Читать бесполезно - надо рассматривать картинки Вашего "проекта" - там на одной из картинок выставлено 32 байта. Кем, зачем и почему мне не ведомо, но это так. QUOTE (Метценгерштейн @ Jan 23 2011, 16:24)  Я знаю что такое стек, писал на асме под авры. Ну и как Вы устанавливали размеры стеков на ASM?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 23 2011, 14:35
|

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

|
QUOTE (Метценгерштейн @ Jan 23 2011, 17:00)  ldi r16, low(RAMEND) out SPL, r16 ;инициализация стека Третья часть марлезонского балета - где здесь у Вас РАЗМЕР  стека  ? Это ТОЛЬКО инициализация указателя. Сколько там места ниже указателя до первых Ваших переменных неведомо. Хватит-ли этого места для, например, размещения желаемых локальных переменных до того, как они наедут на статические переменные это чисто на вашей совести.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 23 2011, 15:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Получается, так. Я устанавливал только указатель на память. Размер стека не устанавливал. В ИАРе стоит размер стека 0х20, т.е. 32 байта как Вы и указали.
Итого, если объявляю массив внутри main (), то он сохранится в стеке, а если в глобальных переменных, то где? Пока не нашел ответа в литературе.
Почему в стартовом коде Второй if бессмысленный с точки зрения применения результатов. Т.е. в результате его выполнения или невыполнения ничего в данном объекте компиляции не меняется. ?
Очевидно, что бессмысленна запись data [num] = getchar();
т.к. массив объявлен в стеке, внутри main()
Сообщение отредактировал Метценгерштейн - Jan 23 2011, 15:43
|
|
|
|
|
Jan 24 2011, 11:00
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Выход из функции и вызов другой функции - разные понятия. При вызове, со стеком вызывающей функции ничего плохого не происходит, а стек вызываемой "дописывается" дальше. При выходе(вообще-то это называется возврат) - стек функции теряется. Это как-бээ физически. Одкано есть такое понятие, как область видимости. Это означает, что переменные, объявленные локально(в функци) не будут видны другим функциям(в том числе и тем, которые были вызваны этой функцией), хотя при этом эти переменные и присутствуют в стеке и имеют определенные значения. Вот ведь как оно бывает))))))
В вашей программе же не просто так бесконечный цикл используется. Это как раз для того, чтобы возврата из main не было. И вам уже достаточно подробно растолковали почему именно компилятор при оптимизации выбрасывает ваш массив, вместе с ifом.
--------------------
The truth is out there...
|
|
|
|
|
Jan 24 2011, 13:44
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Извиняюсь, похоже, торможу я хорошо Я, безусловно все ответы перечитывал, и не раз. Я не игнорирую мне сообщения, пытаюсь вникнуть и понять их. Букварь (K&R) тоже читаю. Так речь- то про что у нас- про оптимизацию, что вызывающая ф-я бесполезна, т.к. массив я дальше нигде не задействовал? Хотите сказать, если бы я дальше в коде использовал этот массив, например так: Код if (data [0] == 'S') cpl (LED); было бы все нормально? Не было у меня все нормально, использовал я массив и имел все- равно глюки. И причем тогда область видимости переменных? Если все банально упирается в то, что дальше этот массив мой нигде не использовался? И как тогда решилась проблема с выносом массива в глобальные переменные?
Сообщение отредактировал Метценгерштейн - Jan 24 2011, 13:55
|
|
|
|
|
Jan 24 2011, 14:17
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата было бы все нормально? Не было у меня все нормально, использовал я массив и имел все- равно глюки. ну вам же объяснили, что при стеке 32байта, отнимать 15 под массив, а потом ещё и вызывать другие функции(которые тоже хотят стека как минимум для сохранения адреса возврата) было опрометчивым решением и скорее всего приводило к переполнению стека со всеми вытекающими последствиями. Объявление же массива глобально, позволяет не размещать его в стеке и таким образом обеспечить нормальный вызов и возврат других функций. Это лишь гипотеза. Также, возможно, у компилятора другая стратегия оптимизации глобальных переменных ибо факт неиспользования уже становится далеко не таким очевидным, как в случае с локальной переменной. И т.д. и т.п., как говорится )) Про область видимости рассказывал для того чтобы: 1. подчеркнуть на сколько очевидно, что ваш массив более нигде не используется. 2. немного помочь вам в самообразовании ))
--------------------
The truth is out there...
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|