muravei 3 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба static inline void ws2812_send_single_byte(uint8_t byte) { for(uint8_t mask = 0x80; mask != 0; mask >>= 1) { if(byte & mask) { __asm__ __volatile__("sbi %0, %1 \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "cbi %0, %1 \n\t" : : "i" (PORT_LED), "i" (PIN_LED) : ); } else { __asm__ __volatile__("sbi %0, %1 \n\t" "nop \n\t" "cbi %0, %1 \n\t" "nop \n\t" "nop \n\t" : : "i" (PORT_LED), "i" (PIN_LED) : ); } } } попробовал так: asm("sbi PORT_LED,PIN_LED"); asm("nop"); asm("cbi PORT_LED,PIN_LED"); asm("nop"); asm("nop"); ругается: Цитата Unknown symbol in inline assembly: "PORT_LED" Я пытался объяснить: #define PIN_LED PB0 #define PORT_LED PORTB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 3 minutes ago, muravei said: Я пытался объяснить: OFF: Вопрос: зачем для современного компилятора писать на ассемблере без крайней на то необходимости? У IAR очень хороший оптимизатор для ARM. Возможно, что то же самое и для AVR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
muravei 3 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 5 минут назад, haker_fox сказал: без крайней на то необходимости? Так как раз тот случай. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
makc 192 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 19 минут назад, muravei сказал: __asm__ __volatile__("sbi %0, %1 \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "cbi %0, %1 \n\t" : : "i" (PORT_LED), "i" (PIN_LED) : ); Этот вариант не компилируется для AVR? Вроде бы у них для ARMовского компилятора такой синтаксис документирован и должен работать. PS: Попытки засунуть дефайны из C в инлайн-ассемблер могут сработать только с помощью конкатенации строк и макроса типа STRINGIFY, чтобы при передачи в транслятор ассемблера уже были подставлены макросы портов и т.п. элементов ассемблерного кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
muravei 3 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 14 минут назад, makc сказал: __asm__ __volatile__ Если заменить на "asm", то не нравится : 15 минут назад, makc сказал: : : "i" (PORT_LED), "i" (PIN_LED) : Если прямо вписать адрес и бит , то мой вариант проходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex11 3 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба Определяйте символы в asm, а не в c. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 7 часов назад, makc сказал: Вроде бы у них для ARMовского компилятора такой синтаксис документирован и должен работать. Для IAR ARM всё ок: #define PORT_LED 29 void ws2812_send_single_byte(uint byte) { asm("MOVS R0, %0\n" : : "i"(PORT_LED) : "cc"); } Нормально компилится даже старым IAR_v7.80.4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба 7 часов назад, muravei сказал: Если заменить на "asm", то не нравится : Откройте документацию на компилятор. Да-да, на компилятор ИАР. Там про встроенный ассемблер буквально пара страниц и в конце резюме - не используйте встраиваемый ассемблер ни для чего сложнее NOP или разрешения/запрета прерываний. То есть ответ на заголовок темы: никак это невозможно переписать на встроенный ассемблер ИАРа для AVR. Для ИАРа надо всю функцию писать на настоящем ассемблере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 5 9 февраля, 2023 Опубликовано 9 февраля, 2023 · Жалоба Пишите на Це с контролем в дизассемблере. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
muravei 3 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба Ну низя, так низя. Всего 4 строчки , напишу циферками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба 1 час назад, muravei сказал: Ну низя, так низя. Дело не в "нельзя". Никто за вас разбираться, что у вас там глючит не будет. И телепатов тут нет, которые угадают - что скрывается за вашими PB0 и PORTB: В 09.02.2023 в 14:27, muravei сказал: Я пытался объяснить: #define PIN_LED PB0 #define PORT_LED PORTB И во что они разворачиваются. Я выше приводил работоспособный пример. В котором макрос PORT_LED нормально разворачивается в литеральную константу. Которая далее нормально компилится. И в вашем компиляторе должен также разворачиваться. Так как препроцессор есть в любом си-компиляторе и работает по общим правилам. Но похоже вы его даже не попробовали. Кроме того, IAR for ARM например в свойствах проекта имеет опцию "Preprocessor output to file". При её включении можно посмотреть - что получилось на выходе препроцессора, перед собственно компиляцией файла. Увидеть результаты макроподстановки. Вполне возможно IAR for AVR тоже имеет аналогичный ключ. Компилим мой пример с включённым ключом "Preprocessor output to file". И в соответствующем .i-файле видим: void ws2812_send_single_byte(uint byte) { asm("MOVS R0, %0\n" : : "i"(29) : "cc"); } Макроподстановка выполнена успешно. Далее asm() будет обработан компилятором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба 3 часа назад, jcxz сказал: И в вашем компиляторе должен также разворачиваться. Не должен. Не умеет IAR для AVR передавать во встроенный ассемблер параметры. Вот это вот все он не умеет: 3 часа назад, jcxz сказал: : : "i"(29) : "cc" И поэтому не может ни передать byte внутрь асма ни отследить, какие регистры были испорчены. Соответственно весь дальнейший код может работать как угодно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба 2 часа назад, Сергей Борщ сказал: Не умеет IAR для AVR передавать во встроенный ассемблер параметры Как это "не умеет"? А тут: В 09.02.2023 в 14:07, muravei сказал: В 09.02.2023 в 13:49, makc сказал: : : "i" (PORT_LED), "i" (PIN_LED) : Если прямо вписать адрес и бит , то мой вариант проходит ТС вроде как пишет, что можно вписать адрес и бит явно. Я понял - литеральными константами вместо PORT_LED и PIN_LED. И будет компилироваться. Или о чём он тут?... написано невразумительно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба 6 часов назад, jcxz сказал: Как это "не умеет"? Вот так. Не умеет согласно документации: 6 часов назад, jcxz сказал: Или о чём он тут?. Это код, который надо было перенести с gcc на IAR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vov4ick 35 10 февраля, 2023 Опубликовано 10 февраля, 2023 · Жалоба А почему нельзя так (примерно) byte |= mask nop() .... byte &= ~mask Компилятор должен сам догадаться. При передаче в функцию адреса регистра ввода-вывода могут быть особенности из-за различных адресных пространств. В документации GCC-AVR об этом написано, в IAR думаю тоже должно быть, вроде были модификаторы типов под адреса-порты, с которыми работают битовые инструкции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться