|
Глюки компилятора IAR?, Важно! Код прошивки по непонятным причинам не стартует в МК AVR. |
|
|
|
Jan 10 2008, 19:42
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Всех с прошедшими праздниками!
Присказка. Чуть больше 6 месяцев вплотную работаю с контроллерами ATMEL и компилятором IAR. Каких только финтов не выкидывала эта связка и вот очередная проблема.Программлю я поэтапно, шаг за шагом проверяя функционально законченные блоки кода. В результате, у меня получился основной код девайса и код, который производит самотестирование периферии контроллера. По отдельности все отлично и стабильно работает. Пришло время отлаживать всё в комплексе и тут начался полтергейст, который я пытаюсь изкоренить методом прямого шаманства. В чём причина конккретно не знаю, одни догадки... Суть проблемы. Короче код после прошивки то запускаетя и работает, то вообще не исполняется ни одной команды. Крутил оптимизацию, распределение памяти - не помогло. Со сбросом всё в порядке, схема не причем, контроллер тоже. Остается компилятор и наверное настройки файла *.xcl Контроллер использую Atmega8. Пишу на С. Использую стандартный lnkm8.xcl. high оптимизация проекта по размеру. IDE: IAR 4.20A/W32 [Evaluation] (4.20.1.3). Компилятор: IAR XLIB 3.29L/386 (3.29.0.12) IAR XLINK 4.59Z (4.59.26.0)
Из своего опыта. Кодил я девайс: считыватель чип-карт, который подключается к USB. Отлаживал отдельно часть кода для работы с картой ичасть кода для обмена по USB. Поставил оптимизацию всего проекта по скорости, т.к. 10 байт с карты приходили верный, а остальные контроллер не успевал обрабатывать (кодил опять же на С). Ладно добился правильной работы оптимизацией. Как только я начал отлаживать все в комплексе - обмен с картой и обмен по USB, то начались проблемы! С картой обмен есть, с USB нет. Оптимизацию вырубаю - наоборот с USB работает, а с карты искаженные данные. Долго я шаманил над проектом... И в итоге сделал так: включил оптимизацию проекта по скорости, а перед теми функциями, которые конкретно отвечают за обмен с USB, воткнул директиву компилятора отключающую оптимизацию именно это процедуры. После этого всё работает. Это конечно ни есть хорошо, но выходя я пока так и не нашёл. Одним словом - шаманство!!!
Посоветуйте, в каком направлении мне копать! Кто сталкивался с такими проблемами?
|
|
|
|
|
 |
Ответов
(45 - 59)
|
Jan 24 2008, 15:17
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Jan 24 2008, 01:37)  Как я понял - речь шла о том гарантируется ли стандартом то, что результатом любого сравнения вида ">" ">=" и т.п. всегда будет только одно из двух "1" или "0", либо такие сравнения гарантируют только "0" и "!0". Вы привели цитаты только для & и &&, что не раскрывает вопроса ;> Ну так недостающий пробел легко восполнить. Открываем Google, набираем ISO/IEC 9899-1999, скачиваем, открываем, search, >=, находим: Цитата 6.5.8 Relational operators 6 Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int. 6.5.9 Equality operators 3 The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence. Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 24 2008, 16:44
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(Freeze Anti @ Jan 23 2008, 21:45)  Кстати, модель памяти я использую small. А можно ли увеличить пространство оперативки следующими методами: - объеденить булевые переменные в байт(регистр) и изменять их состояние побитно - а глобальные переменные собрать в структуру? В результате этого маневра, мы добъемся дефрагментированного расположения данных в ОЗУ. Правильно? А по поводу диапазона переменных и их типа я не совсем понял. Расскажите немного поподробней.
|
|
|
|
|
Jan 24 2008, 16:58
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата А можно ли увеличить пространство оперативки следующими методами: - объеденить булевые переменные в байт(регистр) и изменять их состояние побитно - а глобальные переменные собрать в структуру? Можно: - объеденить булевые переменные в байт(регистр) и изменять их состояние побитно Код typedef struct __Reg { char bit0: 1; char bit1: 1; .... char bit4567: 4: } Reg_t
void Fn(...) { Reg_t RegA; RegA.bit0 = 1; RegA.bit1 ^= RegA.bit0;
RegA.bit4567 = 5;
} -а глобальные переменные собрать в структуру Project->Compiler->Optimizations: Medium - включится галка на Static Clustering - это то ОНО и есть
--------------------
|
|
|
|
|
Jan 24 2008, 17:13
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(aesok @ Jan 21 2008, 23:05)  В функциях EEPROM_* - не должны разрешаться прерывания на выходе. Они должны востанавливать состояние состояние флага "I" таким каким оно было при входе в функцию. Я где-то читал, что во время записи в eeprom нужно отключать все прерывания, иначе, если во время операции записи в eeprom возникнет какое-либо прерывание, то возможно искажение записанной инфы. Как на самом деле? Цитата И вообще используйте библиотечные функции для доступа к EEPROM. В них небудет детских ошибок. А они есть? Я что-то не нашёл ни в справочной IAR и ни в справке по библиотеке DLIB. Где искать?
|
|
|
|
|
Jan 24 2008, 17:24
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(DiMonstr @ Jan 24 2008, 20:13)  Я где-то читал, что во время записи в eeprom нужно отключать все прерывания, иначе, если во время операции записи в eeprom возникнет какое-либо прерывание, то возможно искажение записанной инфы. Как на самом деле? На самом деле прерывания надо запрещать только перед вводом "магической" последовательности в регистр EECR: сохранить флаг I запретить прерывания (i.e. обнулить флаг I) установить в EECR бит EEMWE (master write enable) установить в EECR бит EEWE (write enable) восстановить флаг I В противном случае запись может просто не начаться. Цитата они есть? Я что-то не нашёл ни в справочной IAR и ни в справке по библиотеке DLIB. Где искать? В IAR их нет, потому что IAR предоставляет возможность работать с адресным пространством eeprom как с обычной памятью: Код __eeprom char x; __eeprom char y;
if (x) { y = x; } следовательно можно пользоваться просто указателями Код typedef __eeprom char EEPROM_CHAR; typedef EEPROM_CHAR *PEEPROM_CHAR; Пример записи 20 байт непосредственно в eeprom начиная с адреса 0x10, используя возможности IAR'a: Код void ee_test(void) { PEEPROM_CHAR pChar = (PEEPROM_CHAR)0x10; int i; for (i = 0; i < 20; i++) *pChar++ = (char)i; }
|
|
|
|
|
Jan 24 2008, 18:49
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(prottoss @ Jan 24 2008, 19:58)  Можно... Не знал, что структуры можно объявлять таким образом. А что означает цифра после переменной с двоеточием? Решил я протестить этот код. В отладчике я нифига ничего не увидел, в регистрах и ОЗУ значение переменной bit4 типа char в этой структуре не изменяется. Код if (Reg.bit0 == TRUE) Reg.bit1 = FALSE; else Reg.bit0 = TRUE; while(Reg.bit0) Reg.bit4++; Ещё момент. Допустим структура состоит из однотипных элементов типа Bool. Код typedef struct __Reg { Bool bit0: 1; Bool bit1: 2; Bool bit2: 3; char bit4: 4; } TReg; Это же битовая переменная (может принимать значение 0 или 1), а в ОЗУ она будет занимать целый байт. Так не рентабельно получается. Здесь маскированный подход думаю наиболее приемлем, например: Код U8 Status;
#define Busy 4 #define NoStop 3 #define Parity 2 #define Damage 1 #define Transaction 0 #define Bit(n) (1 << (n)) // макрос работы с битами
void main(void) { Status |= Bit(Busy); // установка бита в 1 Status &= ~Bit(Damage); //сброс бита в 0 if ((Status & Bit(Busz)) != 0) break; } Теперь 5 переменных у нас будут замаскированы в одном байте... сказка!
Сообщение отредактировал DiMonstr - Jan 24 2008, 18:53
|
|
|
|
|
Jan 24 2008, 19:06
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(DiMonstr @ Jan 25 2008, 01:49)  Не знал, что структуры можно объявлять таким образом. А что означает цифра после переменной с двоеточием? Решил я протестить этот код. В отладчике я нифига ничего не увидел, в регистрах и ОЗУ значение переменной bit4 типа char в этой структуре не изменяется. Код if (Reg.bit0 == TRUE) Reg.bit1 = FALSE; else Reg.bit0 = TRUE; while(Reg.bit0) Reg.bit4++; Я не знаю, что такое у ВАС TRUE/FALSE. Но запись Код typedef struct __Reg { char bit0: 1; char bit1: 1; char bit23: 2; char bit4567: 4: } Reg_t означает, что поля bitxx в структуре НЕ булевые переменные ...Это битовые переменные! Как к ним обращаться, я показал выше. И, кстати, продемонстрированная мною структура занимает тоже ровно 1 байт.
Сообщение отредактировал prottoss - Jan 24 2008, 19:08
--------------------
|
|
|
|
|
Jan 24 2008, 19:34
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(prottoss @ Jan 24 2008, 22:06)  Да-а-а!? Тогда это здоровско! Под булевым я имел ввиду тоже 0/1. Код #define FALSE (0==1) #define TRUE (1==1) Но я так и не врубился че значит цифра '1' в записи char bit0: 1; Может номер бита в байте? Но засомневался, т.к. попробовал и вылетела ошибка, если указать '0'. Под состояние бита тоже не прокатывает, т.к. здесь '4' char bit4567: 4; Непонятно короче.
|
|
|
|
|
Jan 24 2008, 21:25
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(prottoss @ Jan 24 2008, 23:17)  Размер поля в битах... Всё больше начинаешь понимать, что до профессионального уровня ещё шагать и шагать... Вот теперь ясно. Благодарю за разъяснения.
Сообщение отредактировал DiMonstr - Jan 24 2008, 21:25
|
|
|
|
|
Jan 25 2008, 13:31
|
Частый гость
 
Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706

|
Цитата(Сергей Борщ @ Jan 25 2008, 11:45)  Для начала вам нужно прочитать учебник по С. Выделить вечер и прочитать его от корки до корки. Если вы каждую элементарную вещь вроде битовых полей будете спрашивать на форуме - "шагать" будете медленно, а скоро вам просто перестанут отвечать. В учебнике, который я изучаю, про работу с битовыми полями таким образом ничего нет. К примеру элементы структуры по этому учебнику описываюся проще, тип_переменная. О таком синтаксисе ничего не сказано. Эта фишка (и не только) уже самого компилятора зарытая и описанная в виде макроса где-то в хидерах или библиотеках.
Сообщение отредактировал DiMonstr - Jan 25 2008, 13:33
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|