Полная версия этой страницы:
варнинг Keil c99
Метценгерштейн
Feb 3 2015, 14:59


почему-то ему не нравится данный код, но это только варнинг
Нужно добавить объявление этой функции до ее использования.
toweroff
Feb 3 2015, 15:45
И хедер не видит - прописать в путь поиска
Метценгерштейн
Feb 3 2015, 18:00
с хидером не все так просто- он есть в путях поиска. Он ругается на содержимое этого хидера, а не на то, что не находит его. И во втором скрине видно, что внутри этой ф-ии ошибка. Как-то не так, вероятно, надо использовать noop эти. Хотя, это пример из официальной поставки с отладочной платой.
Так c99 отключите, и компилируйтесь.
Метценгерштейн
Feb 3 2015, 19:08
Цитата(Opex @ Feb 3 2015, 21:13)

Какую ошибку пишет?
ошибку завтра смогу посмотреть какую пишет.
А если хочу на С99 писать? Никак что ли? Это же не решение.
Так она и варнинг выдает из-за того, что функцию не видит, поскольку в ней ошибка. Надо сверху вниз проблемы решать.
Цитата(Метценгерштейн @ Feb 3 2015, 22:08)

А если хочу на С99 писать? Никак что ли? Это же не решение.
Найдите, как ASM-функции пишутся на нем, и поправьте хидер, чтобы функция стала компилироваться. В общем, правьте хидер до устранения ошибки в нем. Варнинг сам устранится. Что хоть за ошибка то там?
toweroff
Feb 3 2015, 19:43
а разве тело функции можно писать в хедере?
Метценгерштейн
Feb 3 2015, 20:03
Цитата(SM @ Feb 3 2015, 22:13)

Найдите, как ASM-функции пишутся на нем, и поправьте хидер, чтобы функция стала компилироваться. В общем, правьте хидер до устранения ошибки в нем. Варнинг сам устранится. Что хоть за ошибка то там?
ошибку завтра скажу- она на работе осталась
писать ф-ю в хидере можно, но это не правильно, конечно.
Цитата(Метценгерштейн @ Feb 3 2015, 22:08)

А если хочу на С99 писать? Никак что ли? Это же не решение.
Если писать, то писать. А если использовать пример, то это другое.
Я ничего криминального не увидел. Ассемблерная функция вот так у меня работает. С99, естественно.
Код
__asm void HardFault_Handler(void)
{
TST LR, #4
ITE EQ
MRSEQ R0, MSP ; Main Stack was used, put MSP in R0
MRSNE R0, PSP ; Process Stack was used, put PSP in R0
LDR R0, [R0, #24] ; Get stacked PC from stack
LDR R1, =0x40020418 ; GPIOB->BSRR
MOVS R2, #0x0002 ; Bit 2
STRH R2, [R1, #2] ; Reset bit (LED_ON)
B .
}
Только ссылка на нее идет из стартап-файла, тоже ассемблерного.
Совсем не обязательно это помнить наизусь.
Есть описание, help, примеры, device pack.
Несколько минут можно потратить и посмотреть.
Метценгерштейн
Feb 4 2015, 06:57

вот что пишет на варнинг
логика такая-
вызывается ф-я
nrf_delay_us(999);
Код
#include <stdio.h>
#include "compiler_abstraction.h"
#include "nrf.h"
#include "nrf_delay.h"
/*lint --e{438} "Variable not used" */
void nrf_delay_ms(uint32_t volatile number_of_ms)
{
while(number_of_ms != 0)
{
number_of_ms--;
nrf_delay_us(999);
}
}
ее прототип есть в хидере, что
#include "nrf_delay.h"
так что- прототип как бы есть.
а вот в самом хидере уже на нее выскакивет варнинг
Код
static __ASM void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
{
loop
SUBS R0, R0, #1
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
BNE loop
BX LR
}
фото варнинга

так что что-то объявление в ф-ии ему не нравится.
Цитата(Метценгерштейн @ Feb 4 2015, 09:57)

так что что-то объявление в ф-ии ему не нравится.
Либо __ASM, либо __INLINE не определены (либо оба). Ищите, где они определяются, и добавьте соотв. хидер перед этим хидером. Либо замените их __asm и __inline (маленькими буквами).
Либо сами напишите в начале файла
#define __ASM __asm
#define __INLINE __inline
Метценгерштейн
Feb 4 2015, 07:48
#define __ASM __asm
и замена на маленькие буквы не помогла- надо искать где они определяются.
Замена обоих __ASM и __INLINE на маленькие буквы прямо в исходнике - просто обязаны помочь, так как __asm и __inline - это ключевые слова самого KEIL-а. В отличие от __ASM и __INLINE.
Переопределение через #define - может и не помочь, если потом, между Вашим определением и использованием, их еще кто-то переопределяет по-своему, но не так, как кейлу надо. Копайте вокруг этих двух ключевых слов.
andrew_b
Feb 4 2015, 08:39
Цитата(toweroff @ Feb 3 2015, 22:43)

а разве тело функции можно писать в хедере?

Можно. Но если этот хидер будет включён несколько раз, то вы получите несколько таких функций. Линкер увидит такое и будет орать благим матом. Поэтому функции в хидерах должны обязательно объявляться как static.
Метценгерштейн
Feb 4 2015, 09:16
Цитата(andrew_b @ Feb 4 2015, 11:39)

Можно. Но если этот хидер будет включён несколько раз, то вы получите несколько таких функций. Линкер увидит такое и будет орать благим матом. Поэтому функции в хидерах должны обязательно объявляться как static.
да, такие грабли возможны.
А static как поможет? Я включаю файл хидера в .с файл. Обращаюсь к некой ф-ии в нем. И как тут компилятор узнает, что я обращаюсь к ф-ии именно данного включенного хидера?
Получается, что static говорит, что только к локальной ф-ии в этом файле я могу обратиться? Только внутри самого .с ?
Static ограничивает область видимости функции текущей единицей компиляции, из других с-файлов она не будет видима.
Этот хидер - не хидер в обычном смысле, а кусок кода, вставляющийся в разные файлы. Поскольку функция объявлена как static, эти разные функции друг друга не видят, и друг другу не мешают.
Цитата(andrew_b @ Feb 4 2015, 11:39)

Можно. Но если этот хидер будет включён несколько раз, то вы получите несколько таких функций. Линкер увидит такое и будет орать благим матом.
Ничего линкер не увидит. Это же __inline функция - она разворачивается еще компилятором. И, кроме как в хидерах, их нигде и не определить. Ну можно прямо в файле перед использованием.
PS
А вот смысл "static" применительно к __inline совершенно не понятен. Эта функция по любому видима только в пределах файла, где этот include вставлен.
Из стандарта:
A function declaration with an inline specifier declares an inline function. The inline
specifier indicates to the implementation that inline substitution of the function body at the point of call
is to be preferred to the usual function call mechanism. An implementation is not required to perform this
inline substitution at the point of call.....
inline - только рекомендация к встраиванию.
If a function with external linkage is
declared inline in one translation unit, it shall be declared inline in all translation units in which it appears;
no diagnostic is required. An inline function with external linkage shall have the same address in all
translation units.
Видимо, бывают еще извращения всякие.
Цитата(Opex @ Feb 4 2015, 19:20)

If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears;
Ну тем паче, такое можно сделать только, разместив ее в хидере. В общем, это факт, что инлайн-функции, которые могут быть использованы в нескольких файлах, всегда определяются в хидерах.
Попробовал для интереса, можно и в C-файле определить, работает.
Цитата(Opex @ Feb 4 2015, 20:18)

Попробовал для интереса, можно и в C-файле определить, работает.
Конечно, можно, так и делают, если она "местная", нигде больше не нужная. И, вообще, какая разница - если хидер включается еще на этапе препроцессора, и становится единым целым с файлом.
Цитата(SM @ Feb 4 2015, 22:51)

Конечно, можно, так и делают, если она "местная", нигде больше не нужная. И, вообще, какая разница - если хидер включается еще на этапе препроцессора, и становится единым целым с файлом.
Я неточно выразился, в отдельном C-файле. А использовал ее в другом.
Цитата(Opex @ Feb 4 2015, 20:55)

Я неточно выразился, в отдельном C-файле. А использовал ее в другом.
А вот это лажа какая-то... Ее компилятор хоть и не обязан разворачивать, но должен, как все современные и порядочные компиляторы.... И возможности вызвать ее откуда-то снаружи при этом нет.
Еще интересный момент:
A static local variable in an extern inline function always refers to the same object.
Что несовместимо с определением функции в заголовочном файле. Быть может, где-то и находит применение...
Цитата(Opex @ Feb 4 2015, 21:12)

Что несовместимо с определением функции в заголовочном файле.
Это с чего бы несовместимо? Учитывая то, что, собственно, отдельного кода эта функция не имеет, раз она инлайн, то от функции остается только статическая переменная, которая имеет вполне определенное уникальное имя (символ). Все совместимо.
Только вот эта статическая переменная будет разной для разных единиц компиляции. А так - одна на всех.
Цитата(Opex @ Feb 5 2015, 11:34)

Только вот эта статическая переменная будет разной для разных единиц компиляции. А так - одна на всех.
Вот именно потому, что я объяснил, она будет именно одна. Потому что линкер создаст связь всех обращений к переменной к одной и той же, по причине того, что символ имеет одно уникальное имя, несмотря на то, что определен "150 раз" через инклудник.
Да, действительно, одна получается.
Выходит, что определение inline функции в h-файле - то же самое, что объявление extern inline h-файле и определение в с-файле.
Добавление static к функции делает статическую переменную локальной.
Цитата(Opex @ Feb 5 2015, 12:08)

Выходит, что определение inline функции в h-файле - то же самое, что объявление extern inline h-файле и определение в с-файле.
Добавление static к функции делает статическую переменную локальной.
Нельзя определить inline функцию без ее тела - это противоречит самой сущности inline. Без наличия в файле (и всех включенных хидерах) определения тела такой функции, компилятор, если он реально делает инлайн, а не игнорирует его, должен по идее как-то ругнуться. То есть, определение extern inline без определения тела ф-ции это пустой бред - откуда компилятор возьмет тело функции, чтобы его встроить в место ее вызова?
Вот нашел еще:
http://stackoverflow.com/questions/216510/...e/216546#216546in K&R C or C89, inline was not part of the language. Many compilers implemented it as an extension, but there were no defined semantics regarding how it worked. GCC was among the first to implement inlining, and introduced the "inline", "static inline", and "extern inline" constructs; most pre-C99 compiler generally follow its lead.
GNU89:
"inline": the function may be inlined (it's just a hint though). An out-of-line version is always emitted and externally visible. Hence you can only have such an inline defined in one compilation unit, and every other one needs to see it as an out-of-line function (or you'll get duplicate symbols at link time).
"static inline" will not generate a externally visible out-of-line version, though it might generate a file static one. The one-definition rule does not apply, since there is never an emitted external symbol nor a call to one.
"extern inline" will not generate an out-of-line version, but might call one (which you therefore must define in some other compilation unit. The one-definition rule applies, though; the out-of-line version must have the same code as the inline offered here, in case the compiler calls that instead.
C99 (or GNU99):
"inline": like GNU "extern inline"; no externally visible function is emitted, but one might be called and so must exist
"extern inline": like GNU "inline": externally visible code is emitted, so at most one translation unit can use this.
"static inline": like GNU "static inline". This is the only portable one between gnu89 and c99
Цитата(Opex @ Feb 5 2015, 12:54)

no externally visible function is emitted, but one might be called and so must exist
Жестко! А где ее взять? Написать отдельно в не-инлайн версии?
Так получается, на случай, если компилятору не захочется ее встраивать.
В C99 со static inline компилятор сам себе сделает функцию, если не захочет встраивать,
а с просто inline надо ему написать ее с точно таким же кодом.
Мутно, конечно, это. Как я понял, лучше всегда писать static inline, от греха подальше.
Куда-то топик унёсся не туда. Хотелось бы увидеть лог компилятора, а не "весёлые картинки".
На первом сообщении видны реальные матюги компилятора или просто ненормальности Эклипса ?
Он часто в последние годы тупит, пытаясь быть самым умным, но не имея на это достойной поддержки своих "разумных" авторов, "обнимающих необъятное" в IT-областях.
У меня большинство файлов не обходятся без его "меток", хотя в реале всё компилируется без вопросов.
Если пример поставляется для этой среды, то всё должно заехать чисто, все настройки быть прописанными.
Вложить полный проект можно прямо в форум, чтобы "счастливые обладатели" могли быстро боднуться и выложить свои рецепты ?
А можно взять Keil IDE но использовать arm-none-eabi
Там проще всё
Или VisualGDB и VisualStudio
И не мучится с armcc.exe
А что в конференции на keil.com или arm.com говорят ?
Цитата(x893 @ Feb 5 2015, 18:35)

А можно взять
....
А толку то? От смены компилятора вдруг чудесными образом в рамках тех же исходников самоопределятся __ASM и __INCLUDE ?
arm-none-eabi к синтаксису проще относится. То что там проходит - в armcc может быть warning или даже error.
Цитата(x893 @ Feb 5 2015, 22:23)

То что там проходит - в armcc может быть warning или даже error.
Но не этот случай, с банально не определенными двумя словами.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.