Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/26: Рейтинг темы: голосов - 26, средняя оценка - 4.88
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
1

Запрет оптимизации макроса (Atmel Studio, GCC)

03.08.2015, 11:43. Показов 4695. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть макрос, написанный на ассемблере. Как запретить оптимизацию этого макроса?
#define delayUs(us) __asm volatile(" <ассемблерный код> ")
Среда разработки Atmel Studio, компилятор GCC.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.08.2015, 11:43
Ответы с готовыми решениями:

Atmel Studio 6.2, GCC, повторное использование кода
Привет бойцам невидимого фронта! Подскажите пожалуйста, кто подобные вещи пользовал: Есть кучка...

Почему AVR Studio 4, а не Atmel Studio 6?
По какой причине большинство специалистов по AVR микроконтроллерам в основном используют AVR Studyo...

Оптимизации при компиляции gcc в ассемблерный код
На лабораторную работу нам задали написать свой простейший транслятора си-подобного языка в...

Atmel Studio
Подскажите где смотреть библиотеку Atmel Studio.

Atmel studio 6.1
Здравствуйте. столкнулся с проблемой запуска программы. вылетает сообщение:debugging tool is not...

18
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
03.08.2015, 20:10 2
Цитата Сообщение от Haamu Посмотреть сообщение
Есть макрос, написанный на ассемблере. Как запретить оптимизацию этого макроса?
непонятен контекст. Что значит запретить оптимизацию? то что вы показали - это не макрос в ассемблерном понимании. Покажите, в каком именно месте компилятор его выкидывает, и что написано в кавычках.
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
04.08.2015, 09:08  [ТС] 3
Вот код полностью:
C
1
2
3
4
5
6
7
8
9
__attribute__((optimize(0)))
#define delayUs(us)   __asm volatile( "mov r1, %1 \n"       \
                "mul.w  r0, r1, %0 \n"  \
                "subs r0, #10 \n"       \
                "lsrs r0, r0, #1 \n"                 \
                "nop \n"            \
                "1: subs r0, #1 \n"     \
                "bhi 1b"            \
                ::"r"(us), "r"(McuClkMHz) )
Это цикл определенной продолжительности для небольшой задержки. Без оптимизации работает, а при оптимизации O2 становится короче на несколько тактов, компилятор немного оптимизирует ту часть, где происходит вычисление числа повторений цикла. Собственно строкой выше и решение этой проблеммы. Не знаю на сколько правильное решение, но вроде работает.
1
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
04.08.2015, 09:26 4
Сдается мне, вы вообще отключаете в этом случае оптимизацию ), для всего проекта.
Чтобы ограничить действие атрибута функцией организуйте вашу задержку в виде inline-функции, а не дефайна. девайн - хоть и точнее можно понять, но в данном случае менее гибок и коряво выглядит в исходнике.
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
04.08.2015, 12:18  [ТС] 5
Если делать через inline функцию, не будет ли меняться время вызова этой функции при изменении оптимизации?
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
04.08.2015, 12:47 6
Зачем нужен inline
1
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
04.08.2015, 14:40  [ТС] 7
В заголовочном файле:
C
1
inline void delayUs(uint16_t us);
В си-файле:
C
1
2
3
4
5
6
7
8
9
10
11
inline void delayUs(uint16_t us)
{
    __asm volatile( "mov r1, %1 \n"         \
    "mul.w  r0, r1, %0 \n"  \
    "subs r0, #10 \n"       \
    "lsrs r0, r0, #1 \n"    \
    "nop \n"                \
    "1: subs r0, #1 \n"     \
    "bhi 1b"                \
    ::"r"(us), "r"(McuClkMHz) );
}
В main подключаю заголовочнй, вызываю функцию, в результате ошибка: "undefined reference to `delayUs'"
Что я делаю не так?
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
04.08.2015, 15:00 8
1. Модификатор inline оставьте только в си файле в хендоре inline уберите.
2. Есть правило/соглашение в СИ
Не включайте в заголовочный файл исполняемый код, а также объявления переменных.
Но для функции inline допускается исключение, то есть перенести тело в заголовок.

Кстати, из какого файла проекта, Вы, пытаетесь вызвать функцию?
И вообще не стал бы париться с асм вставками
C
1
2
3
4
5
6
7
8
9
10
11
12
void App_DelayUs(u16 us)
{
    u8 i;
    
    while (us--)
    {
        for (i=7; i>0; i--)
        {
            ;
        }
    }
}
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
04.08.2015, 15:19  [ТС] 9
1. Уже сам дошел до этого экспериментальным путем
2. Я правильно понял, вместо объявления функции в хедере, можно сразу определить ее? Не работает...
Цитата Сообщение от Витальич Посмотреть сообщение
Кстати, из какого файла проекта, Вы, пытаетесь вызвать функцию?
А это принципиально? Из main.c прям в самой функции main.
Цитата Сообщение от Витальич Посмотреть сообщение
И вообще не стал бы париться с асм вставками
Всё дело в точности. Хотелось чтобы функция/макрос delayUs выполнялась ровно микросекунду

Почему-то никакого инлайна не получается. Смотрел в дизассемблере, хоть с инлайн, хоть без, происходит просто вызов функции, что дает большую погрешность по времени задержки. Вобщем вернулся к тому, с чего начинал. Решил оставить макрос и забить на всякие там оптимизации. С оптимизацией O2 погрешность меньше процента.
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
04.08.2015, 16:00 10
Цитата Сообщение от Haamu Посмотреть сообщение
Уже сам дошел до этого экспериментальным путем
Документация наше всё
Цитата Сообщение от Haamu Посмотреть сообщение
Я правильно понял, вместо объявления функции в хедере, можно сразу определить ее?
Смотрите документацию на свой компилятор. Про мой пишут, что вот так надо:
C
1
2
3
4
#pragma inline=forced
inline void LedOn() {
    LED_PORT|=(1<<LED_PIN);
}
Цитата Сообщение от Haamu Посмотреть сообщение
А это принципиально?
Иногда, но не в Вашем случаи.
Цитата Сообщение от Haamu Посмотреть сообщение
Всё дело в точности

Не по теме:

Всё дело в волшебных пузырьках

0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
04.08.2015, 16:55 11
Haamu, попробуйте еще так написать:
C
1
__attribute__((always_inline)) inline void foo(void)
...собсно, это тоже самое, что предложил Витальич.
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
04.08.2015, 17:29  [ТС] 12
Попробовал все три варианта:
C
1
2
3
void delayUs(uint16_t us)
inline void delayUs(uint16_t us)
__attribute__((always_inline)) inline void delayUs(uint16_t us)
Никакой разницы...
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
04.08.2015, 17:41 13
Я таки говорил, что лучше читать документацию
Вот документ как раз по Вашей проблеме, короче inline не нужен http://www.ethernut.de/pdf/GCCAVRInlAsmCB.pdf
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
05.08.2015, 09:17  [ТС] 14
Спасибо, но немного не то. Во-первых нет ничего на счет оптимизации, во-вторых у меня ARM, а не AVR.
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
05.08.2015, 10:15 15
Цитата Сообщение от Haamu Посмотреть сообщение
во-вторых у меня ARM, а не AVR
упс, сбило, что Atmel Studio, как то забыл, что она умеет и с Atmel(овскими) ARM работать. Но для arm еще легче документация ищется, например http://www.ethernut.de/en/docu... e-asm.html
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
05.08.2015, 21:43 16
Haamu, сомневаюсь я однако, что делать на АРМе задержку в цикле - это хорошая идея. Для этого в подавляющем большинстве контроллеров есть таймеры и система прерываний с приоритетами. Добиться большой точности измерения времени не так уж и сложно, чего не скажешь о выполнении задачи тотально без прерываний - на арме это допустимо в архи-критических случаях.
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
05.08.2015, 22:04 17
Поддержу уважаемого Voland_, делать программную задержку на ARM, а зачем? А если еще и для GPIO, то совсем печально. ИМХО конечно.
0
1 / 1 / 0
Регистрация: 19.12.2013
Сообщений: 43
06.08.2015, 11:06  [ТС] 18
Полностью с вами согласен, что не хорошо делать задержку в цикле Но я совсем чуть-чуть, всего одну микросекунду и очень редко. Для этих целей пользовать какую-то периферию как-то не хочется. Да и точность по сути не особо критична. Просто для общего развития хотелось попробовать сделать с точностью до такта. Спасибо что откликнулись.
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
06.08.2015, 22:29 19
Цитата Сообщение от Haamu Посмотреть сообщение
с точностью до такта
ну, а вы вообще читали как выполняются инструкции в АРМах? Насчет PREFETCH, FLASH wait-states, выполнении кода из разных типов памяти? АРМы не выполняют инструкции строго по тактам и посчитать это не так просто.
0
06.08.2015, 22:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.08.2015, 22:29
Помогаю со студенческими работами здесь

Atmel Studio 6.0
Здравствуйте! Подскажите пожалуйста , не пойму почему при запуске программы компилятор выдает : ...

Atmel Studio
помогите написать программу работы светофора на языке Assembler

Atmel studio 6
Вопрос таков, есть некая библиотека, в lcd_lib.h прототипы, в lcd_lib.c сами функции, оба файла...

Atmel Studio 7 и Arduino
Добрый день! Раньше у меня была установлена Atmel Studyo 6.2 и плагин Visual Micro и можно было...

Дизассемблирование в Atmel Studio 6.2
Подскажите, как настроить Atmel Studio 6.2, чтобы при загрузки hex файла, он отображался в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru