extern “C”

Інформація, яку видає OpenOCD при звичайному завантаженні програми у flash-пам’ять мікроконтролера, деколи може допомогти так, як наче це був запущений зневаджувач.

Переписую на свій смак шматки, які вже працювали зі стандартною бібліотекою від NXP. При чергових змінах програми вона начисто перестає працювати. Знаходжу дрібну помилку (замість змінної часу повертається константа періоду), виправляю, перешиваю…

Знову висить.

»»» І тут помічаю, що OpenOCD сповістив мене…

Attached Files:

  • h lpc17xx_handlers

    lpc17xx handler prototypes for C/C++ programs (with extern "C" for C++)

Знову LPC17xx та Peripheral Driver Library

Продовжую набігами знайомитися з мікроконтролерами LPC17xx.
При цьому продовжую лізти на кактус: «щоби швидше», підключаю файли зі стандартної периферійної бібліотеки від NXP. І в черговий раз отримую помилку компіляції. На цей раз — з глибин <sys /reent.h>, який включається до <stdio .h>, якого, своєю чергою, потягнув debug_frmwrk.c з LPC1700 Peripheral Driver Library:

--- compiling ./src/NXP/LPC17xx/Drivers/source/debug_frmwrk.c...
In file included from /opt/klen/arm-kgp-eabi/201109/bin/../lib/gcc/arm-kgp-eabi/
                 4.7.0/../../../../arm-kgp-eabi/include/stdio.h:45:0,
        from ./src/NXP/LPC17xx/Drivers/source/debug_frmwrk.c:41:
/opt/klen/arm-kgp-eabi/201109/bin/../lib/gcc/arm-kgp-eabi/4.7.0/../../../
    ../arm-kgp-eabi/include/sys/reent.h:469:10: error: #if без виразу

Причому що в збірці arm-kgp-eabi від Klen, що в CodeSourcery — те саме (the same, як сказали б англомовні). Тільки номери рядків відрізняються та CodeSourcery, на відміну від Klen-ового пакету, зібрано без підтримки локалізацій і він каже #if with no expression а не #if без виразу.

Лізу дивитися sys/reent.h »»» І що ж я бачу? …

LPC175x and LPC176x Standard Peripheral Firmware Driver Library

Взяв я трохи поколупати платку з мікроконтролером LPC1768.
Спробував використати стандартну бібліотеку lpc17xx cmsis driver library, щоб трохи менше думати. Звісно, документацію на мікроконтролер все одно читати треба. Але здалося простіше викликати функцію для налаштування потрібної периферії, передавши їй кілька парметрів, ніж самому уважно комбінувати ті параметри в кілька регістрів. Та ще й, можливо, про порядок запису треба буде думати.

З часів інтелівського ApBUILDER-а — програми для генерації коду ініціалізації для MCS-51, MCS-196, … — я всю роботу з периферією завжди робив вручну. Тобто, я і до цього робив вручну, а тим ApBUILDER-ом спробував і відмовився. І знову лише вручну. Читаєш собі документацію на потрібний модуль та й потихеньку пишеш всі ці маски/зсуви. Константи для них у файлах від компілятора чи виробника мікроконтролерів є — і то добре.
А тут — на тобі… Вирішив полінуватися…

»»» Читати про покарання за лінощі

Attached Files:

Використання секцій в 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]