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

Глюки компилятора IAR?

2 Сергей Борщ.

Собственно именно это я и хотел сказать, но ты, как всегда сказал это более кратко, более внятно и более аргументировано. :)

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


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

Как я понял - речь шла о том гарантируется ли стандартом то, что результатом любого сравнения вида ">" ">=" и т.п. всегда будет только одно из двух "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.

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


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

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

 

А можно ли увеличить пространство оперативки следующими методами:

- объеденить булевые переменные в байт(регистр) и изменять их состояние побитно

- а глобальные переменные собрать в структуру?

В результате этого маневра, мы добъемся дефрагментированного расположения данных в ОЗУ. Правильно?

 

А по поводу диапазона переменных и их типа я не совсем понял. Расскажите немного поподробней.

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


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

А можно ли увеличить пространство оперативки следующими методами:

- объеденить булевые переменные в байт(регистр) и изменять их состояние побитно

- а глобальные переменные собрать в структуру?

Можно:

- объеденить булевые переменные в байт(регистр) и изменять их состояние побитно

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 - это то ОНО и есть

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


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

В функциях EEPROM_* - не должны разрешаться прерывания на выходе. Они должны востанавливать состояние состояние флага "I" таким каким оно было при входе в функцию.

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

 

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

А они есть? Я что-то не нашёл ни в справочной IAR и ни в справке по библиотеке DLIB. Где искать?

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


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

Я где-то читал, что во время записи в 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;
}

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


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

Можно...

Не знал, что структуры можно объявлять таким образом. А что означает цифра после переменной с двоеточием?

Решил я протестить этот код. В отладчике я нифига ничего не увидел, в регистрах и ОЗУ значение переменной 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

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


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

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

 

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

 

__enable_interrupt();__disable_interrupt();

__save_interrupt(uint8_t OldState);__restore_interrupt(uint8_t OldState);

 

почитай сам

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


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

Не знал, что структуры можно объявлять таким образом. А что означает цифра после переменной с двоеточием?

Решил я протестить этот код. В отладчике я нифига ничего не увидел, в регистрах и ОЗУ значение переменной 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

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


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

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

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


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

Да-а-а!? Тогда это здоровско! Под булевым я имел ввиду тоже 0/1.

#define FALSE   (0==1)
#define TRUE    (1==1)

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

Может номер бита в байте? Но засомневался, т.к. попробовал и вылетела ошибка, если указать '0'.

Под состояние бита тоже не прокатывает, т.к. здесь '4' char bit4567: 4;

Непонятно короче.

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


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

Размер поля в битах...

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

Вот теперь ясно. Благодарю за разъяснения. :a14:

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

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


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

Всё больше начинаешь понимать, что до профессионального уровня ещё шагать и шагать...
Для начала вам нужно прочитать учебник по С. Выделить вечер и прочитать его от корки до корки. Если вы каждую элементарную вещь вроде битовых полей будете спрашивать на форуме - "шагать" будете медленно, а скоро вам просто перестанут отвечать.

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


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

Для начала вам нужно прочитать учебник по С. Выделить вечер и прочитать его от корки до корки. Если вы каждую элементарную вещь вроде битовых полей будете спрашивать на форуме - "шагать" будете медленно, а скоро вам просто перестанут отвечать.

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

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

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


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

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

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

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

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

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

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

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

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

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