субота, 6 квітня 2013 р.

CoIDE 1.7.1

З часу попередньої статті китайці випустили декілька оновлень свого славного CoIDE. Сказати, стала оболонка кращою чи гіршою, мені складно -- там такий мікс дрібних приємностей і дрібних косяків... :-) Але трішки по іншому стало точно. 

Спробую розповісти, як робота із CoIDE виглядає зараз. Версія, яку розглядав раніше -- 1.5.1, поточна -- 1.7.1. Багато відсилатимуся до попередньої статті -- щоб не повторюватися, хоча дрібні шматки просто цитуватиму. Розглядатимемо на прикладі плати STM32VLDiscovey. Тут, власне, сидить головне розчарування від останніх релізів. Ні підтримки STM32F3 (включаючи STM32F3Discovery), ні підтримки Stellaris (включаючи Stellaris Launchpad), поки так і не з'явилося. В принципі, принаймні STM32F3, можна пробувати додати самому -- див. діалог на форумі, "STM32F3Discovery - Demo Project for CoIDE", але я поки не пробував. Декілька слів буде і про прикручування C++.

[Update від листопаду 2015 року. Частина, присвячена С (Newlib) та С++ runtime містить багато неточностей та помилок. Існує більш детальний та точний варіант: "Стандартна бібліотека C та SemiHosting (на прикладі STM32 і CoIDE)" і "C++ із ARM GCC + STM32 (+ CoIDE)", відповідно. Крім того, див. пост про нову версію CoIDE, 2.0.3 beta: "CoIDE 2".


Список оновлень див. тут. Відмічу декілька пунктів:
  • В 1.6.0 з'явилася підтримка макетних плат (development board). Поки не користувався, але звучить цікаво. 
  • Після 1.6.2 оболонка почала показувати повний шлях до відкритих файлів (іноді дуже актуально).
  • 1.7.1 почала відновлювати "view" -- відкриті файли і т.д., при відкритті проекту.
  • Та ж 1.7.1 додала підтримку LTO (Link Time Optimization), див. їх форум. Звичайно, тільки для gcc 4.7+. Стверджують, що розмір прошивки із ввімкненим LTO стає помітно меншим, аж до 9%.
Крім того, звичайно, згадується багато модифікацій (автори так скромно і кажуть -- "Modified" а не "покращено" :), та розширень, частину із яких розглянемо нижче.

Дуже важлива зміна, що відбулася десь в процесі -- тепер оболонка не прописує всіх шляхів абсолютно! І хоча абсолютні шляхи все ще трапляються в її робочих файлах, (наприклад, dependencies.xml і history.xml в Debug|Release/obj), тепер проекти можна спокійно переміщати, копіювати і т.д.

Скачати можна тут, як напряму (що вимагає реєстрації, котра, правда, ненапряжна), або за допомогою CoCenter. Оболонка не включає компілятора, його слід скачати окремо. Я зупинився на ARM GCC 4.7, доступним за наступною адресою. Для простоти можна скачати gcc-arm-none-eabi-4_7-2013q1-20130313-win32.zip, розархівувати кудись (в шляху не повинно бути пробілів -- воно може і працюватиме, якщо вони будуть, але це -- прямий і безпосередній шлях до створення самому собі безглуздих проблем), і вказати оболонці, де його шукати.
Зверніть увагу, нарешті підказують, що значить "Toolchain Path", а то кожен раз загадка -- воно хоче корінь, папку bin чи ще щось?
Зауваження: "win32" чудово працюватиме і під 64-бітними системами. Версії ARM GCC є і для Linux, само собою, але CoIDE поки Windows-only. Деякі додаткові деталі про CoCenter і компілятори див. розділ "Інсталяція" попереднього поста.

Створення проекту та робота з ним

  1. На першому етапі з часу 1.5.1 особливих змін не відбулося. "Project --> "New Project". Питається ім'я проекту, яке буде іменем його директорії, тому варто вибирати без пробілів, і обмежитися лише латинськими літерами, цифрами, дефісом та підкресленням. Пропонує помістити його в папку <CoIDE_root>/CoIDE/workspace. Звичайно, краще вибрати більш адекватне місце, групуючи проекти по завданням, що вирішуються, інакше скоро в "workspace" збереться цілий смітник між собою не пов'язаних проектів. ". Увага: піддиректорія для проекту автоматично не створюється, всі файли та директорії проекту навалом впадуть за вказаним в "Project Path" шляхом.
  1. Далі невелика зміна --- можна вибрати проект для мікроконтролера (чіпу) чи для плати (board). Вибравши, слід натиснути Next (кого як, а мене такі гарні, округлі, кнопки збивають з пантелику). Зупинимося на "Chip".
  1. Наступний крок не змінився. Вибирається фірма, сімейство чіпів, конкретний пристрій. Показує підказку -- параметри пристрою: доступна пам'ять, наявна периферія, тощо та містить посилання на документацію. Лише після цього оболонка створить якісь файли.

  1. На цей момент проект міститиме лише два файли, main.c і SampleProject1.coproj  (можуть також додатися SampleProject1.cogui і SampleProject1.comarker, але це не суттєво). Далі, як і раніше, можна вибрати компоненти, з якими проект працюватиме. Зацитую: "Поміж них [цих компонент] CMSIS, частини SPL для роботи із різноманітною периферією, бібліотека периферії від CooCox, CoOS, semihosting, стандартна C-бібліотека на базі Newlib, (також див. короткий опис з прикладами реалізації низькорівневих системних функцій на OSDev), користувацькі компоненти, тощо. Залежності між компонентами задовольняються автоматично. Наприклад, якщо вибрати "GPIO", в проект додадуться також "CMSIS core", "CMSIS boot" (про цю компоненту див. нижче), "RCC". Короткий опис компонент виводиться в панелі справа. Доступні в репозиторії ще дві цікаві вкладки - "Drivers", з драйверами для зовнішніх пристроїв та "Others" з різними корисними компонентами, типу драйвера файлової системи FAT. [На жаль, вони, в основному, розраховані на роботу разом із бібліотекою периферії від CooCox -- COX.] Увага, компоненти можуть затерти ваші файли в проекті! Особливо цим грішать всілякі шаблони від сторонніх розробників (main.c затерти - тільки так). Так само, видалення компоненти із проекту без попередження стирає її файли, навіть якщо вони були змінені. " Зауважу, що файли вибраних копіюються в директорію проекту.

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

Далі знову зацитую попередній пост: "Компіляція: Project --> Build, іконка в тулбарі, або просто F7. Прошивка в контролер: "Flash"-->"Program download". Якщо програматор підтримує (ST-Link на STM32VLDiscovery підтримує), працює і відладка -- breakpoint-и, покрокове виконання, перегляд змінних, тощо. Єдине, потрібно вказати, з яким програматором працювати: "Debug" --> "Debug configuration" "View" -> "Configuration" -> "Debugger". Список підтримуваних програматорів великий. Якщо працювати із описаною в попередньому пості STM32VLDiscovery, слід вибрати ST-Link, Port: SWD, Max Clock -- 2M. Якщо планується використання semihosting, тут же можна його дозволити: "Semihosting Enable". На жаль, це налаштування не може бути глобальним -- потрібно повторювати у кожному проекті. Завжди можна повернутися до репозиторію і додати/прибрати компоненти. Звичайно, якщо забрати компоненти, які використовуються у вашому коді, він перестане компілюватися або лінкуватися." З часу написання цього, виявилося, що оболонка іноді забуває про Semihosting. Видно це по тому, що він без якихось поважних причин просто перестає працювати. Доводиться відкривати конфігурацію і вмикати знову. Сподіваюся, в 1.7.1 це нарешті пофіксили, але точно ще не знаю. Увага: конфігурація доступна в пункті меню "View": View -> Configuration. Всі опції тепер зібрані там, на відміну від того, як було в старіших версіях.

Організація проекту


Відображення структури проекту трохи змінилося. З пунктів 1-9, описаних раніше для 1.5.1, вижили 1, 2, 3, 5, 8. На загал -- перестали виводитися різноманітні службові файли.  Залишилися, цитуючи:
1 -- компоненти, які використовуються. Зверніть увагу на приклади до них. Клікнувши на компоненті можна їх проглянути.
2 -- файли CMSIS, додані компонентою "CMSIS core". Нагадую, для простоти, більшість бібліотек для контролерів постачаються у вигляді вихідних текстів і компілюються разом із кодом програми. Зокрема, CoIDE автоматично копіює їх в папку проекту.

5 -- файли SPL.

Група 3, створена компонентою CMSIS_boot, хитріша -- у ній зібрано трішки різнорідні файли. stm32f10x.h, system_stm32f10x.h, system_stm32f10x.c -- частина CMSIS, що стосується вибраного нами контролера.
system_conf.h -- конфігурація для CMSIS. Зокрема, містить заготовку для ввімкнення перевірки параметрів виклику функцій:

/* Uncomment the line below to expanse the "assert_param" macro  in the Standard Peripheral Library drivers code */
  /* #define USE_FULL_ASSERT    1 */

Увага! Опис дуже важливого файлу, startup_stm32f10x_md_vl.c, копіювати не став -- він займає помітну частину попереднього поста. Див. там, починаючи зі слів: "Нарешті, найбільш важливий із автоматично створених файлів: startup_stm32f10x_md_vl.c"  Нижче буде кілька слів про те, що в ньому змінилося.

8 -- найпростіше, власне файл нашої програми. 

На загал так справді зручніше! Єдиний виняток -- файл link.ld тепер автоматично не створюється, і добратися до нього трішки складніше. Відкриваємо вкладку "Link" ("View" -> "Configuration" -> 'Link"):
Щоб цей файл було створено, або/і можна було його редагувати, слід вимкнути "Use Memory Layout from Memory Windows":
Натиснувши Edit, можна переглядати та модифікувати вміст цього файлу, скрипта для лінкера. Що це таке і навіщо потрібно, копіювати сюди не буду -- це детально описано в часто згадуваному попередньому пості, починаючи зі слів: "Це скрипти лінкера" (опис відсутніх зараз груп 8 і 9). Зауважу тільки, що файл не менш важливий, ніж startup_stm32f10x_md_vl.c!

УВАГА!  На жаль, станом на 1.7.1, згенерований файл буде некоректним! Адреси різних пам'яті будуть прописані невірно. Симптомом цього буде те, що програма прошивки запускатиметься, але просто мовчки завершуватиметься, при цьому плата лише пару раз мигатиме діодом "зв'язку із компом". Слід модифікувати файл, згідно значень, які видно в "Memory Areas" вище -- їх оболонка встановлює правильно:

/* Internal Memory Map*/
MEMORY
{
 rom (rx)  : ORIGIN = 0x08000000, LENGTH = 0x00020000
 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00002000
}

_eram = 0x20000000 + 0x00002000;

Зверніть також увагу на опцію "Enable LTO", підкреслену блакитним на поза-попередньому рисунку. Це, власне,  Link Time Optimization. Із її ввімкненням пов'язані основні зміни у вмісті startup_stm32f10x_md_vl.c. Справа в тому, що є ряд сутностей, необхідних прошивці, які лінкер, під час міжоб'єктної оптимізації, побачивши, що вони не використовуються напряму, просто викине. (Детальніше див. на їх форумі). Це, в першу чергу, обробники переривань та Reset_Handler
  • Обробники переривань слід оголосити з атрибутами: __attribute__ ((used, section(".isr_vector"))),
  • Reset_Handler -- з  _attribute__((used)).
При ввімкненні LTO, не зустрівши цих модифікацій, (наприклад, імпортовано проект, створений попередніми версіями), IDE перепитується:
Правда, механізм детектування не дуже надійний, часто переконує, що їх немає, хоча все ОК. Але якщо йому підтвердити "I have modified", вірить і більше не набридає.

Виглядатимуть ці модифікації якось так:

/* System exception vector handler */
__attribute__ ((used))
void WEAK  Reset_Handler(void);
void WEAK  NMI_Handler(void);
void WEAK  HardFault_Handler(void);

/* --------- SKIPPED --------- */

__attribute__ ((used,section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{       
  /*----------Core Exceptions-------------------------------------------------*/
  (void *)&pulStack[STACK_SIZE],     /*!< The initial stack pointer         */
  Reset_Handler,                /*!< Reset Handler                            */
  NMI_Handler,                  /*!< NMI Handler                              */
  HardFault_Handler,            /*!< Hard Fault Handler                       */
/* --------- SKIPPED --------- */
}
Готовий проект-шаблон із можна скачати тут. (Містить виправлений core_cm3.c, див. наступний пост).

Приклад програми


Для повноти ілюстрації, простенька програма, що мигає світлодіодами STM32VLDiscovery.

#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>


void Delay(void) {
volatile uint32_t i;
    for (i=0; i != 0x80000; i++);
}

int main(void) {
    GPIO_InitTypeDef PORT;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
    PORT.GPIO_Pin = (GPIO_Pin_9 | GPIO_Pin_8);
    PORT.GPIO_Mode = GPIO_Mode_Out_PP;
    PORT.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init( GPIOC , &PORT);
    for(;;) {
        GPIOC->ODR |= (GPIO_Pin_9 | GPIO_Pin_8);
        Delay();
        GPIOC->ODR &= ~(GPIO_Pin_9 | GPIO_Pin_8);
        Delay();
    }
    return 0;
};

Програма знайдена десь на просторах Інтернету, але сподіваюся мені пробачать невказання копірайту для такого простого коду. :-)


Прикручування С++

Офіційної підтримки все ще немає, доводиться викручуватися. 

В загальному, суттєвих змін від попереднього разу немає (див. за посиланням, у розділ "Використання С++"). Декілька слів про зміни.

build.xml зник, але *.cpp-файли підхоплюються нормально, і хоча компілюється gcc, останній, побачивши таке розширення, правильно вибирає мову.

Перейменовування засобами IDE працює мутно, тому найпростіший шлях із main.c зробити main.cpp -- видалити з проекту (файл на диску залишиться), перейменувати та додати назад.

В файлах CMSIS з'явилося трохи "extern "C"", тому потреба додавати при включенні зменшилася, але особливо покладатися не це не варто. Та й всілякі обробники переривань слід так обгортати, щоб не втручалося Name Mangling.

Готовий проект-шаблон із підтримкою C++ можна скачати тут. (Містить виправлений core_cm3.c, див. наступний пост).


Підсумок

 Коротко про найважливіші зміни:
  • Додано підтримку LTO-оптимізації. 
  • Проекти перестали бути прив'язаними до абсолютних шляхів.
  • Спростилася структура відображення файлів проекту. 
  • Змінився спосіб редагування скрипта лінкера, *link.ld. По замовчуванню файл не генерується, створюється після запиту, але з помилковою картою пам'яті -- слід виправляти вручну (див. вище).
  • Перетасовано і впорядковано різноманітні кнопочки та опції
На загал, враження від змін проекту -- позитивні. Є ряд неприємних багів, прогрес не те щоб швидкий, але автори все рівно -- молодці!

Немає коментарів:

Дописати коментар