реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Не отрабатывает #define, глюки работы директивы define
aspID
сообщение Jan 6 2008, 10:27
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



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

Код
#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
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 6 2008, 11:02
Сообщение #2


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



А как вы определяете, что не отрабатывает?
Примеры ваши учебные, должны работать. Я у себя проверил - работает laughing.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 6 2008, 12:08
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aspID @ Jan 6 2008, 12:27) *
Столкнулся с тем, что не отрабатывает.

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

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 6 2008, 12:38
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата
А как вы определяете, что не отрабатывает?

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

Если 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 учту замечание на будущее
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 6 2008, 13:01
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(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))


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 6 2008, 15:14
Сообщение #6


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



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

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

p.s. Приведенные вами выдержки из файлов main.cpp и delay.h, расположенные друг за другом, в ИАРе не дают никаких "ругательств". А если убрать #define F_CPU, то исправно выдаются ваши warning-и
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 7 2008, 20:51
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



называется "почувствуй себя..." завтра(сегодня) попробую проект прицепить с работы

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

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

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

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

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

Сообщение отредактировал aspID - Jan 7 2008, 20:55
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 7 2008, 21:22
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(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 включен.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 8 2008, 03:57
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата
Канает, но исключительно для одного файла main.cpp.

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

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

А! Кажется, понял, что Вы имеете в виду. Тогда полез изучать документацию на предмет порядка обработки файлов компилятором... Я почему-то считал, что тот, в котором main() будет обработан первым unsure.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 8 2008, 07:12
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aspID @ Jan 8 2008, 05:57) *
Я почему-то считал, что тот, в котором main() будет обработан первым unsure.gif

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 8 2008, 08:34
Сообщение #11


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Практическая рекомендация к теоретическим объяснениям 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" в другие свои локальные хедер файлы, но я обычно для наглядности вложения не делаю, а описываю в файлах с кодом все входящие хедеры в явном виде.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 8 2008, 08:38
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Jan 8 2008, 09:12) *
в пределах одного единственного текущего файла
текущего компилируемого (и включенных в него заголовочных) файла.

для aspID: ключевое словосочетание для поисков в книгах и гугле - "раздельная компиляция"


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 8 2008, 08:59
Сообщение #13


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



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

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

А я прочел и решил спросить - а в чем суть возражения? По-моему zltigo и как раз и говорил о текущем файле - т.е. как раз о компилируемом?

Сообщение отредактировал Николай Z - Jan 8 2008, 09:03
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jan 8 2008, 10:14
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



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

А я прочел и понял суть так, что очень хочется подловить на противоречии biggrin.gif
Будь у Вас изначально позитивный подход, Вы бы поняли, что это возражение, а дополнение.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 8 2008, 13:33
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 8 2008, 14:05
Сообщение #16


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 8 2008, 15:05
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата
Если это обида

Сергей, Вовсе даже нет! Просто этого оказалось достаточно. И спасибо было вполне отдушевное.
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 8 2008, 15:07
Сообщение #18


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



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

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

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

Или задавать вопросы - это большой грех? biggrin.gif

Сообщение отредактировал Николай Z - Jan 8 2008, 15:13
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 8 2008, 20:20
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(aspID @ Jan 8 2008, 15:33) *
Я сдаюсь sad.gif разъясните, пожалуйста, почему надо сначала делить, а потом умножать.

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 9 2008, 04:13
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата
Еще придется думать о переполнении

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

Про точность понима, а вот про скорость не понима... Что будет работать быстрее и почему?
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 9 2008, 08:03
Сообщение #21


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



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

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

А вот насчет переполнения сам не уверен: компилятор при константе UL будет считать в 32-разрядных целых или в 64-разрядных?
Если в 32-разрядных, то при больших частоте кварца и задержке будет и переполнение smile.gif
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 9 2008, 08:16
Сообщение #22


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



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

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

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

Сообщение отредактировал Николай Z - Jan 9 2008, 08:17
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 9 2008, 11:05
Сообщение #23


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aspID
сообщение Jan 9 2008, 11:57
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(Сергей Борщ @ Jan 9 2008, 17:05) *
Отнюдь. Если параметр x в точке использования макроса - константа, то IAR все выражение вычислит на этапе компиляции (а в приведенном в посте №1 коде там именно константа). Если переменная - то да, на этапе исполнения.

Спасибо! Самый понравившийся ответ smile.gif
Видимо, именно потому, что не подумал о возможности подстановки вместо x "неконстанты" я и не мог понять, почему так. На всяческий случай подправил "универсально" в своих макросах - чтобы сначала выполнялось деление.
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 9 2008, 12:05
Сообщение #25


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(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 имел в виду не скорость, а размер кода?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 9 2008, 13:32
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Jan 9 2008, 14:05) *
Так что может коллега zltigo имел в виду не скорость, а размер кода?

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



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

Ну теперь знаете smile.gif а то, что называется "сюрприз!" может случиться с задержкой.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 9 2008, 13:42
Сообщение #27


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 9 2008, 16:10
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Jan 9 2008, 15:42) *
...аргументом __delay_cycles() может быть только константа

Ну тогда в этом наиконкретнейшем случае наилучший вариант найден. Главное теперь известно, что возможны варианты smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 9 2008, 20:42
Сообщение #29


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



__delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры? Или что?

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

Что-то смутно помню подобное из архитектуры 8051... подобное... хотя всего год как бросил этот обломок совместимости... biggrin.gif

Сообщение отредактировал Николай Z - Jan 9 2008, 20:44
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 9 2008, 20:54
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



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

Естественно smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 9 2008, 21:41
Сообщение #31


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

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

Это intrinsic function, описанная в EWAVR_CompilerReference.pdf и обьявленная в intrinsics.h
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 9 2008, 22:11
Сообщение #32


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



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

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

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

Одно плохо: функция не стандартная.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 10 2008, 03:49
Сообщение #33


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(zltigo @ Jan 10 2008, 02:54) *
Естественно smile.gif

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

Вообще, имхо, к архитектуре это отношения не имеет, местами вполне полезная фишка.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 10 2008, 08:16
Сообщение #34


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


Цитата(Baser @ Jan 10 2008, 00:11) *
Причем тут "тяжелое наследие"!?
Это у Николая стиль общения такой - "тяжелое наследие", "обломок совместимости". Не обращай внимания.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 10 2008, 09:05
Сообщение #35


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Сергей Борщ @ 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, 08:54
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Jan 10 2008, 09:35
Сообщение #36


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



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


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


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


В данном случае компилятор не позволит использовать неконстантное выражение.
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 10 2008, 09:47
Сообщение #37


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



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

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

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

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

__delay_cycles(unsigned long int);
...
Значит это ограничение забито где-то еще... Ну а часто ли мы по каждому поводу лазаем по мануалам?
Вот и делайте выводы.

Сообщение отредактировал Николай Z - Jan 10 2008, 09:56
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 10 2008, 11:42
Сообщение #38


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



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

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

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

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

А приведенный вами пример с задержкой для 8051 только подтверждает мои слова, там у вас компилятор не ругался, а что получилось?
Вот и делайте выводы. smile.gif
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 11 2008, 21:40
Сообщение #39


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



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

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

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

Только на мой вкус - лучше явное написанный код + комент к нему. Не так много мест где такие аппаратно-зависимые фокусы нужны, а в качестве плюса - самоочевидность этого куска без каких-либо хелпов и доков.
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 11 2008, 23:01
Сообщение #40


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



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

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

Вот вам еще один довод против вашего метода:
Даже если ваша функция задержки обложена volatile, __root и т.д., в ней напрочь отключена оптимизация, то где гарантия, что новая версия компилятора не станет по другому генерить код и все задержки поплывут!? sad.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jan 11 2008, 23:13
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Jan 12 2008, 01:01) *
...где гарантия, что новая версия компилятора не станет по другому генерить код и все задержки поплывут!? sad.gif

Гарантия в НЕИСПОЛЬЗОВАНИИ софтовых задержек smile.gif. Заодно не будет удивления от отсутствия у других компиляторов и компиляторов для других платформ не сколь полезных, сколь провоцирующих функций задержек.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 12 2008, 11:34
Сообщение #42


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Jan 12 2008, 01:13) *
Гарантия в НЕИСПОЛЬЗОВАНИИ софтовых задержек

Интересно, а что вы можете предложить другое для коротких задержек. Таймеров у небольших МК мало и они как правило заняты под другие, более важные задачи. sad.gif
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 12 2008, 11:54
Сообщение #43


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(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, но вот так есть...

Сообщение отредактировал Николай Z - Jan 12 2008, 11:58
Go to the top of the page
 
+Quote Post
Baser
сообщение Jan 12 2008, 11:58
Сообщение #44


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(Николай Z @ Jan 12 2008, 13:54) *
...
Согласен, можно и так rolleyes.gif
Go to the top of the page
 
+Quote Post
Николай Z
сообщение Jan 12 2008, 12:08
Сообщение #45


Местный
***

Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930



Цитата(Baser @ Jan 12 2008, 14:58) *
Согласен, можно и так rolleyes.gif

Дэк - классика это... К тому же - Вы сами сказали - для очень коротких - лучше на ASM написать функцию, которую никакой оптимизатор не тронет - C-шный... И сомнений не будет - относительно правильности-неправильности определения нестандартной функции... Индусы, которые их лепят - далеко не всегда думают о всех возможных последствиях опрел\деления функций подобных delay_cycle(n)...
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 18:02
Рейтинг@Mail.ru


Страница сгенерированна за 0.01848 секунд с 7
ELECTRONIX ©2004-2016