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

 
 
> Глюки компилятора IAR?, Важно! Код прошивки по непонятным причинам не стартует в МК AVR.
DiMonstr
сообщение Jan 10 2008, 19:42
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 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, воткнул директиву компилятора отключающую оптимизацию именно это процедуры. После этого всё работает. Это конечно ни есть хорошо, но выходя я пока так и не нашёл. Одним словом - шаманство!!!


Посоветуйте, в каком направлении мне копать! Кто сталкивался с такими проблемами?
Go to the top of the page
 
+Quote Post
7 страниц V  « < 2 3 4 5 6 > »   
Start new topic
Ответов (45 - 59)
SasaVitebsk
сообщение Jan 24 2008, 12:47
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



2 Сергей Борщ.
Собственно именно это я и хотел сказать, но ты, как всегда сказал это более кратко, более внятно и более аргументировано. smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 24 2008, 15:17
Сообщение #47


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 24 2008, 16:44
Сообщение #48


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(Freeze Anti @ Jan 23 2008, 21:45) *

Кстати, модель памяти я использую small.

А можно ли увеличить пространство оперативки следующими методами:
- объеденить булевые переменные в байт(регистр) и изменять их состояние побитно
- а глобальные переменные собрать в структуру?
В результате этого маневра, мы добъемся дефрагментированного расположения данных в ОЗУ. Правильно?

А по поводу диапазона переменных и их типа я не совсем понял. Расскажите немного поподробней.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 24 2008, 16:58
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 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 - это то ОНО и есть


--------------------
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 24 2008, 17:13
Сообщение #50


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(aesok @ Jan 21 2008, 23:05) *
В функциях EEPROM_* - не должны разрешаться прерывания на выходе. Они должны востанавливать состояние состояние флага "I" таким каким оно было при входе в функцию.

Я где-то читал, что во время записи в eeprom нужно отключать все прерывания, иначе, если во время операции записи в eeprom возникнет какое-либо прерывание, то возможно искажение записанной инфы. Как на самом деле?

Цитата
И вообще используйте библиотечные функции для доступа к EEPROM. В них небудет детских ошибок.

А они есть? Я что-то не нашёл ни в справочной IAR и ни в справке по библиотеке DLIB. Где искать?
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 24 2008, 17:24
Сообщение #51


кекс
******

Группа: Свой
Сообщений: 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;
}
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 24 2008, 18:49
Сообщение #52


Частый гость
**

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jan 24 2008, 18:54
Сообщение #53


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



И вы невнимательно прочитали то, что сами процитировали от aesok. Он вам написал, что нужно запрещать, но по выходу требуется НЕ РАЗРЕШАТЬ ПРЕРЫВАНИЯ, а ВОССТАНАВЛИВАТЬ бит разрешения в то состояние в котором он находился. Это не относится к работе с EEPROM средствами IAR. Там всё верно сделано.

Для этого существуют специальные ф-ии.

__enable_interrupt();__disable_interrupt();
__save_interrupt(uint8_t OldState);__restore_interrupt(uint8_t OldState);

почитай сам
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 24 2008, 19:06
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 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


--------------------
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jan 24 2008, 19:32
Сообщение #55


Частый гость
**

Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613



про типы переменных я говорил, что если у вас переменная изменяется от 1 до 200, то не стоит ее делать типа long... еще кстати... не надо использовать дробные переменные (например, float)... обычно контроллеру не надо делать столь строгих мат. расчетов, поэтому записывайте в целочисленный тип... так сказать, получится дробное число с фиксированной запятой... памяти освободится тьма... (если не ошибаюсь, float 32 бита требует...)


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 24 2008, 19:34
Сообщение #56


Частый гость
**

Группа: Свой
Сообщений: 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;
Непонятно короче.
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 24 2008, 20:17
Сообщение #57


Гуру
******

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



Цитата
Но я так и не врубился че значит цифра '1' в записи char bit0: 1;
Размер поля в битах...


--------------------
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 24 2008, 21:25
Сообщение #58


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(prottoss @ Jan 24 2008, 23:17) *
Размер поля в битах...

Всё больше начинаешь понимать, что до профессионального уровня ещё шагать и шагать...
Вот теперь ясно. Благодарю за разъяснения. a14.gif

Сообщение отредактировал DiMonstr - Jan 24 2008, 21:25
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 25 2008, 08:45
Сообщение #59


Гуру
******

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



Цитата(DiMonstr @ Jan 24 2008, 23:25) *
Всё больше начинаешь понимать, что до профессионального уровня ещё шагать и шагать...
Для начала вам нужно прочитать учебник по С. Выделить вечер и прочитать его от корки до корки. Если вы каждую элементарную вещь вроде битовых полей будете спрашивать на форуме - "шагать" будете медленно, а скоро вам просто перестанут отвечать.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DiMonstr
сообщение Jan 25 2008, 13:31
Сообщение #60


Частый гость
**

Группа: Свой
Сообщений: 81
Регистрация: 26-10-06
Из: Россия, Пенза
Пользователь №: 21 706



Цитата(Сергей Борщ @ Jan 25 2008, 11:45) *
Для начала вам нужно прочитать учебник по С. Выделить вечер и прочитать его от корки до корки. Если вы каждую элементарную вещь вроде битовых полей будете спрашивать на форуме - "шагать" будете медленно, а скоро вам просто перестанут отвечать.

В учебнике, который я изучаю, про работу с битовыми полями таким образом ничего нет. К примеру элементы структуры по этому учебнику описываюся проще, тип_переменная. О таком синтаксисе ничего не сказано. Эта фишка (и не только) уже самого компилятора зарытая и описанная в виде макроса где-то в хидерах или библиотеках.

Сообщение отредактировал DiMonstr - Jan 25 2008, 13:33
Go to the top of the page
 
+Quote Post

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

 


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


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