Error pe065 expected a

IAR Embedded Workbench for ARM, устранение проблем.
     

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом — просто выделите ошибочное слово или фразу и нажмите Shift Enter.

IAR EW ARM: устранение ошибок компиляции Печать

Добавил(а) microsin

  

На этой страничке решил собрать ошибки, возникающие при компиляции, линковке, отладке в IDE IAR Embedded Workbench for ARM, и методы их устранения.

Ошибка произошла из-за того, что я вынес в отдельный файл pins.c определения составных переменных:

//[Файл pio.h] 
// Вычисление размера массива элементов Pin
// Массив должен быть локальным, (не указателем),
// иначе вычисление будет некорректным.
#define PIO_LISTSIZE(list) (sizeof(list) / sizeof(Pin))
//[Файл board.h]
// Столбцы опроса клавиатуры ( захват ввода )
#define PIN_KBMATRIX_COL_0 {1 << 0, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_PULLUP}
#define PIN_KBMATRIX_COL_1 {1 << 1, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_PULLUP}
#define PIN_KBMATRIX_COL_2 {1 << 2, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_PULLUP}
#define PIN_KBMATRIX_COL_3 {1 << 3, AT91C_BASE_PIOA, AT91C_ID_PIOA, PIO_INPUT, PIO_PULLUP}
#define PINS_KBMATRIX_COLS PIN_KBMATRIX_COL_0, PIN_KBMATRIX_COL_1, PIN_KBMATRIX_COL_2, PIN_KBMATRIX_COL_3
//[Файл pins.c]
#include "board.h"const Pin pinsCol[] = {PINS_KBMATRIX_COLS};
//[Файл pins.h]
extern const Pin pinsCol[];
//[Файл main.c]
#include "pins.h"#include ... // Вот тут компилятор ругался на PIO_LISTSIZE, // Error [Pe070]: incomplete type is not allowed for (i=0; i < PIO_LISTSIZE(pinsCol); i++) { ...

Ошибка [Pe070] возникала потому, что макрос PIO_LISTSIZE не мог вычислить sizeof(list). Решение: в pins.h указать размер массива. Связано с неудобствами — нужно следить за синхронизировать pins.c и pins.h. Устранение ошибки:

//[Файл pins.h]
extern const Pin pinsCol[4];

На языке C одиночный оператор может состоять из нескольких строк текста. Принято, что не последняя строка такого оператора должна завершаться обратным слешем ().

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

Error[Pe008]: missing closing quote C:папкамодуль.c 19
Error[Pe007]: unrecognized token C:папкамодуль.c 23
Error[Pe065]: expected a «;» C:папкамодуль.c 23

Пример оператора с ошибкой и без ошибки:

multistring_operator.png

Пропущенный слеш нужно искать в строке перед второй ошибкой.

[Случай 1]

Долго не мог разобраться, почему возникала ошибка Error[Pe147]: declaration is incompatible with «TParams const __data папка_проектаvars.c 22 paramDefault» (declared at line 22). У меня была задана структура TParams как тип:

typedef __packed struct _Params{
    u32 paramseed;
    u32 versionARM;
    ...
    u8 lblstate[15];
    u16 CRC;} TParams;

Грешил даже на то, что структура назначалась как переменной, так и константе:

TParams param;const TParams paramDefault = {
    0xAA55AA55,
    0x00000000,
    ...
    LABEL_DEFAULT,
    0x0000};

Оказалось все проще (хотя сразу не разобрался потому, что компилятор не указывал на это место) — я просто забыл ключевое слово const в хедере, где предварительно объявлялись param и paramDefault. Было там так (это ошибочно):

extern TParams param;extern TParams paramDefault;

А для исправления ошибки должно быть так:

extern TParams param;extern const TParams paramDefault;

[Случай 2]

При портировании проекта BIGTREETECH TFT35 V3.0 из среды Visual Studio Code (VSC, VSCode) на IAR столкнулся с ошибкой несовместимости определений в iccarm_builtin.h и core_cm3.h:

Error[Pe147]: declaration is incompatible with "__nounwind __interwork __softfp
 unsigned int __iar_builtin_REV16(unsigned int)" (declared at line 199 of
 "C:Program Files (x86)IAR SystemsEmbedded Workbench 8.1armincciccarm_builtin.h")
 M:asmBIGTREETECH-TouchScreenFirmware-masterTFTsrcLibrariescmsisCore-CM3core_cm3.h 1124

Как исправить:

1. Удалить файл core_cm3.h, либо переименовать его вcore_cm3.h.old.
2. Зайти в свойства проекта, в разделе General Optoins -> закладка Library Configuration поставить галочку «Use CMSIS».

IAR Use CMSIS

Иногда после продолжительных правок трудно найти место, где пропустили точку с запятой. Например, компилятор неожиданно выдает ошибки на синтаксис в файле kbmatrix.h, который Вы даже не исправляли:

Remark[Pe082]: storage class is not first C:asmtestprojectincludekbmatrix.h 25
Error[Pe065]: expected a «;» C:asmtestprojectincludekbmatrix.h 25
Error[Pe757]: variable «KeyEventCallback» is not a type name C:asmtestprojectincludekbmatrix.h 54
Error[Pe757]: variable «KeyEventCallback» is not a type name C:asmtestprojectincludekbmatrix.h 67
Error while running C/C++ Compiler

Для того, чтобы найти действительное место ошибки, нужно найти все включения файла kbmatrix.h — перед ним наверняка будут другие включаемые заголовки, в которых допущена ошибка. Запускаем общий поиск по всему проекту, для чего жмем Ctrl+F и в строке поиска указываем kbmatrix.h. Переключатель «Look in» должен стоять на «Project files and all include files».

missing semicolon01

После поиска получим список файлов, которые включают директивой #include файл kbmatrix.h:

C:asmtestprojectkbmatrix.c 4 #include «kbmatrix.h»
C:asmtestprojectincludepins.h 3 #include «kbmatrix.h»
C:asmtestprojectpins.c 6 #include «kbmatrix.h»
———-
Found 3 instances. Searched in 270 files.

В одном из этих найденных файлов (kbmatrix.c, pins.h, pins.c), перед #include «kbmatrix.h» включаются другие файлы, в которых допущена ошибка. Теперь место пропущенной точки с запятой найти легко. В моем примере ошибка была в исправленном файле mytypes.h. Вот содержимое файла pins.h (он был в списке найденных), где добавлялся заголовок mytypes.h с ошибкой:

#include «settings.h»
#include «mytypes.h»
#include «kbmatrix.h»
..

Просмотрев список включаемых файлов, перед #include «kbmatrix.h», я увидел файл, который исправлял — mytypes.h, в нем как раз и была ошибка (пропущена точка с запятой после определения типа структуры).

[Причина 1]

Возможно, что пропущено словечко void в параметрах при определении функции. Пример:

extern unsigned char DBGU_GetChar ();unsigned char DBGU_GetChar (){
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY) == 0);
    return AT91C_BASE_DBGU->DBGU_RHR;}

Исправить нужно так:

extern unsigned char DBGU_GetChar (void);unsigned char DBGU_GetChar (void){
    while ((AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY) == 0);
    return AT91C_BASE_DBGU->DBGU_RHR;}

Пример лога ошибок:

Error[Pe020]: identifier "FILE" is undefined C:myprojectprecompiled-IAR-libsat91libperipheralsdbgudbgu.c 82 
Error[Pe020]: identifier "stdout" is undefined C:myprojectprecompiled-IAR-libsat91libperipheralsdbgudbgu.c 84 
Error[Pe020]: identifier "stderr" is undefined C:myprojectprecompiled-IAR-libsat91libperipheralsdbgudbgu.c 84 
Error[Pe020]: identifier "FILE" is undefined C:myprojectprecompiled-IAR-libsat91libperipheralsdbgudbgu.c 103 
Error[Pe020]: identifier "stdout" is undefined C:myprojectprecompiled-IAR-libsat91libperipheralsdbgudbgu.c 141 
Error while running C/C++ Compiler 

Определение FILE находится в заголовочном файле stdlib.h, поэтому нужно подключить его директивой #include. Однако иногда этого недостаточно, потому что поддержка FILE присутствует только в варианте выбора библиотек Full, но может быть выбран другой вариант — None или Normal с целью экономии памяти встраиваемых систем. Чтобы использовать FILE, необходимо переключиться на полный вариант стандартных библиотек это делается опцией командной строки компилятора —dlib full. Либо можно это настроить в диалоге свойств проекта (Options…) -> General Options -> Library Configuration -> Library: поставьте Full:

IAR Library Full

Имейте в виду, что полный вариант стандартных библиотек (Full) приведет к намного большему объему кода. Поэтому если Вы используете FILE только для печати диагностических сообщений в stderr, то лучше использовать какой-нибудь другой способ вывода сообщений.

[Причина 2]

Если в свойствах проекта, раздел C/C++ Compiler -> C dialect стоит галочка «Require prototypes», то для не переопределенных weak-функций это будет гарантированно вызвать ошибку.

IAR Require prototypes

Снимите эту галочку, и ошибка Pa045 пропадет.

Проблема в том, что в блоке памяти [0x00100000-0x001002db] находится код, до которого не могут достать ассемблерные команды короткого перехода, находящиеся в ассемблерном коде (обычно в других модулях). В этом случае нужно править ассемблерный код, чтобы переходы были длинными, либо переписать код с ассемблера на C (тогда компилятор сам подставит нужные команды). Другое решение указать компилятору генерировать код для режима процессора не thumb, а arm (Свойства проекта (Options…) -> General Options -> C/C++ Compiler -> Processor mode -> Arm).

Чтобы сгенерировать карту памяти и статистику линковки (это поможет найти проблему), откройте свойства проекта (Options…) -> General Options -> Linker -> List -> Поставьте галочки на «Generate linker map file» и на «Generate log file», а также все галочки ниже на опциях лог-файла. Лог-файл см. в файле имя_конфигурацииListимя_проекта.log, а карту распределения памяти в файле имя_конфигурацииListимя_проекта.map.

Предупреждение возникало при попытке вызвать из кода на C функцию abs, пример:

Pa = ((float)valU/100000) * ((float)valI/100000) * abs(cos(RadianAngle));

Дело в том, что на простом C (не C++) нельзя распознать прототип функции abs по типу переменной. Только для C++ можно автоматически подставить нужный прототип abs (для разных типов аргументов на C++ имеются разные реализации abs). В данном случае в параметре была переменная типа float, а определение abs подразумевало в параметре целый тип. На самом деле на C нужно напрямую вызывать abs с нужным функционалом по отдельному имени, здесь подойдет fabsf:

//Pa = ((float)valU/100000) * ((float)valI/100000) * abs(cos(RadianAngle));
Pa = ((float)valU/100000) * ((float)valI/100000) * fabsf(cos(RadianAngle));

Пример кода, который генерирует предупреждение Pa091:

unsigned char lblstyle, set, clear;
 
clear = 0x80;
set   = 0x02;
lblstyle &= ~clear;   //тут предупреждение Pa091
lblstyle |= set;

Причина ошибки в том, что оператор инверсии ~ делает приведение типа unsigned char к типу signed int перед инверсией. Для того, чтобы пропало предупреждение, нужно перед инверсией дополнительно вставить ключевое слово unsigned:

unsigned char lblstyle, set, clear;
 
clear = 0x80;
set   = 0x02;//lblstyle &= ~clear;
lblstyle &= ~(unsigned)clear;
lblstyle |= set;

Такая ошибка возникает при логических операциях с константами из перечисления (которые определены через enum). Вот пример кода, который генерирует предупреждение Pe188:

typedef enum{
   MODE_MASK              = 0x00FF,
   TEST                   = 0x4000,
   MODE_INIT              = 0x2000,
   MODE_FIRMWARE          = 0x1000,
   ..
   MODE_LOAD_VARS         = 0x00FE}MODE;
 
MODE appmode = MODE_LOAD_VARS | MODE_INIT;           //Warning[Pe188]!

Причина предупреждения в том, что результатом логической операции будет целочисленный тип, а не тип enum. Исправить можно, если явно указать, что результат операции будет иметь тип перечисления:

MODE appmode = (MODE)(MODE_LOAD_VARS | MODE_INIT);   //OK

Когда 2 заголовочных файла ссылаются друг на друга директивой #include, то могут возникнуть ошибки Error[Pe020]: identifier «имя_идентификатора» имя_файла.h номер строки is undefined (упомянутый идентификатор не найден). К примеру, в заголовочный файл headerA.h подключен файл headerB.h, и также к файлу headerB.h подключен файл headerA.h — тогда блок защиты от повторного включения заголовка [2] не даст видимости всех нужных имен, определенных в первом подключенном заголовке.

////////////////////////////////////////////
// Содержимое заголовка headerA.h
#ifndef __HEADERA__
#define __HEADERA__  #include "headerB.h"//Здесь определения идентификаторов, некоторые
// из которых должны быть видны в заголовке
// headerB.h. ..
#endif //__HEADERA__////////////////////////////////////////////
// Содержимое заголовка headerB.h
#ifndef __HEADERB__
#define __HEADERB__  #include "headerA.h"  //Здесь определения идентификаторов, некоторые
// из которых должны быть видны в заголовке
// headerA.h. ..
#endif //__HEADERB__

Для того, чтобы исправить эту ситуацию, требуется создать третий заголовок headerC.h, который будет содержать общие для headerA.h и headerB.h определения, и подключить headerC.h в headerA.h и headerB.h, чтобы они не ссылались друг на друга.

////////////////////////////////////////////
//Содержимое заголовка headerA.h
#ifndef __HEADERA__
#define __HEADERA__  //#include "headerB.h"
#include "headerC.h"  //Все идентификаторы, которые должны быть видны
// в headerB.h, перенесены в заголовок headerC.h. .. #endif //__HEADERA__
////////////////////////////////////////////
// Содержимое заголовка headerB.h
#ifndef __HEADERB__
#define __HEADERB__  //#include "headerA.h"
#include "headerC.h"  //Все идентификаторы, которые должны быть видны
// в headerA.h, перенесены в заголовок headerC.h. .. #endif //__HEADERB__

Постоянно достают предупреждения компилятора IAR о неправильной строке форматирования (printf, sprintf, sscanf): «IAR EWB ARM: Remark[Pe181]: argument is incompatible with corresponding format string conversion».

Избавиться от таких предупреждений поможет правильный выбор опции форматирования вывода printf. Для подробной информации см. [3].

  • Функция printf, аргумент u8 (unsigned char), строка формата %u -> надо поменять формат на %i.
  • Функция printf, аргумент u16 (unsigned short), строка формата %u -> надо поменять формат на %i.
  • Функция sscanf, аргумент u8 (unsigned char), строка формата %u или %i -> надо поменять формат на %hu, а тип аргумента на u16 (unsigned short).

Ошибка может возникнуть, если неправильно определена переменная структуры, например:

    //Здесь будет Warning[Pe1000]: a storage class ..
    struct myStructVariable
    {
        char var1;
        int  var2;
    };

Исправить предупреждение Pe1000 можно, если правильно указать экземпляр переменной структуры:

    struct
    {
        char var1;
        int  var2;
    }myStructVariable;

[140110]

Вопрос: мне нужно кастомизировать вывод на собственное устройство отображения (LCD). Все сделал, как написано в документации IAR — определил внешнюю функцию MyLowLevelPutchar, раскомментировал функцию __write, но почему-то при вызовах printf и putchar вывод на LCD не происходит. Функция __write не вызывается, и код, который я написал в теле функции MyLowLevelPutchar, не работает. В чем проблема?

Ответ: Вы все сделали правильно, но кроме этого в некоторых версиях IAR (например 4.20) необходимо особым образом выбрать конфигурацию библиотек DLIB. Это делается через свойства проекта General Options -> Library Configuration -> Library. Попробуйте из выпадающего списка выбрать вариант Normal, и если не заработает, то попробуйте выбрать Full. У меня иерархия вызовов в IAR версии 4.20 работала почему-то следующим образом: если выбрать Full, то последовательность вызова получается printf -> .. -> putchar -> fputc, и в этом варианте ничего не работало (код в MyLowLevelPutchar не вызывается). Если выбрать Normal, то тогда цепочка вызовов printf -> .. -> putchar -> __write, и в этом случае перенаправление вывода работает (потому что в функция __write вызывает пользовательский код из MyLowLevelPutchar).

[140312]

Такая ошибка возникает, когда Вы перенесли проект в другую папку, но перед запуском отладки не сделали очистку и не перекомпилировали проект. В отладочных файлах запомнились старые абсолютные пути до фалов исходного кода, которые теперь не соответствуют реальным. Чтобы исправить ошибку, выберите пункт меню Project -> Clean, после чего запустите отладку. Проект скомпилируется заново, и теперь отладка запустится без ошибки.

[140515]

Для больших проектов время компиляции может составлять большую проблему. Есть несколько советов, как можно уменьшить время компиляции.

1. Убедитесь, что в каждом заголовочном файле у Вас есть защитные заголовки, например:

#ifndef __HFILE_H#define __HFILE_H
   /* ... */#endif

Подробнее про защитные заголовки см. [4]. Кроме того, проверьте файлы исходного кода на лишние подключения заголовков директивой #include. Этот фактор значительно влияет на скорость компиляции. 

2. Создайте предварительно скомпилированные библиотеки, куда поместите редко изменяемые модули: BSP (Board Support Package, пакет поддержки платы разработчика), стеки протоколов и т. д. Это нужно делать периодически для кода, который остается неизменным, и который не нужно перекомпилировать каждый раз, когда что-то меняется в коде приложения. Подробнее см. [5].

3. Запретите генерацию файлов листинга компилятора (Options -> C/C++ Compiler -> List).

4. Если некоторые файлы находятся на сетевом диске (даже если это RAM-диск на сервере), попробуйте сделать их локальными, т. е. скопировать на жесткий диск рабочей станции, и компилировать оттуда. Если это ускорит компиляцию, то значит имелись проблемы, связанные с сетевой файловой системой (NFS/Samba).

5. Если совет 4 помог (при использовании локального диска компиляция ускорилась), то может помочь размещение на локальном диске только объектных файлов и файлов листинга. Для этого измените настройки Project -> Options -> General Options -> Output. Сконфигурируйте пути «Object files» и «List files» так, чтобы они были размещены не на сети, а локально.

6. Если при компиляции бывают случаи, что процесс сильно замедляется или среда IAR зависает, то возможно, что в этот момент происходит сканирование рабочих файлов антивирусом. Такой случай может привести также к сообщениям о запрещенном доступе (denied permission), об истечении таймаута.

Для того, чтобы исключить проверку антивирусом папок IAR, нужно добавить в исключения антивируса следующие папки:

• Инсталляционный каталог IAR (например, это может быть папка C:Program FilesIAR SystemsEmbedded Workbench 5.4).
• C:Program FilesCommon FilesIAR Systems
• C:Documents and Settings USERNAME Application DataIAR Embedded Workbench

Здесь USERNAME означает имя (логин пользователя), под которым Вы работаете в системе Windows. Полное имя до этой папки может зависеть от версии операционной системы Windows.

7. Создайте RAM-диск, и попробуйте компилировать проект на нем. Будьте осторожны, поскольку при пропадании питания или зависании компьютера вся Ваша работа потеряется! Как промежуточный вариант, можно на RAM-диск сохранять только объектные файлы, файлы листинга и выходные файлы, для этого в свойствах проекта General Options -> Output поменяйте пути до выходных рабочих директорий Output directories.

Самое простое средство для создания RAM диска — бесплатная программа SoftPerfect RAM Disk site:softperfect.com.

[161019]

При попытке компиляции выскакивают совершенно неожиданные ошибки — невозможно удалить файл, который либо вообще не используется в проекте, либо находится в каталоге установки IAR. Например, у меня появлялась вот такая ошибка, когда я попробовал сменить конфигурацию Release на Debug:

Building configuration: guilibprj - Debug 
Updating build tree... 
Failed to delete C:Program Files (x86)IAR SystemsEmbedded Workbench 5.4 
armincwchar.h 
 
0  file(s) deleted. 
Updating build tree... 
 
Build aborted.

Очевидно, что это полный бред — зачем очистке понадобилось вдруг удалять файл wchar.h, который относится к стандартным библиотекам, да и еще находится в каталоге установки среды разработки IAR Embedded Workbench?..

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

Решение проблемы заключается в просмотре обоих конфигураций и внесение корректных изменений в конфигурацию, где происходит эта ошибка. Особенно внимательно следует проверить дополнительные пути поиска подключаемых файлов, а также наличие предварительно определенных переключающих макросимволов (Project -> Options -> C/C++ Compiler -> Preprocessor).

Довольно часто появляющаяся ошибка в разных версиях IAR. Разработчики борются с этой ошибкой, и с переменным успехом. Обычно проблема решается, если несколько раз выполнить операцию очистки (Project -> Clean). Иногда помогает перезапуск IAR + выполнение очистки проекта.

Еще одна из причин такой ошибки — в проекте имеется 2 подключенных исходных файла, компиляция которых приводит к генерации одного и того же объектного файла. Например, есть две версии одного и того же модуля — один на языке C (с расширением *.c), и другой оптимизированный, на ассемблере (с тем же именем, но с расширением *.s). Решение проблемы очевидно — нужно исключить из процесса компиляции один из этих файлов.

Чтобы переименовать workspace, но сохранить при этом в нем те же самые имена проектов, что и были раньше, просто переименуйте файл *.eww.

Поскольку среда разработки IAR EWB не предоставляет прямого функционала для специального переименования проекта, требуется обходной путь для этого действия. Когда я переименовываю workspace и связанный с ним проект, то поступаю следующим образом:

1. Делаю копию Template.ewp (это файл проекта) и переименовываю копию, скажем, в NewProject.ewp.
2. Открываю файл workspace Template.eww.
3. Выбираю Project -> Add Existing Project…
4. Выбираю NewProject.ewp и кликаю Open.
5. Выбираю закладку «Template» в нижней части списка файлов Workspace (соответствует старому проекту).
6. Делаю правый клик на старом проекте и выбираю Remove.
7. Закрываю IAR EWB, он запросит сохранить workspace, сохраняю.
8. Переименовываю файлы старого workspace *.eww, *.ewd в NewProject.eww, NewProject.ewd (и также файл *.dep, если он у Вас есть).
9. Удаляю Template.ewp.

После этого Вы сможете открыть NewProject.eww как полностью переименованное workspace и полностью переименованный проект. Если Вы хотите только переименовать проект, и оставить старое имя для workspace, то выполните только шаги 1..7.

См. также:

Renaming in IAR Embedded Work Bench site:stackoverflow.com
IAR EW ARM: как перенести проект в другую папку
Расширения файлов IAR для процессоров ARM

[170621]

Заголовочный файл lib_AT91SAM7X256.h, в IAR 6.50 выскакивают ошибки на код с операторами __inline:

__inline void AT91F_AIC_EnableIt (
	AT91PS_AIC pAic, unsigned int irq_id )
{
    pAic->AIC_IECR = 0x1 << irq_id ;
}

Проблема в том, что для встраиваемых функций поменялся синтаксис: замените __inline на inline, и ошибка исчезнет.

На языке C, в отличие от C++, нет определения булевого типа. Поэтому либо подключите в коде C заголовочный файл stdbool.h:

Либо добавьте в общий заголовочный файл (например types.h) следующее определение:

#ifndef  __cplusplus
#define bool  unsigned char
#define true  1
#define false 0
#endif

Это глюк, связанный с файлами нулевой длины. Найдите файл, на который указывает сообщение, и удалите его.

[171204]

Неожиданный глюк, который начал происходить без видимых причин (наблюдалось на IAR 6.50.3 и Windows 7). При попытке компиляции выскакивает ошибка «General exception during build», которая сопровождается ошибкой очистки «General exception during clean». Причем в конфигурации Debug проект компилируется нормально, а в конфигурации Release происходит ошибка.

Ресурс по известным проблемам IAR [6] советует выполнить переустановку IAR в другой каталог на диске, или переименовать папку текущей инсталляции: «Install another copy of your IAR Embedded Workbench product in a different location or rename the directory of your current installation».

Мне помогло следующее — полностью удалил с диска корневую папку проекта, и восстановил её копированием из архива бекапа. После этого ошибка волшебным образом исчезла.

Замечание, сигнализирующее о возможной логической ошибке в операторе switch. Вот пример из библиотеки EFSL, генерирующий такое предупреждение компилятора (Pe1814 на строке 40):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
esint8 sd_State(hwInterface *iface)
{
   eint16 value;
 
   sd_Command(iface,13, 0, 0);
   value=sd_Resp16b(iface);
   switch(value)
   {
   case 0x000:
      return(1);
      //break;
   case 0x0001:
      DBG((TXT("Card is Locked.n")));
      break;
   case 0x0002:
      DBG((TXT("WP Erase Skip, Lock/Unlock Cmd Failed.n")));
      break;
   case 0x0004:
      DBG((TXT("General / Unknown error -- card broken?.n")));
      break;
   case 0x0008:
      DBG((TXT("Internal card controller error.n")));
      break;
   case 0x0010:
      DBG((TXT("Card internal ECC was applied, but failed to correct the data.n")));
      break;
   case 0x0020:
      DBG((TXT("Write protect violation.n")));
      break;
   case 0x0040:
      DBG((TXT("An invalid selection, sectors for erase.n")));
      break;
   case 0x0080:
      DBG((TXT("Out of Range, CSD_Overwrite.n")));
      break;
   default:
      if(value>0x00FF)
         sd_Resp8bError(iface,(euint8) (value>>8));
      else
         DBG((TXT("Unknown error: 0x%x (see SanDisk docs p5-14).n"),value)); //[Pe1814]
      break;
   }
   return(-1);
}

Это пример не очень аккуратного кодирования: оператор swith проверяет переменную value, и эта же переменная проверяется оператором if в default-блоке того же оператора swith. Очевидно, что здесь скорее всего используется не только ненужная проверка if, но и блок else этого оператора if никогда не выполнится.

В TN43262 [7] объясняется, как нужно работать с абсолютно размещаемыми переменными. Проблема с такими переменными заключается в том, что в некоторых ситуациях разработчик получает сообщение об ошибке линкера «переменная не определена». Это может быть связано с тем, что такая переменная должна быть определена специальным, не интуитивно понятным способом.

Решение состоит в том, чтобы определить и разместить переменную в заголовочном файле, который будет подключаться во все исходные файлы, ссылающиеся на эту переменную.

[Дополнительная информация]

Переменные, которые размещаютсы по абсолютному адресу, ведут себя немного не так, как обычные не автоматические переменные C/C++. Абсолютно размещамеые переменные находятся в абсолютном сегменте, таком как ABSOLUTE или xxxx_AN. Абсолютный сегмент не представлен файле линкера, поскольку переменные уже размещены во время компиляции.

Другие (обычные) не автоматические переменные, находящиеся в модуле исходного кода, размещаются в перемещаемый сегмент, который описывается в файле линкера как обычно. Поэтому разрешение адреса осуществляется во время линковки.

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

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

__no_init struct setup configuration @ 0x100;

После этого просто добавьте подключение файла setup.h во все файлы исходного кода, где должна использоваться переменная.

Один из способов запомнить — думать об этом как о наличии #define для описания размещения в памяти, с добавлением наличия способности линкера проверить его непротиворечивость.

[Другой способ абсолютного размещения переменной]

Если Вы вместо этого поместите объект в именованный сегмент:

__no_init struct setup located_configuration @ "SETUP";

то должен быть определен сегмент SETUP, и он должен быть размещен в файле линкера. Переменные, размещенные в сегменте, ведут себя как обычные переменные языка C, для них поместите следующую декларацию в файл заголовка:

// Файл setup.h
extern __no_init struct setup located_configuration;

И затем Вам нужно поместить определение в один (и только в один) исходный файл:

__no_init struct setup located_configuration @ "SETUP";

Если Вам не нравится @-синтаксис, есть его эквивалент, который можно использовать альтернативно:

Здесь описан рецепт запуска компиляции для среды разработки IAR Embedded Workbench for ARM (перевод TN47884 [8]), однако он может быть легко модифицирован для любой другой платформы.

[Запуск IarBuild.exe из командной строки]

Если у Вас есть файл проекта с именем test.ewp, в которое имеется конфигурация с именем Debug, то для сборки проекта можно использовать следующую команду:

< директория инсталляции >commonbinIarBuild.exe test.ewp Debug

Примечание: запустите IarBuild.exe без параметров для получения подсказки по опциям командной строки.

Чтобы заново собрать проект, используйте следующую команду (с опцией расширения лога, чтобы увидеть все сообщения компилятора):

< директория инсталляции >commonbinIarBuild.exe test.ewp -build Debug -log all

Пример полной очистки и повторной сборки:

< директория инсталляции >commonbinIarBuild.exe test.ewp -clean Debug -log all
< директория инсталляции >commonbinIarBuild.exe test.ewp -make Debug -log all

[Компиляция и линковка из командной строки]

Вы можете запустить все .exe файлы в каталоге < директория инсталляции >armbin из командной строки. Запустите любую утилиту из этой папки без параметров, например компилятор iccarm.exe, чтобы получить список доступных опций командной строки.

Чтобы автоматизировать процесс сборки, можно создать .bat-файл, который компилирует каждый исходный файл по отдельности. Чтобы посмотреть параметры командной строки, выберите следующую опцию в среде IAR Embedded Workbench IDE: Tools -> Options -> IDE Options -> Messages -> Show build messages: ‘All’. 

Чтобы создать .bat-файл, который компилирует один исходный файл, введите полный путь до iccarm.exe, за которым должны идти параметры (скопированные из окна View -> Messages -> Build):

< директория инсталляции >armbiniccarm.exe < компилируемый файл > < опции >

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

Для линковки может быть полезной опция -f < файл >. Пример:

< директория инсталляции >armbinilinkarm.exe -f options.xcl

Поместите все параметры линкера из окна Build в файл options.xcl (убедитесь, что каждый параметр размещен на отдельной строке). Из-за того, что командная строка линкера может быть очень длинной, рекомендуется использовать опцию –f для того, чтобы избежать любых проблем, связанных с ограничением на длину командной строки.

Чтобы прочитать больше про сборку через командную строку, см. Help -> IDE Project Management and Building Guide, раздел Building from the command line.

[180911]

На старом проекте под IAR 4.41A неожиданно столкнулся с ошибкой ассемблера Error[54] при компиляции файла Cstartup.s79. Ругань была на строчку кода, выделенную красным цветом:

#if ((MAIN_PRJ==1) || (BOOTLOADER_PRJ==1))
  B START_ADDRESS
#endif

Это был явный глюк ассемблера, связанный с тем, что ранее в тексте этого модуля уже появлялись операторы проверки прероцессора а такими же макроопределениями. Поиск по фразе Error[54]: Expression can not be forward вывел на сайт IAR с заметкой «Technical Note 31237», которая для данного случая никак не помогла.

После плясок с бубном удалось обойти проблему следующей модификацией кода, который делал то же самое, но уже не так красиво, как раньше:

#ifdef MAIN_PRJ
  B START_ADDRESS
#endif
#ifdef BOOTLOADER_PRJ
  B START_ADDRESS
#endif

[180928]

Нечаянно оставил пробел в определении макроса, и получил ошибку:

IAR Pe969 VA ARGS

Error[Pe969]: the identifier __VA_ARGS__ can only appear in the replacement lists  display.h 32
of variadic macros

Потратил много времени, пока удалось догадаться, в чем дело. После удаления пробела за msg_at ошибка исчезла.

[190601]

IAR 5.50, перестали компилироваться проекты. Выглядит так: Project -> Rebuild All, после этого долгое ожидание, и примерно через минуту сообщение об ошибке Cp001. Проблема решается следующим образом, без переустановки IAR:

1. Закройте все окна IAR.

2. Запустите IAR Licence Manager.

3. Licence -> Install…, в окошко ввода лицензии «Licence key:» вставтье длинный текст лицензии:

… длинный набор букв и цифр …# «EWARM» version «2.1_WIN», no expiration date, exclusive

4. Кликните на кнопку Install, закройте IAR Licence Manager.

[191224]

Проблема возникла при подключении файла stm32f4xx_hal_crc.h в модуль, чтобы определить экземпляр дескриптора блока контрольной суммы CRC_HandleTypeDef. Тип HAL_StatusTypeDef определен в файле stm32f4xx_hal_def.h, а ошибка возникала в заголовке stm32f4xx_hal_rcc_ex.h, который подключал stm32f4xx_hal_def.h, и как следствие ошибки Pe020 быть не должно. Но она все-таки возникала!

Долго с этим разбирался, пока каким-то чудом не нашел решение проблемы. Оказывается, вместо заголовка stm32f4xx_hal_crc.h надо подключать stm32f4xx_hal.h.

#pragma once
 
#include "types.h"
// С подключением этого заголовка возникает ошибка Pe020:
//#include "stm32f4xx_hal_crc.h"
// С подключением этого заголовка проблема решается:
#include "stm32f4xx_hal.h"
 
CRC_HandleTypeDef hcrc;

Вывод: не подключайте отдельные заголовки HAL для каждого аппаратного блока STM32, используйте вместо этого общий заголовочный файл stm32f4xx_hal.h.

[200130]

К сожалению, причину ошибки такого рода бывает найти не так просто. Общий совет: проверьте файлы, которые подключают проблемные заголовки, и проверьте опции препроцессора.

[200130]

Проблема возникла при компиляции FreeRTOS V9.0.0 в отдельную библиотеку STM32. Конфликтовали заголовочные файлы cmsis_iar.h и intrinsics.h, в них были совпадающие по именам, но разные определения макросов для асемблерных команд:

Макрос intrinsics.h(1) cmsis_iar.h(1)
__get_PRIMASK строка 61 строка 205
__get_PSP строка 55 строка 206
__set_BASEPRI строка 85 строка 210
__set_CONTROL строка 70 строка 212
__set_FAULTMASK строка 79 строка 213
__set_FPSCR строка 342 строка 214
__set_MSP строка 52 строка 215
__set_PRIMASK строка 64 строка 217
__set_PSP строка 58 строка 218
__DMB строка 770 строка 250
__DSB строка 773 строка 251
__ISB строка 776 строка 252

Примечание (1): файлы intrinsics.h и cmsis_iar.h находились в каталоге «C:Program Files (x86)IAR SystemsEmbedded Workbench 8.1armincc».

Проблема была решена путем комментирования строки #include «cmsis_iar.h» в модуле cmsis_os.c. В любом случае для решения проблемы нужно найти в проекте модули, где одновременно подключаются оба конфликтующих заголовка, и удалить подключение одного из них. Лучший кандидат на удаление — тот заголовок, который больше устарел, или который подключается реже всего. В моем случае это был заголовок cmsis_iar.h — его подключение я удалил.

[220403]

На этот раз проблема была в макросе _SYSTEM_BUILD, который был установлен в свойствах проекта на закладке управления препроцессором:

IAR Pa181 SYSTEM BUILD

После того, как _SYSTEM_BUILD удалил из списка определяемых символов, предупреждение Pa181 исчезло.

Вероятно, что при использовании проекта со смесью кода C и C++ [10, 11] в одном из заголовочных файлов пропущено обрамление из extern «C» { и }:

#ifndef __MYHEADER__
#define __MYHEADER__
 
#ifdef __cplusplus
 extern "C" {
#endif
 
// тут код заголовка:
...
 
#ifdef __cplusplus
}
#endif
 
#endif /* __MYHEADER__ */

См. также Q032.

Причина этой ошибки может быть банальна — просто в проект не добавлен модуль, в котором определен недостающий символ. Но может быть, что символ все-таки определен в подключаемой библиотеке, но эта библиотека скомпилирована как код другого типа (например, находится в библиотеке C++, когда использующий символ код написан на C). Тогда проблему Li005 можно решить путем использования стандартного обрамления кода в заголовке из extern «C» { и }, см. выше Q031, а также [10, 11].

[200303]

При попытке скомпилировать проект IAR выполение сборки останавливалось на первом модуле, с выводом сообщения «Updating build tree…», и дальше компиляция не шла. Симптомы были одинаковые, как в графической среде, так и при компиляции из командной строки (commonbinIarBuild.exe test.ewp -build Release).

Проблема оказалась в неправильном выборе версии IAR — в IAR 5.50 наблюдалась ошибка с остановкой компиляции «Updating build tree…», а в версии IAR 6.50 компиляция проходила нормально.

[220409]

Эту ошибку компилятор IAR может выдавать на встраиваемую (inline) функцию в следующих случах:

1. Нет предварительной декларации этой функции. Например в модуль, где определена функция, не подключен заголовок, где функция декларируется.
2. В декларации inline-функции опущено ключевое слово extern.

Пример:

inline void Beep (uint16_t ms)
{
   // На следующую строку будет ошибка Pe1031:
   // "Error[Pe1031]: an entity with internal linkage cannot be
   //  referenced within an inline function with external linkage"
   beeeptime = ms;
}

Как решить проблему 1 понятно: нужно подключить в модуль заголовочный файл с декларацией inline-функции. Проблема 2 тоже легко решается, надо просто в декларации добавить ключевое extern. Однако мне показалось странным, что не встраиваемая функция не требует extern, а встраиваемая требует.

Ниже пример решения проблемы. Заголовок beeper.h:

#pragma once
#include < stdint.h>
#include < stdbool.h>
 
extern inline void Beep (uint16_t ms);

Модуль beeper.c:

#include "pins.h"
#include "beeper.h"
 
static uint16_t beeeptime = 0;
 
#define BEEPon(on) HAL_GPIO_WritePin(BEEPER_PORT,
                                     BEEPER_PIN, 
                                     on?GPIO_PIN_SET:GPIO_PIN_RESET)
 
inline void Beep (uint16_t ms)
{
   beeeptime = ms;
}

[230119]

В сложных проектах, где много директив препроцессора условной компиляции (#if, #ifdef, #elif, #else), иногда бывает трудно понять, какой код компилируется, а какой нет. Однако разобраться довольно просто: достаточно вставить директиву #error ЛЮБОЙТЕКСТ, тогда если код в этом месте компилируется, то комилятор выведет сообщение об ошибке.

[Ссылки]

1. Что такое lvalue и rvalue?
2. IAR EW ARM: применение #ifndef и #define для разрешения конфликтов включаемых файлов (#include).
3. IAR EWB ARM: форматированный вывод printf библиотеки DLIB.
4. IAR EW ARM: применение #ifndef и #define для разрешения конфликтов включаемых файлов (#include).
5. IAR: создание библиотеки.
6. IAR Embedded Workbench IDE — Known problems site:supp.iar.com.
7. Technical Note 43262 Absolute located variable site:iar.com.
8. Technical Note 47884 Build from the command line site:iar.com.
9. Какие я часто делаю ошибки в языке C.
10. Как использовать совместно код C и C++: FAQ.
11. IAR: совместное использование кода C и кода C++.

Добавить комментарий

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account


Closed

DaveBian opened this issue

Oct 29, 2015

· 5 comments


Closed

Build with IAR failed

#6

DaveBian opened this issue

Oct 29, 2015

· 5 comments

Comments

@DaveBian

Hi,

When I built etl iar project, it failed and give message list below:
IAR version: IAR Embedded Workbench for ARM, 7.40.2.8570
How to fix this problem? Thanks a lot.

Building configuration: etl — Debug
Updating build tree…
test_compile.cpp
Error[Pe065]: expected a «;» C:1.Projets3.RefCodesetlalgorithm.h 296
Error[Pe020]: identifier «n» is undefined C:1.Projets3.RefCodesetlalgorithm.h 298
Error[Pe065]: expected a «;» C:1.Projets3.RefCodesetlalgorithm.h 323
Error[Pe020]: identifier «n» is undefined C:1.Projets3.RefCodesetlalgorithm.h 325
Error[Pe065]: expected a «;» C:1.Projets3.RefCodesetlalgorithm.h 354
Error[Pe020]: identifier «n» is undefined C:1.Projets3.RefCodesetlalgorithm.h 356
Error[Pe065]: expected a «;» C:1.Projets3.RefCodesetlalgorithm.h 381
Error[Pe020]: identifier «n» is undefined C:1.Projets3.RefCodesetlalgorithm.h 383
Warning[Pe940]: missing return statement at end of non-void function «etl::io_port_rw<T, ADDRESS>::iterator::operator=» C:1.Projets3.RefCodesetlio_port.h 76
Error[Pe519]: class «etl::crc8_ccitt» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 188
Error[Pe519]: class «etl::crc8_ccitt» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 189
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 189
Error[Pe519]: class «etl::crc16» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 191
Error[Pe519]: class «etl::crc16» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 192
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 192
Error[Pe519]: class «etl::crc16_ccitt» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 194
Error[Pe519]: class «etl::crc16_ccitt» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 195
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 195
Error[Pe519]: class «etl::crc16_kermit» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 197
Error[Pe519]: class «etl::crc16_kermit» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 198
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 198
Error[Pe519]: class «etl::crc32» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 200
Error[Pe519]: class «etl::crc32» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 201
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 201
Error[Pe519]: class «etl::crc64_ecma» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 203
Error[Pe519]: class «etl::crc64_ecma» may not have a template argument list C:1.Projets3.RefCodesetltesttest_compile.cpp 204
Error[Pe276]: name followed by «::» must be a class or namespace name C:1.Projets3.RefCodesetltesttest_compile.cpp 204
Error while running C/C++ Compiler

Total number of errors: 26
Total number of warnings: 1

@DaveBian

Could some tell me how fix this issue? Thanks in advance.

@jwellbelove

IAR seems to be having a problem with std::iterator_traits::difference_type
Are you able to confirm whether this type is supported by IAR? Maybe you could try substituting ‘int32_t’ or ‘long’ for the type.

I don’t have access to my PC at the moment as I’m in Australia staying at campsites with almost completely useless WIFI. ‘ve only been able to access email twice in two weeks. I shall be back in the UK on Nov 27th and I’ll take a closer look when I’ve got over the jet lag!

One of the jobs I have to finish is to update the test files for the embedded compiler projects as they do not cover any near as much as the unit tests do. There are bound to be a few more cross platform issues due to each compiler interpreting the standard in slightly different ways. Testing for the Green Hills compiler is virtually impossible for me as they will not supply anything other than a 30 day trial. At least Keil and IAR allow ‘mini’ projects without time limit.

The unit tests only run under Linux with GCC and Windows with GCC and Visual Studio.

@DaveBian

John,

Yes, maybe you are right. After the code roll back for former version,
substituting ‘size_t ‘ for type ‘std::iterator_traits::difference_type’ it
works.

Best regards!
David Bian


Business Email: David.Bian@uster.com
David.Bian@uster.comPrivate Email: idavidbian@gmail.com
idavidbian@gmail.com
Skype: idavidbian
P Kindly please consider the environment before printing this email!


2015-11-12 15:36 GMT+08:00 John Wellbelove notifications@github.com:

IAR seems to be having a problem with std::iterator_traits::difference_type
Are you able to confirm whether this type is supported by IAR? Maybe you
could try substituting ‘int32_t’ or ‘long’ for the type.

I don’t have access to my PC at the moment as I’m in Australia staying at
campsites with almost completely useless WIFI. ‘ve only been able to access
email twice in two weeks. I shall be back in the UK on Nov 27th and I’ll
take a closer look when I’ve got over the jet lag!

One of the jobs I have to finish is to update the test files for the
embedded compiler projects as they do not cover any near as much as the
unit tests do. There are bound to be a few more cross platform issues due
to each compiler interpreting the standard in slightly different ways.
Testing for the Green Hills compiler is virtually impossible for me as they
will not supply anything other than a 30 day trial. At least Keil and IAR
allow ‘mini’ projects without time limit.

The unit tests only run under Linux with GCC and Windows with GCC and
Visual Studio.


Reply to this email directly or view it on GitHub
#6 (comment).

@jwellbelove

It looks like all of the ‘is_permutation’ overloads will be a problem for IAR. It would probably be wise to change the difference types to another standard signed type like int32_t. I don’t see many embedded projects being required to check containers in excess of 2GB. It’s possible that there may be some other parts of the library use ‘difference_type’ from ‘interator_traits’. I shall have some free time in December to put some effort in to getting the embedded tests up to date and completing work on etl versions of unordered_map & set. Once these are done I plan to add some cache containers based on unordered_map.

@jwellbelove

I have just issued a new release 6.0 that should significantly reduce code size when using many of the containers.

2 participants

@jwellbelove

@DaveBian

Форум РадиоКот • Просмотр темы — Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

Сообщения без ответов | Активные темы

ПРЯМО СЕЙЧАС:

Автор Сообщение

Не в сети

Заголовок сообщения: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 19:42:41 

Прорезались зубы

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Почему этот код вызывает ошибку в Keil 5 (на C++)?

Портирую код с AVR, затык на ровном месте:

Код:

unsigned char portlcd = 0; //ячейка для хранения данных порта микросхемы расширения
const unsigned char rr = 0b01001110;
I2C_SendByteByADDR(portlcd|=0x04,0b01001110);

строки 2 и 3 вызывают ошибки:

userlcdtwi.cpp(5): error: #65: expected a «;»

userlcdtwi.cpp(73): error: #18: expected a «)»

Что не так?!

Вернуться наверх
 

ПрофильПрофиль

 

Реклама

Аlex

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 19:56:30 

Модератор
Аватар пользователя

Карма: 85

Рейтинг сообщений: 1270

Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4478
Откуда: Планета Земля

Рейтинг сообщения: 0

Медали: 1

Получил миской по аватаре (1)

Тяжело сказать, не видя остального кода.
В каком месте вызываете функцию I2C_SendByteByADDR ? Не там ли, где коду обитать недопустимо ?

Вернуться наверх
Реклама

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:01:44 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Вернуться наверх

ARV

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:08:17 

Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97

Рейтинг сообщений: 2032

Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 17886
Откуда: Новочеркасск

Рейтинг сообщения: 7

Медали: 2

Получил миской по аватаре (1)

Мявтор 3-й степени (1)

на сколько я знаю, префикс 0b (для двоичных констант) не является стандартным для Си


_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется…

скушно, бабоньки!

Вернуться наверх
Реклама

Выгодные LED-драйверы для решения любых задач

КОМПЭЛ представляет со склада и под заказ широкий выбор LED-драйверов производства MEAN WELL, MOSO, Snappy, Inventronics, EagleRise. Линейки LED-драйверов этих компаний, выполненные по технологии Tunable White и имеющие возможность непосредственного встраивания в систему умного дома (димминг по шине KNX), перекрывают практически полный спектр применений: от простых световых указателей и декоративной подсветки до диммируемых по различным протоколам светильников внутреннего и наружного освещения.

Подобрать LED-драйвер>>

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:21:13 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Как заставить Keil его понимать?

Вернуться наверх
Реклама

Реклама

LIMF – источники питания High-End от MORNSUN со стандартным функционалом на DIN-рейку

На склад Компэл поступили ИП MORNSUN (крепление на DIN-рейку) с выходной мощностью 240 и 480 Вт. Данные источники питания обладают 150% перегрузочной способностью, активной схемой коррекции коэффициента мощности (ККМ; PFC), наличием сухого контакта реле для контроля работоспособности (DC OK) и возможностью подстройки выходного напряжения. Источники питания выполнены в металлическом корпусе, ПП с компонентами покрыта лаком с двух сторон, что делает ее устойчивой к соляному туману и пыли. Изделия соответствуют требованиям ANSI/ISA 71.04-2013 G3 на устойчивость к коррозии, а также нормам ATEX для взрывоопасных зон.

Подробнее>>

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:27:37 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

Двоичные константы появились в С++14. Умеет keil C++14?

ЗЫ: гугл говорит, что умеет. Включи его поддержку.

Последний раз редактировалось VladislavS Сб ноя 24, 2018 20:31:50, всего редактировалось 1 раз.

Вернуться наверх

Reflector

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:31:11 

Поставщик валерьянки для Кота

Карма: 20

Рейтинг сообщений: 251

Зарегистрирован: Вс июн 19, 2016 09:32:03
Сообщений: 1950

Рейтинг сообщения: 0

Вернуться наверх

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:32:41 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:37:49 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

В настройках проекта вестимо. Там вкладок то с гулькин нос. Вангую она С/С++ называется.

Вернуться наверх

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:42:35 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Ну и где?
Изображение

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:50:21 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

DENIS451, ты издеваешься? Вкладку Target открой и выбери компилятор 6-й версии.

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:55:25 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

Вернуться наверх

Мурик

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 20:56:56 

Друг Кота
Аватар пользователя

Карма: 1

Рейтинг сообщений: 157

Зарегистрирован: Пн окт 11, 2010 19:00:08
Сообщений: 3313

Рейтинг сообщения: 0

VladislavS писал(а):

Двоичные константы появились в С++14.

В GCC даже в Си они поддерживаются.

Вернуться наверх

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 21:00:49 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Спасибо, сделал как на картинках, вроде заработало.

Но теперь появляются какие то подозрительные крестики в редакторе кода — см. 4.png

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 21:07:51 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

VladislavS писал(а):

Двоичные константы появились в С++14.

В GCC даже в Си они поддерживаются.

Это конечно замечательно, но потом появляется такой DENIS451, жертва нестандартных расширений GCC — Аааа! Всё пропало!!!

Вернуться наверх

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 21:17:53 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

С крестиками я уже сам разобрался, похоже Keil не мог найти файл исходников в директории «user» сам, а вот компилятор почему то смог.

Вернуться наверх

ARV

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 21:18:54 

Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97

Рейтинг сообщений: 2032

Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 17886
Откуда: Новочеркасск

Рейтинг сообщения: 0

Медали: 2

Получил миской по аватаре (1)

Мявтор 3-й степени (1)

Как заставить Keil его понимать?

отказаться от двоичных констант, использовать те, которые обязаны понимать ВСЕ компиляторы Си: десятичные, восьмеричные или шестнадцатеричные


_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется…

скушно, бабоньки!

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 21:26:45 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

Либо использовать С++ компилятор даже для С кода. Тогда, например, можно разряды отделять вот так 0b0000’1111’0000’1111 или 10’000.

Вернуться наверх

DENIS451

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 22:21:04 

Карма: -3

Рейтинг сообщений: -3

Зарегистрирован: Вт сен 09, 2008 18:17:27
Сообщений: 213

Рейтинг сообщения: 0

Рано радовался, после переключения на компилятор v6 проект собирается без ошибок, только в контроллере он
перестаёт работать!

Вернуться наверх

VladislavS

Не в сети

Заголовок сообщения: Re: Почему этот код с AVR вызывает ошибку в Keil 5 (на C++)?

СообщениеДобавлено: Сб ноя 24, 2018 22:37:45 

Поставщик валерьянки для Кота
Аватар пользователя

Карма: 13

Рейтинг сообщений: 362

Зарегистрирован: Вт май 01, 2018 19:44:47
Сообщений: 2300

Рейтинг сообщения: 0

Проц на 72 МГц включил и FLASH_Latency_2 не поставил?

PS: Или опять BOOT0 не туда перемкнут ? :)

Вернуться наверх

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

pkm

1

01.02.2012, 18:48. Показов 7218. Ответов 2


При копировании функции _delay_loop из некого рабочего проекта, и компилировании её в IAR. вылетает куча ошибок

Код

__asm void _delay_loop(uint32_t __count)
{
loop   SUBS     r0,r0,#1
BNE      loop
BX    lr
}

Ошибки:

Код

Error[Pe130]: expected a "{" D:ДокументыIAR ProjectDTH-11 ARMdelay.h 11
Error[Pe040]: expected an identifier D:ДокументыIAR ProjectDTH-11 ARMdelay.h 36
Error[Pe260]: explicit type is missing ("int" assumed) D:ДокументыIAR ProjectDTH-11 ARMdelay.h 36
Error[Pe020]: identifier "loop" is undefined D:ДокументыIAR ProjectDTH-11 ARMdelay.h 38
Error[Pe065]: expected a ";" D:ДокументыIAR ProjectDTH-11 ARMdelay.h 38
Error[Pe010]: "#" not expected here D:ДокументыIAR ProjectDTH-11 ARMdelay.h 38
Error while running C/C++ Compyter

Если привести код как написано в документации к IAR:

Код

void _delay_loop(uint32_t __count)
{
asm("loop: n");
asm("SUBS r0,r0,#1 n");
asm("BNE loop n");
asm("BX lr");
}

Ругается так:

Error[Og010]: Inline assembler instruction does not have a unique size: «BNE loop «

Как быть? может что настроить нужно в IDE?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

1 / 1 / 0

Регистрация: 22.09.2010

Сообщений: 393

01.02.2012, 22:12

2

А если метку на место поставить ?

Код

asm("loop: SUBS r0,r0,#1 n");

PS к данной ошибке отношение не имеет , но много кто не любит кириллицу в путях…



0



pkm

02.02.2012, 00:37

3

чтобы избавиться от данной ошибки нужно:
asm(«BNE loop n»);

заменить на

asm(«BNE.N loop n»);

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    >
    Разбираемся с IAR
    , Обсуждаем небольшие коды на IAR.

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #181

    ,
    26.03.04, 08:51

      Senior Member

      ****

      Рейтинг (т): 26

      Цитата

      unsigned char Keys = (~PORTB) & (4|8); /* состояние кнопок на RB2-RB3. Ждёт нажатия */

      определять такие ошибки пора бы уже и саму научиться:)


      bizar



      Сообщ.
      #182

      ,
      26.03.04, 09:12

        potor, в тех местах так ошибки и остались

        ExpandedWrap disabled

          Rebuilding target Debug…

          Untitled1.c

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (21) : Error[Pe268]: declaration may not appear after executable statement in block

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (43) : Error[Pe268]: declaration may not appear after executable statement in block

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (45) : Error[Pe112]: expected «while»

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (46) : Warning[Pe223]: function declared implicitly

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (49) : Error[Pe079]: expected a type specifier

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (50) : Error[Pe065]: expected a «;»

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (51) : Warning[Pe128]: loop is not reachable from preceding code

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (54) : Error[Pe079]: expected a type specifier

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (55) : Error[Pe065]: expected a «;»

          C:Documents and SettingsAdministratorMy DocumentsIAR проектНовая папкаUntitled1.c (57) : Warning[Pe001]: last line of file ends without a newline

          Total number of errors: 7

          Total number of warnings: 3


        trainer



        Сообщ.
        #183

        ,
        26.03.04, 09:20

          Цитата

          bizar, 26.03.04, 11:38
          do
          {
          tick(); /* НЕБОЛЬШОЙ ПРОМЕЖУТОК ВРЕМЕНИ, «не будем опрашивать кнопки слишком часто» */
          Keys = (~PORTB) & (4|8); /* состояние кнопок на RB2-RB3. Ждёт нажатия */
          }
          Keys >>= 1;
          while(PORTB & Bit(0)); /* если установлен бит 0, значит нажата кнопка на RB2 */

          Для do нет соответствующего while. Или Keys >>= 1; стоит не там, где нужно


          potor



          Сообщ.
          #184

          ,
          26.03.04, 09:21

            Senior Member

            ****

            Рейтинг (т): 26

            ПОПРОБУЙ ТАК:

            Цитата

            void TransmitByte(char Symbol)
            {
            unsigned int count = 8;// счетчик передаваемых бит данных
            PORTA &= 0xfe; //передаем стартовый бит
            do
            {
            TransmitBitDelay(); // задержка перед передачей следующего бита
            PORTA ^= (~Symbol) & 1; // выдаем очередной бит в COM
            Symbol >>= 1; //следующий бит
            count—;
            } while (count >0);
            TransmitBitDelay(); // задержка перед передачей следующего бита
            PORTA |= 1; //передаем стоповый бит
            }

            Цитата

            unsignet char Keys;
            main ()
            {
            TRISB = 4|8; /* RB2 — RB3 настраиваем на вход */
            PORTB = 0xfc; /* RB0 — RB1 настраиваем на вывод*/
            while(1)
            {
            do
            {
            tick(); /* НЕБОЛЬШОЙ ПРОМЕЖУТОК ВРЕМЕНИ, «не будем опрашивать кнопки слишком часто» */
            Keys = (~PORTB) & (4|8); /* состояние кнопок на RB2-RB3. Ждёт нажатия */
            }
            Keys >>= 1;
            while(PORTB & Bit(0)); /* если установлен бит 0, значит нажата кнопка на RB2 */
            while(1)
            {
            void TransmitByte(34) /* посылаем 34 */
            }
            while(PORTB & Bit(1)); /* если установлен бит 1, значит нажата кнопка на RB3 */
            while(1)
            {
            void TransmitByte(35) /* посылаем 35 */
            }
            }
            }


            bizar



            Сообщ.
            #185

            ,
            27.03.04, 05:59

              Думаю нужно начать всё сначало?

              Прикреплённый файлПрикреплённый файл__________.rar (26.83 Кбайт, скачиваний: 403)


              potor



              Сообщ.
              #186

              ,
              27.03.04, 20:38

                Senior Member

                ****

                Рейтинг (т): 26

                в общем в моем IARe для AVR надо в режиме дебаггера сделать View/Disassembly, либо в Project/Options в закладке компилятора list ставишь галочку Assembler mnemonics, т е ты выслал не то, нужен ассемблерный код


                bizar



                Сообщ.
                #187

                ,
                28.03.04, 04:01

                  potor, я этим покозал что ошибок море,
                  и не знаю как их исправить (уже всё перепробовал).


                  potor



                  Сообщ.
                  #188

                  ,
                  28.03.04, 15:59

                    Senior Member

                    ****

                    Рейтинг (т): 26

                    бл…
                    unsigned char Keys
                    :)

                    Добавлено в 28.03.04, 16:01:
                    точку с запятой незабудь поставить:)


                    potor



                    Сообщ.
                    #189

                    ,
                    28.03.04, 17:01

                      Senior Member

                      ****

                      Рейтинг (т): 26

                      на будующее, в микроконтроллерных компиляторах, ввиду их недоделанности, следует обращать внимание на первую ошибку, остальные генерятся как правило от балды:)


                      bizar



                      Сообщ.
                      #190

                      ,
                      30.03.04, 08:12

                        Ещё остались ошибки.

                        Прикреплённый файлПрикреплённый файл__________.rar (21.64 Кбайт, скачиваний: 415)


                        potor



                        Сообщ.
                        #191

                        ,
                        30.03.04, 08:30

                          Senior Member

                          ****

                          Рейтинг (т): 26

                          ExpandedWrap disabled

                            main () {

                               TRISB = 4|8;  /* RB2 — RB3 настраиваем на вход */

                               PORTB = 0xfc; /* RB0 — RB1 настраиваем на вывод*/

                               while(1) {

                                  do {

                                     tick(); /* НЕБОЛЬШОЙ ПРОМЕЖУТОК ВРЕМЕНИ, «не будем опрашивать кнопки слишком часто» */

                                     Keys = (~PORTB) & (4|8); /* состояние кнопок на RB2-RB3. Ждёт нажатия */

                                  } while( Keys == 0 );

                                  if(Keys & Bit(2))   /* если установлен бит 0, значит нажата кнопка на RB2 */

                                     TransmitByte(34); /* посылаем 34 */

                                  if(Keys & Bit(3))   /* если установлен бит 1, значит нажата кнопка на RB3 */

                                     TransmitByte(35); /* посылаем 35 */

                               }

                            }

                          этот код тебе писал ранее trainer:)


                          bizar



                          Сообщ.
                          #192

                          ,
                          30.03.04, 11:12

                            В нём ошибка:

                            ExpandedWrap disabled

                              if(Keys & Bit(2))

                            Сдесь выдаёт ошибку.


                            potor



                            Сообщ.
                            #193

                            ,
                            30.03.04, 11:19

                              Senior Member

                              ****

                              Рейтинг (т): 26

                              после #include <io16f84.h>
                              вставь строчку
                              #define Bit(x) 1<<(x)
                              дело в том что команды Bit нет, это макрос который мы определяем сами


                              bizar



                              Сообщ.
                              #194

                              ,
                              31.03.04, 05:25

                                Ok всё скомпелил без ошибок
                                теперь зашить и проверить.


                                potor



                                Сообщ.
                                #195

                                ,
                                01.04.04, 04:44

                                  Senior Member

                                  ****

                                  Рейтинг (т): 26

                                  неееет, зашить и проверить неполучится, сначала надо подобрать числа, т е десятки там не пройдут:)

                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                                  0 пользователей:

                                  • Предыдущая тема
                                  • Микроконтроллеры
                                  • Следующая тема

                                  Рейтинг@Mail.ru

                                  [ Script execution time: 0,0464 ]   [ 15 queries used ]   [ Generated: 9.02.23, 14:59 GMT ]  

                                  Error pe040 expected an identifier

                                  На этой страничке решил собрать ошибки, возникающие при компиляции, линковке, отладке в IDE IAR Embedded Workbench for ARM, и методы их устранения.

                                  Ошибка произошла из-за того, что я вынес в отдельный файл pins.c определения составных переменных:

                                  Ошибка [Pe070] возникала потому, что макрос PIO_LISTSIZE не мог вычислить sizeof(list). Решение: в pins.h указать размер массива. Связано с неудобствами — нужно следить за синхронизировать pins.c и pins.h. Устранение ошибки:

                                  //[Файл pins.h]
                                  extern const Pin pinsCol [ 4 ] ;

                                  На языке C одиночный оператор может состоять из нескольких строк текста. Принято, что не последняя строка такого оператора должна завершаться обратным слешем ().

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

                                  Error[Pe008]: missing closing quote C:папкамодуль.c 19
                                  Error[Pe007]: unrecognized token C:папкамодуль.c 23
                                  Error[Pe065]: expected a «;» C:папкамодуль.c 23

                                  Пример оператора с ошибкой и без ошибки:

                                  Пропущенный слеш нужно искать в строке перед второй ошибкой.

                                  [Случай 1]

                                  Долго не мог разобраться, почему возникала ошибка Error[Pe147]: declaration is incompatible with «TParams const __data папка_проектаvars.c 22 paramDefault» (declared at line 22). У меня была задана структура TParams как тип:

                                  Грешил даже на то, что структура назначалась как переменной, так и константе:

                                  Оказалось все проще (хотя сразу не разобрался потому, что компилятор не указывал на это место) — я просто забыл ключевое слово const в хедере, где предварительно объявлялись param и paramDefault. Было там так (это ошибочно):

                                  А для исправления ошибки должно быть так:

                                  [Случай 2]

                                  При портировании проекта BIGTREETECH TFT35 V3.0 из среды Visual Studio Code (VSC, VSCode) на IAR столкнулся с ошибкой несовместимости определений в iccarm_builtin.h и core_cm3.h:

                                  1. Удалить файл core_cm3.h, либо переименовать его вcore_cm3.h.old.
                                  2. Зайти в свойства проекта, в разделе General Optoins -> закладка Library Configuration поставить галочку «Use CMSIS».

                                  Иногда после продолжительных правок трудно найти место, где пропустили точку с запятой. Например, компилятор неожиданно выдает ошибки на синтаксис в файле kbmatrix.h, который Вы даже не исправляли:

                                  Remark[Pe082]: storage class is not first C:asmtestprojectincludekbmatrix.h 25
                                  Error[Pe065]: expected a «;» C:asmtestprojectincludekbmatrix.h 25
                                  Error[Pe757]: variable «KeyEventCallback» is not a type name C:asmtestprojectincludekbmatrix.h 54
                                  Error[Pe757]: variable «KeyEventCallback» is not a type name C:asmtestprojectincludekbmatrix.h 67
                                  Error while running C/C++ Compiler

                                  Для того, чтобы найти действительное место ошибки, нужно найти все включения файла kbmatrix.h — перед ним наверняка будут другие включаемые заголовки, в которых допущена ошибка. Запускаем общий поиск по всему проекту, для чего жмем Ctrl+F и в строке поиска указываем kbmatrix.h. Переключатель «Look in» должен стоять на «Project files and all include files».

                                  После поиска получим список файлов, которые включают директивой #include файл kbmatrix.h:

                                  C:asmtestprojectkbmatrix.c 4 #include «kbmatrix.h»
                                  C:asmtestprojectincludepins.h 3 #include «kbmatrix.h»
                                  C:asmtestprojectpins.c 6 #include «kbmatrix.h»
                                  ———-
                                  Found 3 instances. Searched in 270 files.

                                  В одном из этих найденных файлов (kbmatrix.c, pins.h, pins.c), перед #include «kbmatrix.h» включаются другие файлы, в которых допущена ошибка. Теперь место пропущенной точки с запятой найти легко. В моем примере ошибка была в исправленном файле mytypes.h. Вот содержимое файла pins.h (он был в списке найденных), где добавлялся заголовок mytypes.h с ошибкой:

                                  #include «settings.h»
                                  #include «mytypes.h»
                                  #include «kbmatrix.h»
                                  ..

                                  Просмотрев список включаемых файлов, перед #include «kbmatrix.h», я увидел файл, который исправлял — mytypes.h, в нем как раз и была ошибка (пропущена точка с запятой после определения типа структуры).

                                  [Причина 1]

                                  Возможно, что пропущено словечко void в параметрах при определении функции. Пример:

                                  Исправить нужно так:

                                  Пример лога ошибок:

                                  Определение FILE находится в заголовочном файле stdlib.h, поэтому нужно подключить его директивой #include. Однако иногда этого недостаточно, потому что поддержка FILE присутствует только в варианте выбора библиотек Full, но может быть выбран другой вариант — None или Normal с целью экономии памяти встраиваемых систем. Чтобы использовать FILE, необходимо переключиться на полный вариант стандартных библиотек это делается опцией командной строки компилятора —dlib full. Либо можно это настроить в диалоге свойств проекта (Options. ) -> General Options -> Library Configuration -> Library: поставьте Full:

                                  Имейте в виду, что полный вариант стандартных библиотек (Full) приведет к намного большему объему кода. Поэтому если Вы используете FILE только для печати диагностических сообщений в stderr, то лучше использовать какой-нибудь другой способ вывода сообщений.

                                  [Причина 2]

                                  Если в свойствах проекта, раздел C/C++ Compiler -> C dialect стоит галочка «Require prototypes», то для не переопределенных weak-функций это будет гарантированно вызвать ошибку.

                                  Снимите эту галочку, и ошибка Pa045 пропадет.

                                  Проблема в том, что в блоке памяти [0x00100000-0x001002db] находится код, до которого не могут достать ассемблерные команды короткого перехода, находящиеся в ассемблерном коде (обычно в других модулях). В этом случае нужно править ассемблерный код, чтобы переходы были длинными, либо переписать код с ассемблера на C (тогда компилятор сам подставит нужные команды). Другое решение указать компилятору генерировать код для режима процессора не thumb, а arm (Свойства проекта (Options. ) -> General Options -> C/C++ Compiler -> Processor mode -> Arm).

                                  Чтобы сгенерировать карту памяти и статистику линковки (это поможет найти проблему), откройте свойства проекта (Options. ) -> General Options -> Linker -> List -> Поставьте галочки на «Generate linker map file» и на «Generate log file», а также все галочки ниже на опциях лог-файла. Лог-файл см. в файле имя_конфигурацииListимя_проекта.log, а карту распределения памяти в файле имя_конфигурацииListимя_проекта.map.

                                  Предупреждение возникало при попытке вызвать из кода на C функцию abs, пример:

                                  Дело в том, что на простом C (не C++) нельзя распознать прототип функции abs по типу переменной. Только для C++ можно автоматически подставить нужный прототип abs (для разных типов аргументов на C++ имеются разные реализации abs). В данном случае в параметре была переменная типа float, а определение abs подразумевало в параметре целый тип. На самом деле на C нужно напрямую вызывать abs с нужным функционалом по отдельному имени, здесь подойдет fabsf:

                                  Пример кода, который генерирует предупреждение Pa091:

                                  Причина ошибки в том, что оператор инверсии

                                  делает приведение типа unsigned char к типу signed int перед инверсией. Для того, чтобы пропало предупреждение, нужно перед инверсией дополнительно вставить ключевое слово unsigned:

                                  Такая ошибка возникает при логических операциях с константами из перечисления (которые определены через enum). Вот пример кода, который генерирует предупреждение Pe188:

                                  Причина предупреждения в том, что результатом логической операции будет целочисленный тип, а не тип enum. Исправить можно, если явно указать, что результат операции будет иметь тип перечисления:

                                  Когда 2 заголовочных файла ссылаются друг на друга директивой #include, то могут возникнуть ошибки Error[Pe020]: identifier «имя_идентификатора» имя_файла.h номер строки is undefined (упомянутый идентификатор не найден). К примеру, в заголовочный файл headerA.h подключен файл headerB.h, и также к файлу headerB.h подключен файл headerA.h — тогда блок защиты от повторного включения заголовка [2] не даст видимости всех нужных имен, определенных в первом подключенном заголовке.

                                  Для того, чтобы исправить эту ситуацию, требуется создать третий заголовок headerC.h, который будет содержать общие для headerA.h и headerB.h определения, и подключить headerC.h в headerA.h и headerB.h, чтобы они не ссылались друг на друга.

                                  Постоянно достают предупреждения компилятора IAR о неправильной строке форматирования (printf, sprintf, sscanf): «IAR EWB ARM: Remark[Pe181]: argument is incompatible with corresponding format string conversion».

                                  Избавиться от таких предупреждений поможет правильный выбор опции форматирования вывода printf. Для подробной информации см. [3].

                                  • Функция printf, аргумент u8 (unsigned char), строка формата %u -> надо поменять формат на %i.
                                  • Функция printf, аргумент u16 (unsigned short), строка формата %u -> надо поменять формат на %i.
                                  • Функция sscanf, аргумент u8 (unsigned char), строка формата %u или %i -> надо поменять формат на %hu, а тип аргумента на u16 (unsigned short).

                                  Ошибка может возникнуть, если неправильно определена переменная структуры, например:

                                  Исправить предупреждение Pe1000 можно, если правильно указать экземпляр переменной структуры:

                                  [140110]

                                  Вопрос: мне нужно кастомизировать вывод на собственное устройство отображения (LCD). Все сделал, как написано в документации IAR — определил внешнюю функцию MyLowLevelPutchar, раскомментировал функцию __write, но почему-то при вызовах printf и putchar вывод на LCD не происходит. Функция __write не вызывается, и код, который я написал в теле функции MyLowLevelPutchar, не работает. В чем проблема?

                                  Ответ: Вы все сделали правильно, но кроме этого в некоторых версиях IAR (например 4.20) необходимо особым образом выбрать конфигурацию библиотек DLIB. Это делается через свойства проекта General Options -> Library Configuration -> Library. Попробуйте из выпадающего списка выбрать вариант Normal, и если не заработает, то попробуйте выбрать Full. У меня иерархия вызовов в IAR версии 4.20 работала почему-то следующим образом: если выбрать Full, то последовательность вызова получается printf -> .. -> putchar -> fputc, и в этом варианте ничего не работало (код в MyLowLevelPutchar не вызывается). Если выбрать Normal, то тогда цепочка вызовов printf -> .. -> putchar -> __write, и в этом случае перенаправление вывода работает (потому что в функция __write вызывает пользовательский код из MyLowLevelPutchar).

                                  [140312]

                                  Такая ошибка возникает, когда Вы перенесли проект в другую папку, но перед запуском отладки не сделали очистку и не перекомпилировали проект. В отладочных файлах запомнились старые абсолютные пути до фалов исходного кода, которые теперь не соответствуют реальным. Чтобы исправить ошибку, выберите пункт меню Project -> Clean, после чего запустите отладку. Проект скомпилируется заново, и теперь отладка запустится без ошибки.

                                  [140515]

                                  Для больших проектов время компиляции может составлять большую проблему. Есть несколько советов, как можно уменьшить время компиляции.

                                  1. Убедитесь, что в каждом заголовочном файле у Вас есть защитные заголовки, например:

                                  Подробнее про защитные заголовки см. [4]. Кроме того, проверьте файлы исходного кода на лишние подключения заголовков директивой #include. Этот фактор значительно влияет на скорость компиляции.

                                  2. Создайте предварительно скомпилированные библиотеки, куда поместите редко изменяемые модули: BSP (Board Support Package, пакет поддержки платы разработчика), стеки протоколов и т. д. Это нужно делать периодически для кода, который остается неизменным, и который не нужно перекомпилировать каждый раз, когда что-то меняется в коде приложения. Подробнее см. [5].

                                  3. Запретите генерацию файлов листинга компилятора (Options -> C/C++ Compiler -> List).

                                  4. Если некоторые файлы находятся на сетевом диске (даже если это RAM-диск на сервере), попробуйте сделать их локальными, т. е. скопировать на жесткий диск рабочей станции, и компилировать оттуда. Если это ускорит компиляцию, то значит имелись проблемы, связанные с сетевой файловой системой (NFS/Samba).

                                  5. Если совет 4 помог (при использовании локального диска компиляция ускорилась), то может помочь размещение на локальном диске только объектных файлов и файлов листинга. Для этого измените настройки Project -> Options -> General Options -> Output. Сконфигурируйте пути «Object files» и «List files» так, чтобы они были размещены не на сети, а локально.

                                  6. Если при компиляции бывают случаи, что процесс сильно замедляется или среда IAR зависает, то возможно, что в этот момент происходит сканирование рабочих файлов антивирусом. Такой случай может привести также к сообщениям о запрещенном доступе (denied permission), об истечении таймаута.

                                  Для того, чтобы исключить проверку антивирусом папок IAR, нужно добавить в исключения антивируса следующие папки:

                                  • Инсталляционный каталог IAR (например, это может быть папка C:Program FilesIAR SystemsEmbedded Workbench 5.4).
                                  • C:Program FilesCommon FilesIAR Systems
                                  • C:Documents and Settings USERNAME Application DataIAR Embedded Workbench

                                  Здесь USERNAME означает имя (логин пользователя), под которым Вы работаете в системе Windows. Полное имя до этой папки может зависеть от версии операционной системы Windows.

                                  7. Создайте RAM-диск, и попробуйте компилировать проект на нем. Будьте осторожны, поскольку при пропадании питания или зависании компьютера вся Ваша работа потеряется! Как промежуточный вариант, можно на RAM-диск сохранять только объектные файлы, файлы листинга и выходные файлы, для этого в свойствах проекта General Options -> Output поменяйте пути до выходных рабочих директорий Output directories.

                                  Самое простое средство для создания RAM диска — бесплатная программа SoftPerfect RAM Disk site:softperfect.com.

                                  [161019]

                                  При попытке компиляции выскакивают совершенно неожиданные ошибки — невозможно удалить файл, который либо вообще не используется в проекте, либо находится в каталоге установки IAR. Например, у меня появлялась вот такая ошибка, когда я попробовал сменить конфигурацию Release на Debug:

                                  Очевидно, что это полный бред — зачем очистке понадобилось вдруг удалять файл wchar.h, который относится к стандартным библиотекам, да и еще находится в каталоге установки среды разработки IAR Embedded Workbench.

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

                                  Решение проблемы заключается в просмотре обоих конфигураций и внесение корректных изменений в конфигурацию, где происходит эта ошибка. Особенно внимательно следует проверить дополнительные пути поиска подключаемых файлов, а также наличие предварительно определенных переключающих макросимволов (Project -> Options -> C/C++ Compiler -> Preprocessor).

                                  Довольно часто появляющаяся ошибка в разных версиях IAR. Разработчики борются с этой ошибкой, и с переменным успехом. Обычно проблема решается, если несколько раз выполнить операцию очистки (Project -> Clean). Иногда помогает перезапуск IAR + выполнение очистки проекта.

                                  Еще одна из причин такой ошибки — в проекте имеется 2 подключенных исходных файла, компиляция которых приводит к генерации одного и того же объектного файла. Например, есть две версии одного и того же модуля — один на языке C (с расширением *.c), и другой оптимизированный, на ассемблере (с тем же именем, но с расширением *.s). Решение проблемы очевидно — нужно исключить из процесса компиляции один из этих файлов.

                                  Чтобы переименовать workspace, но сохранить при этом в нем те же самые имена проектов, что и были раньше, просто переименуйте файл *.eww.

                                  Поскольку среда разработки IAR EWB не предоставляет прямого функционала для специального переименования проекта, требуется обходной путь для этого действия. Когда я переименовываю workspace и связанный с ним проект, то поступаю следующим образом:

                                  1. Делаю копию Template.ewp (это файл проекта) и переименовываю копию, скажем, в NewProject.ewp.
                                  2. Открываю файл workspace Template.eww.
                                  3. Выбираю Project -> Add Existing Project.
                                  4. Выбираю NewProject.ewp и кликаю Open.
                                  5. Выбираю закладку «Template» в нижней части списка файлов Workspace (соответствует старому проекту).
                                  6. Делаю правый клик на старом проекте и выбираю Remove.
                                  7. Закрываю IAR EWB, он запросит сохранить workspace, сохраняю.
                                  8. Переименовываю файлы старого workspace *.eww, *.ewd в NewProject.eww, NewProject.ewd (и также файл *.dep, если он у Вас есть).
                                  9. Удаляю Template.ewp.

                                  После этого Вы сможете открыть NewProject.eww как полностью переименованное workspace и полностью переименованный проект. Если Вы хотите только переименовать проект, и оставить старое имя для workspace, то выполните только шаги 1..7.

                                  [170621]

                                  Заголовочный файл lib_AT91SAM7X256.h, в IAR 6.50 выскакивают ошибки на код с операторами __inline:

                                  Проблема в том, что для встраиваемых функций поменялся синтаксис: замените __inline на inline, и ошибка исчезнет.

                                  На языке C, в отличие от C++, нет определения булевого типа. Поэтому либо подключите в коде C заголовочный файл stdbool.h:

                                  Либо добавьте в общий заголовочный файл (например types.h) следующее определение:

                                  Это глюк, связанный с файлами нулевой длины. Найдите файл, на который указывает сообщение, и удалите его.

                                  [171204]

                                  Неожиданный глюк, который начал происходить без видимых причин (наблюдалось на IAR 6.50.3 и Windows 7). При попытке компиляции выскакивает ошибка «General exception during build», которая сопровождается ошибкой очистки «General exception during clean». Причем в конфигурации Debug проект компилируется нормально, а в конфигурации Release происходит ошибка.

                                  Ресурс по известным проблемам IAR [6] советует выполнить переустановку IAR в другой каталог на диске, или переименовать папку текущей инсталляции: «Install another copy of your IAR Embedded Workbench product in a different location or rename the directory of your current installation».

                                  Мне помогло следующее — полностью удалил с диска корневую папку проекта, и восстановил её копированием из архива бекапа. После этого ошибка волшебным образом исчезла.

                                  Замечание, сигнализирующее о возможной логической ошибке в операторе switch. Вот пример из библиотеки EFSL, генерирующий такое предупреждение компилятора (Pe1814 на строке 40):

                                  Это пример не очень аккуратного кодирования: оператор swith проверяет переменную value, и эта же переменная проверяется оператором if в default-блоке того же оператора swith. Очевидно, что здесь скорее всего используется не только ненужная проверка if, но и блок else этого оператора if никогда не выполнится.

                                  В TN43262 [7] объясняется, как нужно работать с абсолютно размещаемыми переменными. Проблема с такими переменными заключается в том, что в некоторых ситуациях разработчик получает сообщение об ошибке линкера «переменная не определена». Это может быть связано с тем, что такая переменная должна быть определена специальным, не интуитивно понятным способом.

                                  Решение состоит в том, чтобы определить и разместить переменную в заголовочном файле, который будет подключаться во все исходные файлы, ссылающиеся на эту переменную.

                                  [Дополнительная информация]

                                  Переменные, которые размещаютсы по абсолютному адресу, ведут себя немного не так, как обычные не автоматические переменные C/C++. Абсолютно размещамеые переменные находятся в абсолютном сегменте, таком как ABSOLUTE или xxxx_AN. Абсолютный сегмент не представлен файле линкера, поскольку переменные уже размещены во время компиляции.

                                  Другие (обычные) не автоматические переменные, находящиеся в модуле исходного кода, размещаются в перемещаемый сегмент, который описывается в файле линкера как обычно. Поэтому разрешение адреса осуществляется во время линковки.

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

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

                                  После этого просто добавьте подключение файла setup.h во все файлы исходного кода, где должна использоваться переменная.

                                  Один из способов запомнить — думать об этом как о наличии #define для описания размещения в памяти, с добавлением наличия способности линкера проверить его непротиворечивость.

                                  [Другой способ абсолютного размещения переменной]

                                  Если Вы вместо этого поместите объект в именованный сегмент:

                                  то должен быть определен сегмент SETUP, и он должен быть размещен в файле линкера. Переменные, размещенные в сегменте, ведут себя как обычные переменные языка C, для них поместите следующую декларацию в файл заголовка:

                                  И затем Вам нужно поместить определение в один (и только в один) исходный файл:

                                  Если Вам не нравится @-синтаксис, есть его эквивалент, который можно использовать альтернативно:

                                  Источник

                                  Понравилась статья? Поделить с друзьями:
                                • Error pe007 unrecognized token
                                • Error pdo driver mysql is missing from the system freepbx
                                • Error pdf structure 40 invalid file format что делать
                                • Error pci subsystem id mismatch что это
                                • Error pci subsystem id mismatch перевод