Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глюки компилятора IAR?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
defunct
Цитата(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;
}
DiMonstr
Цитата(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 переменных у нас будут замаскированы в одном байте... сказка!
SasaVitebsk
И вы невнимательно прочитали то, что сами процитировали от aesok. Он вам написал, что нужно запрещать, но по выходу требуется НЕ РАЗРЕШАТЬ ПРЕРЫВАНИЯ, а ВОССТАНАВЛИВАТЬ бит разрешения в то состояние в котором он находился. Это не относится к работе с EEPROM средствами IAR. Там всё верно сделано.

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

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

почитай сам
prottoss
Цитата(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 байт.
Freeze Anti
про типы переменных я говорил, что если у вас переменная изменяется от 1 до 200, то не стоит ее делать типа long... еще кстати... не надо использовать дробные переменные (например, float)... обычно контроллеру не надо делать столь строгих мат. расчетов, поэтому записывайте в целочисленный тип... так сказать, получится дробное число с фиксированной запятой... памяти освободится тьма... (если не ошибаюсь, float 32 бита требует...)
DiMonstr
Цитата(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;
Непонятно короче.
prottoss
Цитата
Но я так и не врубился че значит цифра '1' в записи char bit0: 1;
Размер поля в битах...
DiMonstr
Цитата(prottoss @ Jan 24 2008, 23:17) *
Размер поля в битах...

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

В учебнике, который я изучаю, про работу с битовыми полями таким образом ничего нет. К примеру элементы структуры по этому учебнику описываюся проще, тип_переменная. О таком синтаксисе ничего не сказано. Эта фишка (и не только) уже самого компилятора зарытая и описанная в виде макроса где-то в хидерах или библиотеках.
SasaVitebsk
Цитата(DiMonstr @ Jan 25 2008, 17:31) *
В учебнике, который я изучаю, про работу с битовыми полями таким образом ничего нет. К примеру элементы структуры по этому учебнику описываюся проще, тип_переменная. О таком синтаксисе ничего не сказано. Эта фишка (и не только) уже самого компилятора зарытая и описанная в виде макроса где-то в хидерах или библиотеках.

Нет это чётко описано в самом компиляторе Си и в книгах тоже. Поменяйте книгу.
Сергей Борщ
Цитата(DiMonstr @ Jan 25 2008, 15:31) *
Эта фишка (и не только) уже самого компилятора зарытая и описанная в виде макроса где-то в хидерах или библиотеках.
Докажите. Можно от противного - достаточно доказать, что битовые поля не упоминаются в стандарте языка С.
DiMonstr
Цитата(Сергей Борщ @ Jan 25 2008, 16:58) *

Я не говорю, что ни в одной литературе не написано о битовых поолях.
Вы бы сами какую книгу порекомендовали по Си?
Сергей Борщ
Вы утверждали, что это "Эта фишка (и не только) уже самого компилятора зарытая". Т.е. снова, как и в начале ветки, во всем виноват компилятор а не ваше невежество.

Книга по С бывает одна: Керниган и Ритчи, "Язык программирования С". Второе (!) издание. Все остальные - ее толкования. Книга есть в интернете. Где искать - не подскажу, гугля в помощь.
DiMonstr
Цитата(Сергей Борщ @ Jan 25 2008, 18:09) *
Вы утверждали, что это "Эта фишка (и не только) уже самого компилятора зарытая". Т.е. снова, как и в начале ветки, во всем виноват компилятор а не ваше невежество.

Книга по С бывает одна: Керниган и Ритчи, "Язык программирования С". Второе (!) издание. Все остальные - ее толкования. Книга есть в интернете. Где искать - не подскажу, гугля в помощь.


Оптимизировал проект. Добавил ещё функций. Кое-что переписал. НО!!! Проблема осталась не смотря на все усилия!!! Хоть головой бейся о монитор с клавой, но программа в контроллере не запускается!!! Не знаю где капать! Весь инет перерыл. Подобного ни у кого не было! Что делать???
DiMonstr
А может попробовать скомпилять проект в WinAVR? Да в принципе это последняя надеждаsad.gif А нееет, есть ещё вариант переписать код на асме....
singlskv
Цитата(DiMonstr @ Feb 10 2008, 00:24) *
А может попробовать скомпилять проект в WinAVR? Да в принципе это последняя надеждаsad.gif А нееет, есть ещё вариант переписать код на асме....
Есть еще вариант, если, как Вы здесь утверждаете, виноват компилятор и дело
до main не доходит, если, как Вы опять же утверждаете, Вы знаете Асм,
ну дык кто Вам мешал все это время не заниматься болтовней, а просто взять листинг до main,
перенести его в студию и найти место где компилятор ошибся...
И радостно нам об этом сообщить.

Что то мне подсказывает, что "Если" получилось много, и часть из них Вы не осилили 07.gif biggrin.gif
zltigo
Цитата(singlskv @ Feb 10 2008, 01:09) *
Вы здесь утверждаете, виноват компилятор...

Можно это утверждение игнорировать начисто - я бегло просмотрел этот код. Полный мрак, начиная с переопределенной точки входа прямо в main(), деклараций переменных в header-ах, конструкций switch( константа ), отсутсвие volatile, обилия кривых макросов, & и && - по барабану,.....
В приложении, то, что подправлено за 15 минут - наверное до main() дойдет, но дальше smile.gif ....
DiMonstr
Цитата(zltigo @ Feb 10 2008, 02:17) *

Я с Вами согласен. Сам ужаснулся, когда начал с самого начала просматривать код. Вот версия проекта, которая более менее доведена до ума. Заценитеsmile.gif
C Вашей прошивкой работоспособность кода я оценить не смогу. Для этой прошивки в хидере settings.h какие значения определены следующим именам:
#define IsCheckCRC
#define IsCheckRAM
#define IsCheckJUMP
#define IsCheckAnalogScheme
#define IsCheckBlock
forever failure
Хинт: уберите весь (да, весь, вообще весь) код, до которого не доходит исполнение, оставьте только то место, на котором исполнение затыкается. Попытайтесь локализовать место, на котором программа затыкается.

ЗЫ. switch от (CurrentDevice) т.е. от константы - категорически не труъ, как уже было выше замечено. Уберите.

Ещё, хотелось бы Ваших пояснений, относительно вот этого участка кода (возможно, здесь одна из ошибок):

Value = slow_crc16(Value,(unsigned char __flash *)0, (unsigned long)&__checksum); /* здесь передаётся в третьем параметре указатель */
Value = slow_crc16(Value,(unsigned char __flash *)&zero,2); /* а здесь целое */

Что вообще должно быть здесь выполнено ?
DiMonstr
Цитата(forever failure @ Feb 10 2008, 13:58) *
Хинт: уберите весь (да, весь, вообще весь) код, до которого не доходит исполнение, оставьте только то место, на котором исполнение затыкается. Попытайтесь локализовать место, на котором программа затыкается.

В том-то и дело, что я незнаю до какого адреса доходит выполнение программы. Я делал так, сразу после main() инициализировал USART интерфейс и atmega передавала в цикле байты на комп, пока не получит ответа. Теперь после прошивки я точно мог узнать работает код или нет. Так и сделал, отключив сначала все функции тестирования. Заработало. Затем начал экспериментировать разрешая выполнение тестов и снова прошивая. Ну и что Вы думаете? Выполнение программы, то доходило до команды посылки байта, то через раз ничего не работало, то работало стабильно. Получается прога затыкается перед функцией main() на стадии инициализации стека, озу и т.д. Верно?

Цитата
ЗЫ. switch от (CurrentDevice) т.е. от константы - категорически не труъ, как уже было выше замечено. Уберите.

Понял, сделаем.

Цитата
Ещё, хотелось бы Ваших пояснений, относительно вот этого участка кода (возможно, здесь одна из ошибок):
Value = slow_crc16(Value,(unsigned char __flash *)0, (unsigned long)&__checksum); /* здесь передаётся в третьем параметре указатель */
Value = slow_crc16(Value,(unsigned char __flash *)&zero,2); /* а здесь целое */
Что вообще должно быть здесь выполнено ?

Здесь производится подсчет CRC прошивки и сравнение с CRC, которая сохраняется в конец файла прошивки на стадии компиляции.
Код
unsigned short slow_crc16(unsigned short sum, unsigned char __flash *p, unsigned long len)
{
  while (len--)
  {
    int i;
    unsigned char byte = *p++;
    
    for (i = 0; i < 8; ++i)
    {
      unsigned long osum = sum;
      sum <<= 1;
      if (byte & 0x80)
        sum |= 1;
      if (osum & 0x8000)
        sum ^= 0x1021;
      byte <<= 1;
    }
  }
  return sum;
}


Этот код к проблеме не имеет отношения, без него такая же лажа. Он был взят из "апноутов".
DiMonstr
Попутно ещё вопрос. Что происходит если программа переходит на адрес по которому лежит код команды 0xFFFF?
И чем лучше забивать свободное пространство памяти программ 0x0000, 0xFFFF или 0x1895
VladislavS
0xFFFF так же как NOP отрабатывается. Ничем забивать не надо. Если программа переходит по неправильному адресу, то выкидывать такую программу. Если такой переход вызван аппаратным сбоем - заводите собаку и лечите железо.
DiMonstr
Как в IAR написать код, который будет выполняться перед вызовом основной функции main()? Компилятор располагает такими возможностями?
zltigo
Цитата(DiMonstr @ Feb 11 2008, 23:17) *
Компилятор располагает такими возможностями?

Да, но придется взглянуть на документацию smile.gif __low_level_init(), либо просто вызвать из startup....
singlskv
Цитата(zltigo @ Feb 10 2008, 02:17) *
Можно это утверждение игнорировать начисто - я бегло просмотрел этот код. Полный мрак, начиная с переопределенной точки входа прямо в main(), деклараций переменных в header-ах,

Нда..., Вы меня заинтриговали и я тоже глянул на код...
Переопределение main это фигня, если автор точно знает что делает,
декларация переменных в хедерах...., ну сам иногда пользуюсь, иногда это удобнее
и правильнее...(в соответствующем контексте конечно...)

Но примерно 30-50 вызовов функции EEPROM_write_byte, половина из которых
вызывается из прерываний... 07.gif

Эта прога не заживет никогда, хотя автар будет еще долго утверждать что по частям
у него все работало... АМИНЬ...
DiMonstr
Спасибо.
bzx
Цитата(DiMonstr @ Feb 12 2008, 00:00) *
Спасибо.

Надеюсь Вас тут убелили, что не стоит делать хитроумные проверки в виде счётчика переходов до основной точки входа и, тем более, хаять компилятор...
DiMonstr
Цитата(bzx @ Feb 12 2008, 00:20) *
Надеюсь Вас тут убелили, что не стоит делать хитроумные проверки в виде счётчика переходов до основной точки входа и, тем более, хаять компилятор...

А вот и нет, не убедили. Я не понимаю почему не стоит делать проверки джампов до main(). Как раз там её и целесообразней сделать, чтобы ещё до начала фунциклирования кода выявить ошибку. Я не вижу в этом ничего криминального! В любых системах, перед её запуском производится тестирование оборудования.

Цитата(singlskv @ Feb 12 2008, 00:00) *
...Но примерно 30-50 вызовов функции EEPROM_write_byte, половина из которых
вызывается из прерываний... 07.gif
Эта прога не заживет никогда, хотя автар будет еще долго утверждать что по частям
у него все работало... АМИНЬ...

А в чем собственно проблема? И причем тут вызов EEPROM_write_byte. Да хоть 100 раз я вызову - коренным образом это ничего не изменит. Во-первых, я их использую для отладки. Во-вторых, вызов функции записи в eeprom из прерываний для меня не критичен. В-третьих, на ход выполнения кода это тоже никак не влияет, иначе зачем тогда eeprom? Что Вы этим хотели сказать? Конкретизируйте пожалуйста. smile3009.gif
singlskv
Цитата(DiMonstr @ Feb 12 2008, 20:44) *
Во-первых, я их использую для отладки. Во-вторых, вызов функции записи в eeprom из прерываний для меня не критичен. В-третьих, на ход выполнения кода это тоже никак не влияет, иначе зачем тогда eeprom?
Если для Вас не критично что из-за вызова функции записи в EEPROM,
прерывание может зависнуть в этом месте примерно на 3,5миллисекунды , и будут пропущены
другие прерывания, тогда не вопрос, тогда у Вас все в порядке... 07.gif
forever failure
Кстати, кто-нить смотрел checkjump.asm ? Особенно вот такое место впечатлило :
TESTJMP_SUCCESS_BRID:
INC R17
;//////////////////////////////////////////////////////////////////////////
;// Формируем адрес перехода исходя из результатов тестов
// SHL ecx, 1
// ADD R17, offset TESTJMP_FINISH;
;//////////////////////////////////////////////////////////////////////////
;// Переход в зависимости от результата
// JMP R17
;//////////////////////////////////////////////////////////////////////////
;// Програмные ловушки
TESTJMP_FINISH:
TESTJMP_FINISH_COMPLETE:
END
/*кгхм.... ну и куда дальше пошло исполнение ?
прим. мое, f. f. */

Автор, если серьёзно хотите что-то продолжить, у вас есть два выбора:
1. Внимать советам более опытных участников форума и не упираться рогами в духе
"а я вот хочу так и всё".
2. Продолжить самостоятельно заниматься этим сумеречным умопомрачением, но уже не задавать вопросы "почему у меня не заводится, наверно компилятор кривой ?"

[плохой вариант удалён]
GDI
Цитата
Я не понимаю почему не стоит делать проверки джампов до main()

Потому что Си программа стартует с main(), а все что вы понаписали до функции main() это только определения функций, т.е. код , который может быть вызван, только из функции main() или из прерываний, которые инициализируются и разрешаются опять же из функции main().
DiMonstr
Цитата(forever failure @ Feb 13 2008, 09:09) *
Кстати, кто-нить смотрел checkjump.asm ? Особенно вот такое место впечатлило...

Да этот тест ещё не дописан уважаемый!!! Не пугайтесь так. Приведенная Вами часть кода пока в разработке.


Цитата(GDI @ Feb 13 2008, 10:39) *
Потому что Си программа стартует с main(), а все что вы понаписали до функции main() это только определения функций, т.е. код , который может быть вызван, только из функции main() или из прерываний, которые инициализируются и разрешаются опять же из функции main().

А здесь я с Вами в корне не согласен! Как тут уже упоминалось, можно прицепить файл cstartup.s90 и написать код в нем. Вызов main() функции производиться из этого файла строкой:
Код
?cstartup_call_main:
    XCALL   main

Здесь я и продумываю разместить свои тесты, т.е. до инициализации стека и массивов данных.

Сегодня я провел такой эксперимент с прошивкой которая не запускается в атмеге.
Вставил в этот файл свой код, который пару раз дергает один из выводов порта.
Подключил к ноге анализатор и зашил прошивку.
Код вставил сюда:
Код
;----------------------------------------------------------------------------
; Set up the CSTACK and RSTACK pointers.
;----------------------------------------------------------------------------
    RSEG    CODE:CODE:NOROOT(1)
?SETUP_STACK:
    SBI 0x11, 4
    SBI 0x12, 4    
    CBI 0x12, 4
    SBI 0x12, 4    
    CBI 0x12, 4    
   ;; Return address stack (RSTACK)
    LDI R16,LOW(SFE(RSTACK)-1)
    OUT 0x3D,R16

После запуска стало ясно, что выполнение программы даже до этого участка не доходит!!! wacko.gif
Изменений сигнала на выводе порта не происходит!

Выходит дело, что переход с нулевого адреса выполняется не по адресу PC+0x00F9:
Код
@00000000: __program_start
---- cstartup.s90 ---------------------------------------------------------------------------------
26:           XJMP    ?C_STARTUP
+00000000:   C0F8        RJMP    PC+0x00F9        Relative jump
@00000001: ??INTVEC 2


Или в результате компиляции рождается битая прошивка.
А иначе как такое можно объяснить???!!!

Что на это скажете?!
bzx
Цитата(DiMonstr @ Feb 13 2008, 23:31) *
Или в результате компиляции рождается битая прошивка.
А иначе как такое можно объяснить???!!!
Что на это скажете?!

Откуда у Вас такая неуёмная страсть к мазохизму? Вам уже десятка два людей прямо говорят, перестаньте страдать фигнёй. Годика 2-3 непрерывно попишите чего-нибудь попроще на чистом C, тогда, возможно, и самостоятельно разберётесь что к чему и без посторонней помощи, которую Вы не хотите слышать.
forever failure
Прогнать в симуляторе АВР студии полученный код не пробовали ? Прямо по шагам по ассемблерным инструкциям, откуда стартует, куда доходит, куда не доходит. Не обломайтесь, прогоните, многое станет ясно. Еще вариант - сделать полный дизассемблерный листинг прошивки. 8к кода - это не очень много, что бы найти в нём ошибку за достаточно короткое время.
DiMonstr
Цитата(forever failure @ Feb 14 2008, 07:36) *

Прогонял я код и в AVR Studio и в IARовском отладчике. Правда в IAR я дебаггера так и не заставил шагать с 0x00 адреса. Всегда он начинает с main(). Ну да ладно...
В общем в студии всё чисто, без криминала. Всё работает.


Цитата(bzx @ Feb 14 2008, 00:21) *

Откуда у Вас такая неуёмная страсть к мазохизму? Вам уже десятка два людей прямо говорят, перестаньте страдать фигнёй. Годика 2-3 непрерывно попишите чего-нибудь попроще на чистом C, тогда, возможно, и самостоятельно разберётесь что к чему и без посторонней помощи, которую Вы не хотите слышать.

Да и так уже почти год пишу на Си. Начинал с камешка AT90USB. Таких проблем там не было, а те что были разрулил. Это второй проект, причем на самом простом контроллере из AVR. И такая засада получилась...
IgorKossak
Цитата(DiMonstr @ Feb 14 2008, 08:10) *
Прогонял я код и в AVR Studio и в IARовском отладчике. Правда в IAR я дебаггера так и не заставил шагать с 0x00 адреса. Всегда он начинает с main().

Project->Options->Debugger->Setup снять галочку Run to main.
Сергей Борщ
Цитата(DiMonstr @ Feb 14 2008, 08:10) *
Да и так уже почти год пишу на Си.
Тогда вернитесь к истокам. Создайте новый проект, напишите в нем моргалку светодиодом из четырех команд и вылизывая железо добейтесь ее устойчивой работы. Если даже такая простая программа работать не будет - надо менять или железо или профессию. Вы питание и землю на все ножки питания/земли процессора подали или только на одну пару?
Потом постепенно добавите кусочки из своего нынешнего проекта. Проверять команды перехода - полная фигня. Что вы будете делать, если тест покажет ошибку? Будете крутиться в замкнутом цикле? Но какой командой вы цикл организуете, ведь переходы-то не работают! Запрещать переходить в main тоже не нужно - если переходы не работают, вы туда просто не попадете по XCALL main, ведь переходы-то не работают.

Менять cstartup для выполнения кода перед main не нужно - почитайте про функцию __low_level_init() в IAR и секции .initX в avr-gcc.
MrYuran
Цитата(Сергей Борщ @ Jan 11 2008, 11:11) *
Первое, что нужно сделать - посмотреть в листинг и убедиться, что компилятор понял вас правильно.
Это понятно, что компилятор обвинить проще простого. У меня подобное поведение наблюдалось однажды, когда ошибочно был установлен фуз BRST. А у студента - когда подтяжка ресета вместо питания была подключена к одному из портов. Он порт настраивает на вывод - контроллер ресетится.

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


А я часто сталкиваюсь с глюками ИАРа под МСП. В основном они однообразны и заключаются в непереходе по условию if, когда вроде бы всё очевидно.
Я точно не помню, но было что-то типа такого:

char i;
...
if (i) do something
else dо other

Так вот, условие никогда не выполнялось, хотя i было явно не ноль.
И так продолжалось до тех пор, пока я не переопределил условие типа i==0 или что-то типа этого, точно уже не помню.

И случай не единичный. Но ничего , привык. Правда, теперь вот на mspgcc надо переходить, а он вообще не хочет работать (в смысле код)

Хотя согласен, чаще всего ошибки в собственном коде.
SasaVitebsk
Цитата(MrYuran @ Mar 3 2008, 18:31) *
А я часто сталкиваюсь с глюками ИАРа под МСП. В основном они однообразны и заключаются в непереходе по условию if, когда вроде бы всё очевидно.

Как правило причину уже озвучивали, - volatile. Компилятор просто видит, что вы не делали никаких операций и выбрасывает условие (оптимизирует)
Сергей Борщ
Цитата(MrYuran @ Mar 3 2008, 16:31) *
А я часто сталкиваюсь с глюками ИАРа под МСП.
А я не часто. За всю жизнь (а использую ИАР с 98 года) - 2 или 3 глюка именно ИАРа. И продолжаю спорить на ящик пива, что это глюки НЕ ИАРа. В sdcc наловил глюков 5 или 6 за один проект, но он еще довольно молодой и, увы, единственный свободный компилятор С для PIC/PIC18.
DiMonstr
Всех приветствую!!!

Я нашел причину 08.gif И она зарыта была не в коде и не в компиляторе. А в фуз битах, мать их...
FUSE BITS - ЭТО ТАКАЯ ГЕММОРОЙНАЯ ПОДСТРОЙКА КОНТРОЛЛЕРА,
ЧТО ВРЕМЕНАМИ ХОЧЕТЬСЯ НАПИТЬСЯ И ЗАБЫТЬСЯ wacko.gif

Жалко, что вспомнил я про эти биты поздновато.
Хотя я об этом и не жалею. Пока искал косяк, исправил множество ошибок в коде,
оптимизировал его, а также изучил фишки компилятора IAR.
Короче дернул меня черт посмотреть как организована FLASH память. Я знал, что она
состоит из двух секций: загрузочной и прикладной программ. Так вот, в документе я обнаружил,
что по умолчанию размер BOOT области памяти установлен максимальный посредством фузов BOOTSZ.
Я прикинул побыстрому - аха, глюки начинаются как раз, когда прошивка превышает размер в 6 КБ.
Не долго думая я сократил размер этой области до минимума. И заработало!!! 08.gif
Оказывается у меня был запрограммирован фуз BOOTRST. Тем самым я переместил вектор сброса
в BOOT сектор памяти, который и перетирался кодом прикладной программы.
Только я вот до сих пор не понял, почему одна и таже прошивка могла запуститься, а
могла и не запуститься. Наверное это зависило от того кода, который оказывался по адресу расположения вектора сброса.

a14.gif В общем всем огромное спасибо и уважуха! Я много узнал с вашей момощью. a14.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.