Мікроконтролер своїми руками

Намагаючись освоїти контролери і вже володіючи навичками програмування ПЛІС, мені прийшла в голову погана думка. Прийшла, постукала і увійшла. Усім тим, до кого приходять погані думки, і кому цікаво як з цим явищем справляються інші, присвячується.
 
Виникла ідея намалювати свій контролер, не обмежений за кількістю периферії, ОЗУ та іншим параметрам, окрім ємності ПЛІС. Скажімо контролер містить 5 UARTов, а конче потрібен шостий, доведеться викручуватися. А навіщо, якщо можна просто клацнути мишкою і додати необхідну? Або навпаки, задачка добре вирішується на п'яти контролерах з розрядністю 5, 32, 20, 32 і 20 з непередбачуваним кількістю ліній зв'язку між ними. Шкода використовувати п'ять 32 розрядників, ресурс завжди шкода, а суміщати дві підзадачі на одне ядро ​​- некрасиво, чи що.
 
Час відгуку на переривання в контроллерах досить велике. Так, контролер переривань моніторить входи (чомусь обмежені за кількістю) незалежно від ядра. Але перш ніж почати виконання коду програми з обробки переривання, скажімо, читати порт, потрібно зберегти регістри загального призначення, а потім їх ще й відновити. А це не один такт на порожнє з точки зору логіки програми переписування регістрів в стек і повернення цих же значень назад. Воно звичайно вписується в поняття реального часу, але ж можна ж робити це миттєво: виконувався код з низьким пріоритетом, на наступному ж такті через різку необхідності починає виконаються високопріоритетні переривання по таймеру, а через такт виконується код з обробки зовнішнього потоку даних, бо там зовсім все швидко треба.
 
Звичайно, всі ці проблеми надумані і вирішуються і легко і просто. Але погана думка не шукає таких рішень, вона просто блукає в переповненому просторі свідомості і підштовхує зробити нестандарт. А, якщо у молодого інженера відпустку, то прости дружина і діти, але тато не «знову сидить за комп'ютером», а професійно зростає. Тим більше іноді хочеться виконувати не кимось придумані задачки, а свої, повністю свої.
 
 image
 
 Рис. 1. Таймери. Додавай скільки хочеш. Зверніть увагу на граматичну помилку. Соромно, але не хочеться Builder встановлювати для перекомпіляції.
 
Дозвольте представити вам контролер, архітектура якого, не те щоб відрізняється від всіх інших, скоріше вона не прийнята на озброєння. Вже давно забутий список прочитаної перед початком робіт літератури, використані думки багатьох людей з різних комп'ютерних епох, вибачте мене мої забуті вчителя. Зате вам не доведеться від мене відхрещуватися. Та й грошей це не пронесло, тому і ділитися нічим.
 
Відразу скажу, що контролер відбувся, прошитий в Спартан всіх поколінь і успішно трудиться на просторах СНД і одній країні Прибалтики. Зараз би багато що було зроблено по іншому, але будь-які зміни мені вже ліниві і, що сталося, те сталося. А трапилося ось що.
 
 - Розрядність контролера від 1 до 32, із знаком або без оного. (Не пам'ятаю перевіряв я роботу на малих Розрядному). Використовується додатковий код.
 - Кількість портів введення / виводу ні чим не обмежена, розрядність обмежена розрядністю ядра.
 - Кількість таймерів так само не обмежена. На кожен таймер можна встановити свій оброблювач переривання.
 - Оброблювач переривань з нескінченною кількістю входів, кожен вхід має пріоритет від 0 до 99 (обмеження з причини «і так великого числа»). Можливість забороняти всі переривання або низькопріоритетні тільки.
 - Кількість послідовних портів типу UART необмежено, розрядність обмежена розрядністю ядра.
 - Дільник частоти зроблений погано і неправильно, але справно видає будь-яку частоту для будь периферії або просто назовні контролера.
 - Співпроцесор. Про нього нижче.
 
Тобто ми маємо контролер, що підтримує основні операції арифметики та іншого зміни бітів в словах (плюс, мінус, зсув, побітова логіка ...). Так само він звертається до внутрішньої пам'яті і зберігає код програми так само всередині себе. Пам'ять використовується блокова, саме вона є платформозавісімой і в налаштуваннях програми обов'язково потрібно вказати яка мікросхема буде носієм контролера. Всі операції по будь-якому напряму дій виконуються за один такт, це може і не завжди добре, але спростило проектування архітектури. Винятком є ​​цілочисельний дільник, функції якого реалізовані в сопроцессорами, поділ виконується повільно, але впевнено. Алгоритм ділення був обраний найпростіший — побітно.
 
Хотілося б розповісти про код команд, але сам не пам'ятаю з чого він складається. Виходячи з принципу «не використовувати те, що не використовується» навіть довга коду команди є величиною не константної, тим більше його вміст. Скажімо, якщо в компільованої програмі зустрічається 14 команд, то кожна команда кодується 4 бітами, якщо використовується 18 команд — виділяється п'ятий біт. Плюс до кожної команди додається біт довжини, якщо він дорівнює 0, то команда одинарна, якщо 1 — подвійна, або навпаки, це не важливо. Подвійна команда потрібна для операцій, що містять адресу ОЗУ або ПЗУ. Додамо до цього те, що шини адреси так само мають не константні довжини, і отримаємо повний бардак в коді команд, розглядати його ніяким дизассемблером сенсу немає, як власне і асемблер в цьому контролері.
 
Форт — ось та мова, який дозволив мені реалізувати ці дивні ідеї. Форт простий і низькорівневий. Писати компілятор даної мови — одне задоволення. Ну, звичайно, всі конструкції мови не підтримуються, тільки основні з пересилання даних і їх зміну.
 
 image
 Рис. 2. Керівництво досить скромне. Нескромна так і не написано.
 
 image
 Рис. 3. Друга частина керівництва. Не знаю чому, але вікно розширити не можна. Є ще й третя частина, але вже зовсім нудна.
 
І, природно, ми маємо стековий контролер. Тобто Форт функціонує у своїй природно середовищі — в стеку, в апаратній стеку, а не повільному програмному. «Все за такт!» — Другий девіз проекту. Апаратний стек дозволив при переході у функції або виклику переривання відразу приступати до виконання команд обробки даних, без необхідності зберігати контент перерваного процесу. «Нові» дані просто поміщаються в стек зверху, «старі» йде у глибину і чудово там зберігаються. Потім «нові» дані, взявши участь у різних операціях, благополучно переходять в ОЗУ або інші місця, а «старі» виштовхуються на вершину. При поверненні в перерваний ділянку коду ніхто нічого не помітить. Адреса перерваного коду зберігається в іншому стеку, і максимальна кількість перерваних процесів залежить тільки ото глибини стек повернень. Це величина налаштовується при компіляції, хоч би й «дуже велике число». Параметри в функції передаються так само через стек.
 
Stackcpu — саме так і називається контролер, чомусь латиницею, хоча писати код можна і кирилицею. Що я і роблю, наведу приклад функції «меняем_біти_в_слове»:
 
 
:меняем_биты_в_слове 
	читаем_из_нужного_порта, 
	меняем_прочитанное_из_нужного_порта, 
	записываем_в_требуемую_ячейку_памяти;

 
Де: «чітаем_із_нужного_порта», «меняем_прочитанное_из_нужного_порта», «записываем_в_требуемую_ячейку_памяти» — функції, які виконують певні дії.
 
Ну не псих чи я чи красиво? Наведу ще докази, програма управління світлофором:
 
 
\\main 
BEGIN
	зелёный потушить, жёлтый потушить, красный зажечь.
	пятьдесят секунд ждём…
	зелёный потушить, жёлтый зажечь, красный потушить.
	четыре секунды ждём…
	зелёный зажечь, жёлтый потушить, красный потушить.
	сорок секунд ждём…
	зелёный уменьшить_яркость_до_нуля, жёлтый гори, а красный не_гори.
	четыре секунды ждём…
0 UNTIL		\бесконечный цикл

 
Ну що, псих красиво? Третій принцип проекту: «Літературна мова в управління електронікою!» Хоча, як показала практика, писати так програми досить утомливо. Для знавців Форт повідомлю, що крапку мій компілятор сприймає як роздільник, і кому теж. Звичайно, краще використовувати мову С, але компілятор С мені не по зубах, а використовувати сторонні компілятори архітектура не дозволяє.
 
 image
 Рис. 4. Середу розробки із звітом компілятора і лінковщік.
 
Скільки ємності FPGA займає контролер? Та хто ж його знає. Все залежить від розрядності числа, обраної периферії, ще чогось, і від тексту програми. У контролері НЕ БУДЕ помножувача, якщо він не зустрічається в програмному коді, або буде дільника, якщо його не використовує програміст. Під програмістом я маю на увазі себе, так як інших програмістів даного контролера не існує (принцип «не використовувати тим, хто не використовує»). За блокової пам'яті для ОЗУ даних і ПЗУ команд: мінімум два блоки, максимум вся блокова пам'ять кристала.
 
Максимальна частота роботи вираховується тільки досвідченим шляхом, під конкретну архітектуру. Один з моїх 24 розрядних контролерів не працював на частоті 48 Mhz в Spartan2, на частоті 40Mhz запрацював. У Spartan6 на сотні Mhz працював 32 розрядний. А може і на парі сотень запрацює, нічого в ньому такого складного немає.
 
 image
 Рис. 5. Ось такий код побачить процесор. Зверніть увагу, одна команда FORTH — це одна команда ядра процесора — один системний такт.
 
Перший PS: згадаю одну можливість співпроцесора — фільтр. Звичайний БИХ фільтр. Але ось, що незвичайного в ньому, так це те, що він використовує плаваючу точку. Не те що б в цьому був якийсь сенс, просто прочитав якусь книжку про форму представлення чисел, і вирішив: дурниця цікава ця ваша плаваюча точка, зробимо.
 
 image
 Рис. 6. Моделювання результатів роботи фільтра. Вираховується логіка коду VHDL з точністю до бітікі.
 
Так само були плани по перетворення проекту в систему на кристалі: додавання різних, писаних на VHDL блоків у периферію контролера. І начебто не так вже й складно, але запал вичерпався. Погані думки мене покинули, і бродять десь між програмістами і електронщиками. І звуть їх тепер стартапи.
Так що, якщо до вас хтось прийде і представиться стартапів, подумайте, а чи не ховається під ним небудь Времяубіватель.
І ще одне PS: З іншого боку, за час роботи над проектом Stackcpu я непогано підучив три дві мови програмування:
1. FORTH, точніше якесь його підмножина, необхідне для перевірки працездатності контролера.
2. С + +, на чистому С було б важко написати середовище розробки і компілятор.
 3. VHDL, саме букви цієї мови і є контролер.
 
Зрозуміло, що розповідати можна довго, але на цьому вистачить. Піду займатися чужими ідеями, але з моєї реалізацією!
Власне контролер (половина мегабайта): cloud.mail.ru/public/6cae734a85cc/StackCPU.rar

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.