Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не отрабатывает #define
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
aspID
Столкнулся с тем, что не отрабатывает. Приходится ставить все в опциях компилятора. Не понимаю, почему. Поиску либо разучился задавать вопросы, либо на самом деле ни у кого такой проблемы не возникало и здесь ее не обсуждали (наверное, вряд ли, но прошу сильно не сердиться и по возможности не просто отослать в поиск, а дать ссылку)

Код
#ifdef DEBUG
//Генерация импульса синхронизации
DDRD |= 1 << PD1;
PORTD |= 1 << PD1;
_delay_ms( 1 );
PORTD &= ~(1 << PD1);
#endif //DEBUG


Пока явно в опциях не поставишь DEBUG, в любом из файлов хоть заставься. Точно также не отрабатывает

Код
#ifndef F_CPU
  #define F_CPU 3686400UL
#endif


В используемом далее контексте ругается, что не определено F_CPU
Код
#ifndef F_CPU
# warning "F_CPU not defined for <aspID/delay.h> using 1MHz"
# warning "To define F_CPU go Proj->Opt->C/C++->Defined symbols"
# define F_CPU 1000000UL
#endif

Но и этот # define очень похоже, что не отрабатывает.
help.gif
Заранее спасибо и всех с наступающим Рождеством! santa2.gif


ЗЫ: до сих пор не могу победить проблему, если пишу с использованием классов и НЕ использую конструктор по умолчанию - кричит "дай!" sad.gif
Baser
А как вы определяете, что не отрабатывает?
Примеры ваши учебные, должны работать. Я у себя проверил - работает laughing.gif
zltigo
Цитата(aspID @ Jan 6 2008, 12:27) *
Столкнулся с тем, что не отрабатывает.

Не работать не может. Нет, конечно, если в огороде бузина а дядька в Киеве, то тогода будут проблемы...
Надо понимать, что
#define F_CPU 3686400UL
это не есть нечно вроде "глобальной переменной". Это просто простейшая подстановка препроцесора которая должна встретиться до ее использования именно в текущем файле или прямо описанная, или описанная в другом файле, но включенном в текуший через #include.

P.S.
Писать в стиле "#<пробелы>directive" не стоит, хоть это препроцессор и понимает.
aspID
Цитата
А как вы определяете, что не отрабатывает?

Ну, хотя бы по "ругательствам"...
Или по тому, что если прописываю эти же дефайны в опциях, то работает "как хочу", а не "что это?!"

Если main.cpp начинается с
Код
#ifndef ENABLE_BIT_DEFINITIONS
  #define ENABLE_BIT_DEFINITIONS
#endif

#ifndef DEBUG
  #define DEBUG
#endif //DEBUG

#ifndef F_CPU
  #define F_CPU 3686400UL
#endif

#include <iotiny2313.h>
#include <aspID/defs.h>
#include <aspID/delay.h>
#include "1-wire.h"
#include <aspID/seg7.h>


А в delay.h стоит
Код
#ifndef _DELAY_H_ASP_
#define _DELAY_H_ASP_

#include <inavr.h>

#ifndef F_CPU
# warning "F_CPU not defined for <aspID/delay.h> using 1MHz"
# warning "To define F_CPU go Proj->Opt->C/C++->Defined symbols"
# define F_CPU 1000000UL
#endif

#define _delay_ns(x) __delay_cycles(x*F_CPU/1000000000)
#define _delay_us(x) __delay_cycles(x*F_CPU/1000000)
#define _delay_ms(x) __delay_cycles(x*F_CPU/1000)
#define _delay_s(x) __delay_cycles(x*F_CPU)

#endif //_DELAY_H_ASP_

То это по-моему, за ошибку "раньше-позже" не проканывает - ряд должен "сходиться", а он "расходится" twak.gif


Цитата
Писать в стиле "#<пробелы>directive" не стоит, хоть это препроцессор и понимает.

Ага, понимает! smile.gif учту замечание на будущее
zltigo
Цитата(aspID @ Jan 6 2008, 14:38) *
Или по тому, что если прописываю эти же дефайны в опциях, то работает "как хочу"....

Я понимаю, что Вы чего-то хотите, только из приведенных кусочков лично я не могу понять что Вы "хочу". Определения F_CPU в текстах нет в принципе. Соответственно имеет место "ругань", если, конечно не подсунуть определение препроцессору в командной строке через -DF_CPU, что Вы и делаете и что, естественно, работает.

Макросы КРАЙНЕ небрежны sad.gif. Рихтуем:
Код
#define _delay_ns(x) __delay_cycles(((x)*(F_CPU))/1000000000UL)
#define _delay_us(x) __delay_cycles(((x)*(F_CPU))/1000000UL)
#define _delay_ms(x) __delay_cycles(((x)*(F_CPU))/1000UL)
#define _delay_s(x) __delay_cycles((x)*(F_CPU))

Только о наносекундах речь не пойдет smile.gif Надо выбирать:
Код
#define _delay_ns(x) __delay_cycles((x)*((F_CPU)/1000000000UL)
#define _delay_us(x) __delay_cycles((x)*((F_CPU)/1000000UL)
#define _delay_ms(x) __delay_cycles((x)*((F_CPU)/1000UL)
#define _delay_s(x) __delay_cycles((x)*(F_CPU))
Baser
Цитата(aspID @ Jan 6 2008, 14:38) *
Ну, хотя бы по "ругательствам"...
Или по тому, что если прописываю эти же дефайны в опциях, то работает "как хочу", а не "что это?!"
...
То это по-моему, за ошибку "раньше-позже" не проканывает - ряд должен "сходиться", а он "расходится"

Вы меня извините, но почему-то то, что говорит вам zltigo я прекрасно понимаю, а то что говорите вы, нет! laughing.gif Не могли бы вы понятней объяснить, что вы хотите получить и что у вас в результате получается.

p.s. Приведенные вами выдержки из файлов main.cpp и delay.h, расположенные друг за другом, в ИАРе не дают никаких "ругательств". А если убрать #define F_CPU, то исправно выдаются ваши warning-и
aspID
называется "почувствуй себя..." завтра(сегодня) попробую проект прицепить с работы

Цитата
Надо выбирать

Ок, учтем-с, спасибо! Правда, пока не понял глубокой разницы :-/ Прошу пока не подсказывать smile.gif

Цитата
Определения F_CPU в текстах нет в принципе.

main.cpp строки 9-11 гласят
Код
#ifndef F_CPU
  #define F_CPU 3686400UL
#endif

Или "оно" за директиву не канает уже? wacko.gif
zltigo
Цитата(aspID @ Jan 7 2008, 22:51) *
Правда, пока не понял глубокой разницы

Есть. Местами разительная.
Цитата
main.cpp строки 9-11 гласят
Код
#ifndef F_CPU
  #define F_CPU 3686400UL
#endif

Или "оно" за директиву не канает уже? wacko.gif

Канает, но исключительно для одного файла main.cpp. Что-то мне подсказывает, что у Вас delay.h не в одном файле по #include включен.
aspID
Цитата
Канает, но исключительно для одного файла main.cpp.

Как для одного? Это же директива препроцессора, он ее должен обработать на начальном этапе... А до этой директивы никаких #include не обозначено...

Цитата
не в одном файле по #include включен.

А! Кажется, понял, что Вы имеете в виду. Тогда полез изучать документацию на предмет порядка обработки файлов компилятором... Я почему-то считал, что тот, в котором main() будет обработан первым unsure.gif
zltigo
Цитата(aspID @ Jan 8 2008, 05:57) *
Я почему-то считал, что тот, в котором main() будет обработан первым unsure.gif

Хоть первым, хоть двадцать первым, хоть минус первым. Все все директивы препроцессора обрабатыватываются исключительно в пределах одного единственного текущего файла и НИКАКОГО влияния ни на какие другие файлы не оказывают.
Baser
Практическая рекомендация к теоретическим объяснениям zltigo:
Я обычно делаю хедер файл, в котором описываю все глобальные для всего проекта define, описания регистровых флагов (если они используются), extern-ы глобальных переменных и функций, называя его, например defines.h
Код
//==============================================================//
//      Header file for ........ :      External Definitions    //
//==============================================================//
#ifndef ENABLE_BIT_DEFINITIONS
  #define ENABLE_BIT_DEFINITIONS
#endif

#ifndef DEBUG
  #define DEBUG
#endif //DEBUG

#ifndef F_CPU
  #define F_CPU 3686400UL
#endif

__regvar __no_init volatile union {
    unsigned char Flags1;
    struct {
        unsigned char f10ms_Past :1;
        unsigned char            :7;
        };
    } @ 15;

extern unsigned char Test1;
extern void crc16_XModem(unsigned char data);
......

Далее этот файл добавляется через #include "defines.h" ВО ВСЕ другие файлы проекта, где встречаются эти определения. Можно делать и вложенные #include "defines.h" в другие свои локальные хедер файлы, но я обычно для наглядности вложения не делаю, а описываю в файлах с кодом все входящие хедеры в явном виде.
Сергей Борщ
Цитата(zltigo @ Jan 8 2008, 09:12) *
в пределах одного единственного текущего файла
текущего компилируемого (и включенных в него заголовочных) файла.

для aspID: ключевое словосочетание для поисков в книгах и гугле - "раздельная компиляция"
Николай Z
zltigo сказал:
Цитата(zltigo @ Jan 8 2008, 10:12) *
Хоть первым, хоть двадцать первым, хоть минус первым. Все все директивы препроцессора обрабатыватываются исключительно в пределах одного единственного текущего файла и НИКАКОГО влияния ни на какие другие файлы не оказывают.

Сергей Борщ возразил на это:
Цитата(Сергей Борщ @ Jan 8 2008, 11:38) *
текущего компилируемого (и включенных в него заголовочных) файла.

А я прочел и решил спросить - а в чем суть возражения? По-моему zltigo и как раз и говорил о текущем файле - т.е. как раз о компилируемом?
Dog Pawlowa
Цитата(Николай Z @ Jan 8 2008, 12:59) *
А я прочел и решил спросить - а в чем суть возражения?

А я прочел и понял суть так, что очень хочется подловить на противоречии biggrin.gif
Будь у Вас изначально позитивный подход, Вы бы поняли, что это возражение, а дополнение.
aspID
Цитата(zltigo @ Jan 6 2008, 19:01) *
Макросы КРАЙНЕ небрежны sad.gif. Рихтуем:
Код
#define _delay_ns(x) __delay_cycles(((x)*(F_CPU))/1000000000UL)
#define _delay_us(x) __delay_cycles(((x)*(F_CPU))/1000000UL)
#define _delay_ms(x) __delay_cycles(((x)*(F_CPU))/1000UL)
#define _delay_s(x) __delay_cycles((x)*(F_CPU))

Только о наносекундах речь не пойдет smile.gif Надо выбирать:
Код
#define _delay_ns(x) __delay_cycles((x)*((F_CPU)/1000000000UL)
#define _delay_us(x) __delay_cycles((x)*((F_CPU)/1000000UL)
#define _delay_ms(x) __delay_cycles((x)*((F_CPU)/1000UL)
#define _delay_s(x) __delay_cycles((x)*(F_CPU))


Пересмотрел и вышеозвученной "разительной" разницы не нашел. Разве что недостаток закрывающих скобок smile.gif Я сдаюсь sad.gif разъясните, пожалуйста, почему надо сначала делить, а потом умножать.

Цитата
ключевое словосочетание

понЯл, отстал. Спасибо rolleyes.gif
Сергей Борщ
Цитата(aspID @ Jan 8 2008, 15:33) *
понЯл, отстал. Спасибо rolleyes.gif
Если это обида - то совершенно напрасно. Я полагаю, что через поисковик вы найдете гораздо более обширную информацию по этому вопросу (в разных местах освещенную с разных сторон). И это будет гораздо полезнее, чем если кто-то попытается кратко (и возможно с ошибками) пересказать ее здесь.
aspID
Цитата
Если это обида

Сергей, Вовсе даже нет! Просто этого оказалось достаточно. И спасибо было вполне отдушевное.
Николай Z
Цитата(Dog Pawlowa @ Jan 8 2008, 13:14) *
А я прочел и понял суть так, что очень хочется подловить на противоречии biggrin.gif
Будь у Вас изначально позитивный подход, Вы бы поняли, что это возражение, а дополнение.

Неправильно поняли - я никого ловить не собирался. И противоречия в ответах я не наблюдаю.
Я только пытаюсь понять - а зачем это уточнение.
Я видите ли в том случае, если что-то не понял имею обыкновение переспросить.

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

Или задавать вопросы - это большой грех? biggrin.gif
zltigo
Цитата(aspID @ Jan 8 2008, 15:33) *
Я сдаюсь sad.gif разъясните, пожалуйста, почему надо сначала делить, а потом умножать.

Нужно делать то, что нужно. А что нужно - либо точность, либо скорость - думайте. Еще придется думать о переполнении.
aspID
Цитата
Еще придется думать о переполнении

Макрос. Срабатывает при компиляции. На "большом" компутере. Переполнение... Нет, представляю, как оно может случиться, но по-моему, если не формировать секундные задержки наносекундным макросом то переполниться сложно blush.gif

Про точность понима, а вот про скорость не понима... Что будет работать быстрее и почему?
Baser
Цитата(aspID @ Jan 9 2008, 06:13) *
Макрос. Срабатывает при компиляции. На "большом" компутере. Переполнение... Нет, представляю, как оно может случиться

У вас в макросах все константы - целые числа. Поэтому и все промежуточные результаты будут целыми. Все дробные части отбрасываются. Для точности нужно сначала УМНОЖИТЬ, а потом ПОДЕЛИТЬ.

А вот насчет переполнения сам не уверен: компилятор при константе UL будет считать в 32-разрядных целых или в 64-разрядных?
Если в 32-разрядных, то при больших частоте кварца и задержке будет и переполнение smile.gif
Николай Z
Цитата(aspID @ Jan 9 2008, 07:13) *
Макрос. Срабатывает при компиляции. На "большом" компутере. Переполнение... Нет, представляю, как оно может случиться, но по-моему, если не формировать секундные задержки наносекундным макросом то переполниться сложно blush.gif

Про точность понима, а вот про скорость не понима... Что будет работать быстрее и почему?

Отнюдь... У Вас там параметр x присутствует... Потому полностью при компиляции не сработает.
Если деление сначала - то это должно сработать при компиляции, а вот умножение при исполнении...
Если наоборот - первым умножение - то все будет работать только при исполнении - отсюда и разница в быстродействии... А переполнение возможно в зависимости от реализации целочисленной арифметики при умножении - я не знаю деталей вашего проца.
Сергей Борщ
Цитата(Baser @ Jan 9 2008, 10:03) *
А вот насчет переполнения сам не уверен: компилятор при константе UL будет считать в 32-разрядных целых или в 64-разрядных?
UL - 32 разрядные. ULL - 64 разряда
Цитата(Николай Z @ Jan 9 2008, 10:16) *
Отнюдь... У Вас там параметр x присутствует... Потому полностью при компиляции не сработает.
Отнюдь. Если параметр x в точке использования макроса - константа, то IAR все выражение вычислит на этапе компиляции (а в приведенном в посте №1 коде там именно константа). Если переменная - то да, на этапе исполнения.
aspID
Цитата(Сергей Борщ @ Jan 9 2008, 17:05) *
Отнюдь. Если параметр x в точке использования макроса - константа, то IAR все выражение вычислит на этапе компиляции (а в приведенном в посте №1 коде там именно константа). Если переменная - то да, на этапе исполнения.

Спасибо! Самый понравившийся ответ smile.gif
Видимо, именно потому, что не подумал о возможности подстановки вместо x "неконстанты" я и не мог понять, почему так. На всяческий случай подправил "универсально" в своих макросах - чтобы сначала выполнялось деление.
Baser
Цитата(zltigo @ Jan 8 2008, 22:20) *
А что нужно - либо точность, либо скорость - думайте.

Цитата(aspID @ Jan 9 2008, 06:13) *
Про точность понима, а вот про скорость не понима... Что будет работать быстрее и почему?

А вот действительно, наконец-то задумался smile.gif и тоже не понял, что значит в данном примере СКОРОСТЬ.
Макрос то использует встроенную функцию ИАРа:
Цитата
__delay_cycles(unsigned long int);
Makes the compiler generate code that takes the given amount of cycles to perform, that is it inserts a time delay that lasts the specified number of cycles.
Note: The specified value must be a constant integer expression and not an expression that is evaluated at runtime.

И если он будет генерить для одной и той-же или для близких по величине констант код, работающий сильно различное время, то это будет явный ляп ИАРа. А его не наблюдается smile.gif
Так что может коллега zltigo имел в виду не скорость, а размер кода?
zltigo
Цитата(Baser @ Jan 9 2008, 14:05) *
Так что может коллега zltigo имел в виду не скорость, а размер кода?

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



Цитата(aspID @ Jan 9 2008, 13:57) *
Видимо, именно потому, что не подумал о возможности подстановки вместо x "неконстанты"...

Ну теперь знаете smile.gif а то, что называется "сюрприз!" может случиться с задержкой.
Сергей Борщ
Цитата(zltigo @ Jan 9 2008, 15:32) *
а то, что называется "сюрприз!" может случиться с задержкой.
На этапе компиляции. Baser правильно заметил - аргументом __delay_cycles() может быть только константа, ибо компилятор для каждой конкретной задержки генерит подогнанный по тактам код. Для задержек в 2-4 такта вообще без цикла. Если использовать в качестве аргумента переменную - выдает ошибку на этапе компиляции. Исходя из этого можно посоветовать aspIDу поменять макросы назад - чтобы сначала выполнялось умножение и при прочих равных иметь бОльшую точность. А F_CPU объявить с индексом ULL - чтобы вычисления выполнялись в 64 битах и (при разумных задержках) не происходило переполнения.
zltigo
Цитата(Сергей Борщ @ Jan 9 2008, 15:42) *
...аргументом __delay_cycles() может быть только константа

Ну тогда в этом наиконкретнейшем случае наилучший вариант найден. Главное теперь известно, что возможны варианты smile.gif
Николай Z
__delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры? Или что?

Я что-то перерыл все библиотеки в своем IAR-е 4.3 и вообще ее не обнаружил...

Что-то смутно помню подобное из архитектуры 8051... подобное... хотя всего год как бросил этот обломок совместимости... biggrin.gif
zltigo
Цитата(Николай Z @ Jan 9 2008, 22:42) *
__delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры?

Естественно smile.gif
IgorKossak
Цитата(Николай Z @ Jan 9 2008, 22:42) *
__delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры? Или что?

Я что-то перерыл все библиотеки в своем IAR-е 4.3 и вообще ее не обнаружил...

Это intrinsic function, описанная в EWAVR_CompilerReference.pdf и обьявленная в intrinsics.h
Baser
Цитата(Николай Z @ Jan 9 2008, 22:42) *
__delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры? Или что?

Причем тут "тяжелое наследие"!? Это удобное расширение Си, реализованное в ИАРовских компиляторах в виде intrinsic function. Выше я уже приводил кусок хелпа, а Сергей Борщ кратко про нее рассказал.

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

Одно плохо: функция не стандартная.
dxp
Цитата(zltigo @ Jan 10 2008, 02:54) *
Естественно smile.gif

Еще это является с некоторых пор и "тяжелым наследием 16-разрядной архитектуры" - в том же EW430, например, с некоторых пор тоже существует такой интринсик. smile.gif

Вообще, имхо, к архитектуре это отношения не имеет, местами вполне полезная фишка.
Сергей Борщ
Цитата(dxp @ Jan 10 2008, 05:49) *
Вообще, имхо, к архитектуре это отношения не имеет, местами вполне полезная фишка.
Есть предложение считать правильной такую версию: эта функция реализована в компиляторах ИАРа для процессоров, у которых детерминировано время выполнения команд. Вот, например, у ARM7 время выполнения зависит от места исполнения (ОЗУ/флеш), от настроек ускорителя, у более старших (скорее всего) - от настроек кеша. Поэтому в EWARM такой функции нет.


Цитата(Baser @ Jan 10 2008, 00:11) *
Причем тут "тяжелое наследие"!?
Это у Николая стиль общения такой - "тяжелое наследие", "обломок совместимости". Не обращай внимания.
Николай Z
Цитата(Сергей Борщ @ Jan 10 2008, 11:16) *
Есть предложение считать правильной такую версию: эта функция реализована в компиляторах ИАРа для процессоров, у которых детерминировано время выполнения команд. Вот, например, у ARM7 время выполнения зависит от места исполнения (ОЗУ/флеш), от настроек ускорителя, у более старших (скорее всего) - от настроек кеша. Поэтому в EWARM такой функции нет.

Понятно... А то я озадачился отсутствием этой функции в моих библиотеках... специально искал ее и не нашел...

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

Даже на 8051-м процессоре(поискал и нашел-таки в старых залежах) я постарался аналогичную функцию исключить из употребления и необходимые задержки предпочитал вставлять сам в виде 2-3 asm(" nop"); или соответствующих циклов.

Зачем? А вот как раз затем - что аналогичная функция в моем случае позволяла задать пераметром не только константное выражение. В результате - один из наших "сильно умных" практикантов написал кусок кода с операцией деления при рассчете этой задержки. Ну а деление в свою очередь - не имело аппаратной поддержки... Как результат - вот именно то о чем говорил zltigo - вместо задержки на фиксированное количество тактов - получалось черт знает что. Если точнее - функция-то задержку делала правильную, но ей предшествовало вычисление величины этой задержки, которое занимало в несколько раз большее время и это время сильно зависело от заданных значений.

Цитата(Baser @ Jan 10 2008, 01:11) *
Все свои программные задержки, где забываешь счетчик цикла объявить volatile, оптимизатор безжалостно выкидывает smile.gif

Одно плохо: функция не стандартная.

Угу... А когда забудешь и влепишь выражение в параметр подобной функции - это лучше?
Я предпочитаю явное указание оптимизатору давать : "а не лезь сюда со своим интеллектом" - volatile это...
А насчет рассчитать величину задержки - а что тут такого суперсложного?

Насчет стандартности - такая функция(и другие ей подобные) стандартной быть не может и не должна. Ибо она платформенно-зависимая в очень большой степени.

Цитата(IgorKossak @ Jan 10 2008, 00:41) *
Это intrinsic function, описанная в EWAVR_CompilerReference.pdf и обьявленная в intrinsics.h

А у меня не EWAVR_CompilerReference.pdf , у меня EWARM_CompilerReference.pdf
Непомнящий Евгений
Цитата(Николай Z @ Jan 10 2008, 12:05) *
А насчет рассчитать величину задержки - а что тут такого суперсложного?


Да ничего, но ее надо рассчитать. Для чего надо знать про оптимизацию. Или вставлять код на асме. А __delay_cycles(X) делает это автоматом, наиболее корректно и затем при чтении кода не возникает вопросов о том, что это такое.
Так что в ситуациях, когда нужны небольшие задержки - по моему, самое оно.
Насчет переносимости - она обычно используется где-то глубоко внизу, а при переносе на другую платформу "низ" обычно приходится так или иначе переписывать...


Цитата(Николай Z @ Jan 10 2008, 12:05) *
Угу... А когда забудешь и влепишь выражение в параметр подобной функции - это лучше?


В данном случае компилятор не позволит использовать неконстантное выражение.
Николай Z
Цитата(Непомнящий Евгений @ Jan 10 2008, 12:35) *
В данном случае компилятор не позволит использовать неконстантное выражение.

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

Ну а было бы - допустим - прозрачным, самоочевидным и ясным определение это функции - то и не было бы тут этого обсуждения. Кстати... biggrin.gif

Вот по такому определению функции мне совершенно неясно - что параметр должен быть константным выражением (eго Baser привел и видимо оно в *.h и забито):
Цитата
Макрос то использует встроенную функцию ИАРа:

__delay_cycles(unsigned long int);
...
Значит это ограничение забито где-то еще... Ну а часто ли мы по каждому поводу лазаем по мануалам?
Вот и делайте выводы.
Baser
Цитата(Николай Z @ Jan 10 2008, 11:47) *
Потому я бы все-таки предпочел самое, что ни на есть явное задание нужных мне задержек.
Чтобы не надо было искать особенности этой функции нигде - прозрачность кода вещь архиполезнейшая...

Ну а было бы - допустим - прозрачным, самоочевидным и ясным определение это функции - то и не было бы тут этого обсуждения

Вот по такому определению функции мне совершенно неясно - что параметр должен быть константным выражением ...
Значит это ограничение забито где-то еще... Ну а часто ли мы по каждому поводу лазаем по мануалам?
Вот и делайте выводы.

Чесно говоря я не могу придумать более самоочевидного и ясного определения:
__delay_cycles(k); - подождать k циклов (вставить k виртуальных NOPов).
А если параметр будет некорректным - компилятор ругнется. ПосмОтрите в хелп (один раз) и далее будете применять правильно. А посколько функция нестандартная, скорее перед ее применением посмотрите в хелп (также один раз).

А приведенный вами пример с задержкой для 8051 только подтверждает мои слова, там у вас компилятор не ругался, а что получилось?
Вот и делайте выводы. smile.gif
Николай Z
Цитата(Baser @ Jan 10 2008, 14:42) *
Чесно говоря я не могу придумать более самоочевидного и ясного определения:
__delay_cycles(k); - подождать k циклов (вставить k виртуальных NOPов).
А если параметр будет некорректным - компилятор ругнется. ПосмОтрите в хелп (один раз) и далее будете применять правильно. А посколько функция нестандартная, скорее перед ее применением посмотрите в хелп (также один раз).

А приведенный вами пример с задержкой для 8051 только подтверждает мои слова, там у вас компилятор не ругался, а что получилось?
Вот и делайте выводы. smile.gif

Да ради бога - нравится используйте...

Только на мой вкус - лучше явное написанный код + комент к нему. Не так много мест где такие аппаратно-зависимые фокусы нужны, а в качестве плюса - самоочевидность этого куска без каких-либо хелпов и доков.
Baser
Цитата(Николай Z @ Jan 11 2008, 23:40) *
Только на мой вкус - лучше явное написанный код + комент к нему. Не так много мест где такие аппаратно-зависимые фокусы нужны, а в качестве плюса - самоочевидность этого куска без каких-либо хелпов и доков.

В результате этой дискуссии, где я с пеной у рта расписывал преимущества применения функции __delay_cycles, я и себя самого убедил, что это хорошо biggrin.gif
На самом деле я эту функцию ни разу не применял, а задержки реализую в виде функций на ассме. Но сейчас убедился, что и __delay_cycles тоже реализована правильно.

Вот вам еще один довод против вашего метода:
Даже если ваша функция задержки обложена volatile, __root и т.д., в ней напрочь отключена оптимизация, то где гарантия, что новая версия компилятора не станет по другому генерить код и все задержки поплывут!? sad.gif
zltigo
Цитата(Baser @ Jan 12 2008, 01:01) *
...где гарантия, что новая версия компилятора не станет по другому генерить код и все задержки поплывут!? sad.gif

Гарантия в НЕИСПОЛЬЗОВАНИИ софтовых задержек smile.gif. Заодно не будет удивления от отсутствия у других компиляторов и компиляторов для других платформ не сколь полезных, сколь провоцирующих функций задержек.
Baser
Цитата(zltigo @ Jan 12 2008, 01:13) *
Гарантия в НЕИСПОЛЬЗОВАНИИ софтовых задержек

Интересно, а что вы можете предложить другое для коротких задержек. Таймеров у небольших МК мало и они как правило заняты под другие, более важные задачи. sad.gif
Николай Z
Цитата(Baser @ Jan 12 2008, 14:34) *
Интересно, а что вы можете предложить другое для коротких задержек. Таймеров у небольших МК мало и они как правило заняты под другие, более важные задачи. sad.gif

А разве трудно сделать простейшую функцию опроса таймера? Кто сказал, что один таймер это мало?
Процесс простейший:
1) Узнать текущий отсчет таймера...
2) Посчитать требуемый...
3) Пока значение меньше требуемого - вертеть цикл с операций NOP...

Ну а если Вам нужна задержка на 1-2-3-5 тактов - обкладывайте это место volatil-ом сколько хотите и никакой оптимизатор туда не полезет... Особенно если там вставлен ассемблерный код прямо в C-шную функцию...

А для длинных задержек - не грех и семафоры устроить и ждать их(call-back или любой другой механизм)...

Ну а если Вы заглянете в коды FreeRTOS - для STR912 - то вообще обнаружите, что там весь тайминг построен вообще не на таймерах... А на сторожевом таймере - watchdog-е... Мне это было немного странно - при наличии целых 3-х таймеров и одном RTC, но вот так есть...
Baser
Цитата(Николай Z @ Jan 12 2008, 13:54) *
...
Согласен, можно и так rolleyes.gif
Николай Z
Цитата(Baser @ Jan 12 2008, 14:58) *
Согласен, можно и так rolleyes.gif

Дэк - классика это... К тому же - Вы сами сказали - для очень коротких - лучше на ASM написать функцию, которую никакой оптимизатор не тронет - C-шный... И сомнений не будет - относительно правильности-неправильности определения нестандартной функции... Индусы, которые их лепят - далеко не всегда думают о всех возможных последствиях опрел\деления функций подобных delay_cycle(n)...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.