|
Не отрабатывает #define, глюки работы директивы define |
|
|
|
Jan 9 2008, 22:11
|

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

|
Цитата(Николай Z @ Jan 9 2008, 22:42)  __delay_cycles() - это тяжелое наследие 8-ми разрядной архитектуры? Или что? Причем тут "тяжелое наследие"!? Это удобное расширение Си, реализованное в ИАРовских компиляторах в виде intrinsic function. Выше я уже приводил кусок хелпа, а Сергей Борщ кратко про нее рассказал. Могу повториться: встретив эту функцию, компилятор заменяет её кодом минимальной длины (циклами), который выполняется заданное число тактов конкретного процессора. Большое преимущество этой фичи в том, что во-первых не нужно в ручную подбирать циклы, а во-вторых, этот кусок кода не трогает оптимизатор. Все свои программные задержки, где забываешь счетчик цикла объявить volatile, оптимизатор безжалостно выкидывает Одно плохо: функция не стандартная.
|
|
|
|
|
Jan 10 2008, 08:16
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Jan 10 2008, 09:05
|
Местный
  
Группа: Участник*
Сообщений: 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, оптимизатор безжалостно выкидывает Одно плохо: функция не стандартная. Угу... А когда забудешь и влепишь выражение в параметр подобной функции - это лучше? Я предпочитаю явное указание оптимизатору давать : "а не лезь сюда со своим интеллектом" - volatile это... А насчет рассчитать величину задержки - а что тут такого суперсложного? Насчет стандартности - такая функция(и другие ей подобные) стандартной быть не может и не должна. Ибо она платформенно-зависимая в очень большой степени. Цитата(IgorKossak @ Jan 10 2008, 00:41)  Это intrinsic function, описанная в EWAVR_CompilerReference.pdf и обьявленная в intrinsics.h А у меня не EW AVR_CompilerReference.pdf , у меня EW ARM_CompilerReference.pdf
Сообщение отредактировал Николай Z - Jan 10 2008, 08:54
|
|
|
|
|
Jan 10 2008, 09:35
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(Николай Z @ Jan 10 2008, 12:05)  А насчет рассчитать величину задержки - а что тут такого суперсложного? Да ничего, но ее надо рассчитать. Для чего надо знать про оптимизацию. Или вставлять код на асме. А __delay_cycles(X) делает это автоматом, наиболее корректно и затем при чтении кода не возникает вопросов о том, что это такое. Так что в ситуациях, когда нужны небольшие задержки - по моему, самое оно. Насчет переносимости - она обычно используется где-то глубоко внизу, а при переносе на другую платформу "низ" обычно приходится так или иначе переписывать... Цитата(Николай Z @ Jan 10 2008, 12:05)  Угу... А когда забудешь и влепишь выражение в параметр подобной функции - это лучше? В данном случае компилятор не позволит использовать неконстантное выражение.
|
|
|
|
|
Jan 10 2008, 09:47
|
Местный
  
Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930

|
Цитата(Непомнящий Евгений @ Jan 10 2008, 12:35)  В данном случае компилятор не позволит использовать неконстантное выражение. В данном - возможно... А в моем - который я выше описал - очень даже позволил. Потому я бы все-таки предпочел самое, что ни на есть явное задание нужных мне задержек. Чтобы не надо было искать особенности этой функции нигде - прозрачность кода вещь архиполезнейшая... Ну а было бы - допустим - прозрачным, самоочевидным и ясным определение это функции - то и не было бы тут этого обсуждения. Кстати...  Вот по такому определению функции мне совершенно неясно - что параметр должен быть константным выражением (eго Baser привел и видимо оно в *.h и забито): Цитата Макрос то использует встроенную функцию ИАРа:
__delay_cycles(unsigned long int); ... Значит это ограничение забито где-то еще... Ну а часто ли мы по каждому поводу лазаем по мануалам? Вот и делайте выводы.
Сообщение отредактировал Николай Z - Jan 10 2008, 09:56
|
|
|
|
|
Jan 10 2008, 11:42
|

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

|
Цитата(Николай Z @ Jan 10 2008, 11:47)  Потому я бы все-таки предпочел самое, что ни на есть явное задание нужных мне задержек. Чтобы не надо было искать особенности этой функции нигде - прозрачность кода вещь архиполезнейшая...
Ну а было бы - допустим - прозрачным, самоочевидным и ясным определение это функции - то и не было бы тут этого обсуждения
Вот по такому определению функции мне совершенно неясно - что параметр должен быть константным выражением ... Значит это ограничение забито где-то еще... Ну а часто ли мы по каждому поводу лазаем по мануалам? Вот и делайте выводы. Чесно говоря я не могу придумать более самоочевидного и ясного определения: __delay_cycles(k); - подождать k циклов (вставить k виртуальных NOPов). А если параметр будет некорректным - компилятор ругнется. ПосмОтрите в хелп ( один раз) и далее будете применять правильно. А посколько функция нестандартная, скорее перед ее применением посмотрите в хелп ( также один раз). А приведенный вами пример с задержкой для 8051 только подтверждает мои слова, там у вас компилятор не ругался, а что получилось? Вот и делайте выводы.
|
|
|
|
|
Jan 11 2008, 21:40
|
Местный
  
Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930

|
Цитата(Baser @ Jan 10 2008, 14:42)  Чесно говоря я не могу придумать более самоочевидного и ясного определения: __delay_cycles(k); - подождать k циклов (вставить k виртуальных NOPов). А если параметр будет некорректным - компилятор ругнется. ПосмОтрите в хелп ( один раз) и далее будете применять правильно. А посколько функция нестандартная, скорее перед ее применением посмотрите в хелп ( также один раз). А приведенный вами пример с задержкой для 8051 только подтверждает мои слова, там у вас компилятор не ругался, а что получилось? Вот и делайте выводы.  Да ради бога - нравится используйте... Только на мой вкус - лучше явное написанный код + комент к нему. Не так много мест где такие аппаратно-зависимые фокусы нужны, а в качестве плюса - самоочевидность этого куска без каких-либо хелпов и доков.
|
|
|
|
|
Jan 11 2008, 23:01
|

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

|
Цитата(Николай Z @ Jan 11 2008, 23:40)  Только на мой вкус - лучше явное написанный код + комент к нему. Не так много мест где такие аппаратно-зависимые фокусы нужны, а в качестве плюса - самоочевидность этого куска без каких-либо хелпов и доков. В результате этой дискуссии, где я с пеной у рта расписывал преимущества применения функции __delay_cycles, я и себя самого убедил, что это хорошо На самом деле я эту функцию ни разу не применял, а задержки реализую в виде функций на ассме. Но сейчас убедился, что и __delay_cycles тоже реализована правильно. Вот вам еще один довод против вашего метода: Даже если ваша функция задержки обложена volatile, __root и т.д., в ней напрочь отключена оптимизация, то где гарантия, что новая версия компилятора не станет по другому генерить код и все задержки поплывут!?
|
|
|
|
|
Jan 12 2008, 11:54
|
Местный
  
Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930

|
Цитата(Baser @ Jan 12 2008, 14:34)  Интересно, а что вы можете предложить другое для коротких задержек. Таймеров у небольших МК мало и они как правило заняты под другие, более важные задачи.  А разве трудно сделать простейшую функцию опроса таймера? Кто сказал, что один таймер это мало? Процесс простейший: 1) Узнать текущий отсчет таймера... 2) Посчитать требуемый... 3) Пока значение меньше требуемого - вертеть цикл с операций NOP... Ну а если Вам нужна задержка на 1-2-3-5 тактов - обкладывайте это место volatil-ом сколько хотите и никакой оптимизатор туда не полезет... Особенно если там вставлен ассемблерный код прямо в C-шную функцию... А для длинных задержек - не грех и семафоры устроить и ждать их(call-back или любой другой механизм)... Ну а если Вы заглянете в коды FreeRTOS - для STR912 - то вообще обнаружите, что там весь тайминг построен вообще не на таймерах... А на сторожевом таймере - watchdog-е... Мне это было немного странно - при наличии целых 3-х таймеров и одном RTC, но вот так есть...
Сообщение отредактировал Николай Z - Jan 12 2008, 11:58
|
|
|
|
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|