Універсальний gcc-avr.mak

У зв’язку з описаною раніше помилкою avr-ld та методом боротьби з нею мене спитали про той «універсальний» файл gcc-avr.mak, яким я користуюся у всіх проектах. «Нічого воєнного», це просто файл, у який зібрано команди, які без змін переходили б з проекту в проект шляхом копіювання (і наступного редагування) Makefile від попереднього проекту 😉

Тепер файл gcc-avr.mak підключається до Makefile проекту командою include. Так само, як і подібний мейк-файл для роботи з програматором avreal — avreal.mak. Файл для проекту тепер короткий, містить лише головні налаштування. Легше знайти потрібне, важче поламати те, що вже перевірене.

Повернімося тепер до цього універсального мейк-файлу для avr-gcc і до згаданої помилки в avr-ld.

Окрім іншого, на початку gcc-avr.mak здійснюється налаштування шляхів до програм, використовуваних при компіляції. Виглядає це так (нумерація рядків відповідає файлу, доданому у прикріплений архів).

40
41
42
43
44
45
46
47
48
49
# Set default toolchain prefix if it does not defind in environment or project makefile
TOOL ?= avr-

# Set tool names
CC  := $(TOOL)gcc
AS  := $(TOOL)gcc -x assembler-with-cpp
BIN := $(TOOL)objcopy
OBJCOPY := $(TOOL)objcopy
OBJDUMP := $(TOOL)objdump
SIZE    := $(TOOL)size

Читати далі » » »

Attached Files:

avr-ld buffer overflow

Дійсно прикра помилка в avr-ld (binutils-avr 2.25) — та, що спонукала мене до перевірки використання Raspberry Pi як комп’ютера для роботи, — виявилася доволі цікавою.

Почала вивалюватися вона у мене доволі давно, але я помилково вважав, що вона притаманна 64-бітній версії Ubuntu 16.04, бо на роботі в 32-бітній все працювало. Думав, що це якісь проблеми невраховування розмірів чи співвідношення розмірів змінних на зразок «подаруночка від FTDI». Чесно кажучи, у повідомлення не особливо і вчитувався — «та хай, це по роботі, то на роботі й зберу» і вдома більше не запускав аж до того, як нещодавно перезібрати знадобилося негайно, бо це зупиняло термінову роботу. Тоді ж ото зібрав на Raspberry й написав про все це.

Ну й на ключову фразу *** buffer overflow detected *** Іван у коментарях пояснив, як із цим можна боротися.
Докладніше читайте » » »

Raspberry Pi як комп’ютер для роботи

Не від хорошого життя довелося провести тест Raspberry Pi як робочого комп’ютера.

Не знаю, після якого оновлення Ubuntu MATE, але на моєму основному комп’ютері перестав працювати avr-ld, валиться з помилкою «*** buffer overflow detected ***» (це на 64-бітній системі, пізніше я перевірив, що на 32-бітній такій же МАТЕ і з тими ж оновленнями все працює — це не так, залежить не від розрядності, докладніше тут).
А мені терміново знадобилося внести маленьку зміну в прошивку ATtiny13A. Мій «червоненький» ноутбук зараз інтенсивно використовує дружина, то щоб їй не заважати, я згадав про Raspberry, на яку оце ж нещодавно ставив (таку ж!) убунту.

Поставив там avr-gcc, все зібрав, перекинув на основний комп, прошив.

Стало цікаво порівняти швидкість. Цей маленький (близько 400 байт прошивки) асемблерний проект на роль такого тесту геть не годиться, тому я вирішив позбирати більший. Поставив, відповідно, arm-none-eabi-gcc, щоб збирати поточний проект для STM32F105. Там десятки файлів, за 40 кілобайт результат, — час вже можна міряти. Збирав на Raspberry, на основному своєму комп’ютері (AMD A8), на «червоненькому» Dell Vostro V130 (Core i3) і на роботі на Pentium D (дохлий, як на нинішні часи, комп’ютер, але його там цілком вистачає). На всіх системах стоїть Ubuntu MATE 16.04 з усіма оновленнями. Лише на AMD A8 64-бітна, всі інші 32-бітні (і на всіх 32-бітних avr-ld свою роботу чесно робить).

Ось що вийшло (time make -j число_ядер, час у секундах).
Воно від збирання до збирання трохи стрибало, але не принципово.

система
(ядер*ГГц)
real user system
Raspberry Pi 3
(4*1.2)
12.2 32.6 3.3
Pentium E2160
(2*1,8)
9.5 13.3 1.8
Core i3 M380
(4*1,33)
8.2 20.6 2.7
AMD A8-7600
(4*3.1)
3.1 7.7 1.2

Тут у табличці нема ширини і швидкості шини пам’яті, своє слово сказало і те, що Raspberry працює з SD-карти, Pentium-D і AMD A8 з SATA-дисків, а Core-i3 з SSD. Але тут я хочу порівняти все ж таки не кількість зкомпільованих рядків коду на гігагерц-ядро чи DDR-истість пам’яті, а абсолютний час — питання, що турбує: «чи йти заварювати чай, чи воно раніше збере» 🙂

Виявилося, що Pi 3, на відміну від перших Raspberry, цілком придатний для роботи з прошивками такого обсягу.
І що ця плата реально набагато швидша, ніж комп’ютер, на якому років 15 тому я запускав альтерівський Quartus-II 9.1 для збирання прошивок альтер (не можу пригадати, що у мене тоді було… якийсь Athlon-550 чи що). Та й «мікроконтролерні» компіляції там більше часу займали.

Різні версії WinAVR поруч

Коли виходять нові версії компіляторів, у більшості випадків варто спершу спробувати нову версію в роботі, не відмовляючись остаточно від старої. Лише після перевірки перейти на нову версію, можливо навіть попроектно. Бажано залишити можливість повернення до попередньої.
Для цього необхідно встановити поруч кілька версій:

avr-gcc folders

Але ж треба якось вказати своїй системі програмування, яку саме версію використовувати. Звісно, при необхідності замінити версію витирати з кореня диску каталог C:\WinAVR та копіювати у нього один з каталогів компіляторів це «дещо незручно».
»»» Прочитати, як це можна зробити зручніше…

Використання секцій в GCC

Нехай перед нами стоїть наступна задача. Програма може складатися з набору модулів, які комбінуються в залежності від потреб. Кожен модуль має функцію, яка викликається при його виборі в простому меню на терміналі. Також є текстовий рядок та літера для меню. Ми хочемо автоматизувати процес збирання програми таким чином, що при підключення модуля в проект він «сам» ініціалізується і «реєструється» в програмі до початку роботи main(). В C++ це робиться за допомогою конструкторів, але при цьому розмір програми росте. В C можна в окремому файлі створити масив структур опису модулів і ініціалізувати його статично. Щоправда, при цьому доведеться ініціалізувати модулі окремим циклом на початку функції main() (теж трохи додаткового коду) та для формування масиву залежно від потреб використовувати #ifdef / #endif.

Зрозуміло, якщо «з першого акту на стіні висить рушниця» моделі «використання секцій», то тут стрілятиме саме вона.
Читати далі — автоматизація реєстрації модулів за допомогою секцій… » » »

Attached Files:

  • zip GCC sections usage demo

    avr-gcc, atmega168. Code::Blocks project with external makefile (can be used with any IDE or without IDE)

Секції .init в avr-gcc

Для програм, написаних мовою С чи С++, часто буває зручно, а іноді просто необхідно проініціалізувати якісь ресурси мікроконтролера до початку роботи фунцкії main() (для C++ — до початку роботи конструкторів статичних об’єктів). В багатьох системах програмування для цього використовується функція на зразок low_level_init(), яка викликається з С-шного «пускача» (start-up module, в більшості випадків пишеться на асембелрі) і має бути визначеною десь в проекті. Якщо такої функції нема, тобто програміст її не написав у даному проекті, то з бібліотеки береться коротка «затичка» (stub), яка просто нічого не робить.

У avr-gcc це зроблено дещо по-іншому. Використовуються можливості системи програмування по обробці секцій (сегментів, sections, segments) програми. Вашій увазі пропонується невеличкий приклад з детальним описом.
Continue reading ‘Секції .init в avr-gcc’ »

Attached Files:

[flagcounter image]