Wiele projektów opiera się na założeniu optymalizacji pod jedno, konkretnie zdefiniowane zadanie. Dobierane są jednotorowe rozwiązania mające na celu eliminację kosztów, niestety za cenę utrudnionego rozwoju i braku elastyczności. Niekiedy potrzebne jest zupełnie odmienne podejście i zdecydowanie się na wszechstronność, która może okazać się kluczem do przeniesienia procesu rozwoju na zupełnie nowy poziom.

IDO Electronics potrafi postawić na uniwersalność fundamentalnych etapów produkowanych urządzeń. Głównym założeniem jest wypracowanie jednolitego systemu wdrażania kolejnych narzędzi stanowiących bazę dla wielu różnych rozwiązań. Przestrzeganie tej sprawdzonej metodyki to diametralne zwiększenie tempa realizacji oraz zapewnienie stabilności projektu znajdującego się w dowolnej fazie rozwoju.

Hardware

Baza całej rodziny urządzeń elektronicznych zostaje przez nas przygotowana pod zamienny montaż poszczególnych podzespołów. W miejsce jednej fizycznej realizacji interfejsu można zamontować inny, zależnie od pojawiających się potrzeb. Wystarczy dokonać prostej zmiany w dokumentacji produkcyjnej (BOM) i wytworzyć wybrany wariant sprzętowy.

Częścią wspólną reprezentującą naszą linię produktów jest procesor NXP i.MX6 bazujący na rdzeniu Arm Cortex®-A7. Jest to układ scalony idealny do realizacji projektów multimedialnych o szerokiej funkcjonalności. Dzięki zintegrowanej obsłudze wielu różnych interfejsów pozwala budować rodzinę urządzeń bez potrzeby ponownego projektowania ich od podstaw. W zależności od zastosowania możemy wybrać wariant procesora realizujący określony zbiór zadań spośród szeregu dostępnych możliwości.

  • Pamięci: LP DDR2, DDR3, DDR3L, NAND flash, NOR flash, eMMC.
  • Interfejsy peryferiów: SPI, Quad SPI, I2C, PWM, ADC/DAC, CAN, USB OTG, UART, pośrednio RS232/485.
  • Interfejsy sieciowe: Ethernet, WLAN, Bluetooth™, GPS.
  • Zintegrowana obsługa: wyświetlaczy, czujników, przetworników obrazu.
A view of electronic device using i.MX6

 

U-Boot

Skrót U-Boot oznacza Universal Boot Loader. Już sama nazwa tego oprogramowania wskazuje na jego elastyczność. Pozwala wczytać jądro systemu z powszechnie wykorzystywanych nośników danych, np. SATA, flash, pendrive USB czy karta SD. Jest dostosowany do obsługi różnych systemów plików. Dodatkowo nasz bootloader wzbogacono o możliwość wgrania obrazu systemu w trybie sieciowym OTA – TFTP/NFS. W ten sam sposób przeprowadzamy automatyczne aktualizacje U-Boota urządzeń z dostępem do internetu.

Przytrzymanie przycisku umieszczonego na płytce lub wciśnięcie dowolnego klawisza podczas uruchamiania urządzenia przerywa automatyczny proces bootowania. Komunikacja z bootloaderem wystawiana jest na port szeregowy, umożliwiając jego dalszą obsługę. Podstawowa wymiana danych zachodzi przy wykorzystaniu domyślnej konfiguracji, co oznacza przepustowość na poziomie 115200 bit/s, 8 bitów danych, brak kontroli przepływu i bitu parzystości. U-boot obsługuje urządzenia wejściowe podpięte pod port USB oraz ma zaimplementowane wsparcie wyświetlaczy i monitorów, więc nie ma konieczności zamieszczania gotowych skryptów wykonawczych na nośniku z obrazem czy podłączania dodatkowego komputera umożliwiającego komunikację.

Co ważne, bootloader działa niezależnie od wersji hardware’u, którą obsługuje. Dodatkowo realizuje on funkcję rozpoznania konfiguracji sprzętu w danej odmianie produktu. Procesor komunikuje się z poszczególnymi układami scalonymi, tworząc tym samym punkt odniesienia kompatybilności obrazu systemu przeznaczonego do załadowania.

Kernel

Jądro systemu wymaga odpowiedniego skonfigurowania pod konkretne rozwiązanie sprzętowe. Aby to osiągnąć, tworzymy strukturę Device Tree, czyli zestawienie danych wykorzystywanych do opisu konfiguracji hardware’u. Dzięki zdefiniowaniu peryferiów potrzebnych do prawidłowej pracy systemu w jego własnych zasobach zapewniamy uniwersalność niskopoziomowego oprogramowania bootloadera.

Dalszy proces konfiguracji Kernela polega na dodaniu sterowników sprzętowych kompilowanych najczęściej jako moduły jądra. Dokonuje się również optymalizacji wielu procesów pod zasoby konkretnej jednostki obliczeniowej. Przeprowadzamy konfigurację obsługi sieci, portów, peryferiów i systemu plików kontrolującego przepływ i strukturę danych. Kernel to główna część systemu operacyjnego odpowiedzialna za dostarczenie zasobów wszystkim wyższym procesom. Ze względu na jego przeznaczenie, zachodzą w nim najważniejsze instrukcje wymagające dostępu do wszystkich obszarów pamięci i poleceń. Odpowiednia konfiguracja zapewnia stabilność całego urządzenia. Linux system mascotte - a penguin named Tux

Do procesu budowania środowiska systemu wykorzystujemy i rozwijamy elastyczne narzędzia tworzące nasz toolchain. W zależności od potrzeb projektowych modyfikujemy biblioteki, cross-compiler czy debugger z osobna, a czasem decydujemy się na gotowe kompleksowe rozwiązania typu Buildroot/Yocto. Rozważnie zorganizowana procedura konfiguracji Kernela pozwala nam na bardzo sprawne wdrażanie kolejnych projektów z tej samej rodziny urządzeń.

User space

Dzięki planowaniu uniwersalności już od samego początku projektowania hardware’u oraz zapewnieniu elastyczności procesu konfigurowania jądra systemu możemy zrealizować wiele nowych zadań przy minimalnym nakładzie dalszych prac. W zależności od finalnego przeznaczenia układu dobieramy odpowiednią dystrybucję systemu lub w razie potrzeby budujemy własną, dopasowaną do konkretnych zadań. W tym celu najczęściej wykorzystujemy dostępne zasoby projektu Yocto, dostarczającego zbiór narzędzi przeznaczonych do tworzenia customowych wersji systemu operacyjnego. Elastyczność pozostałych etapów projektu pozwala zapewnić kompatybilność z szerokim zbiorem dystrybucji.

Separacja obszarów jądra oraz user space zapewniają bezpieczeństwo i poprawę stabilności. W obszarze user space wykonywane są przede wszystkim procesy aplikacji. Dzięki temu eliminuje się bezpośredni wpływ błędów i defektów programów na pracę systemu operacyjnego. Również na tym etapie realizacji całego projektu zapewniamy uniwersalność naszych narzędzi. Tworzone przez nas aplikacje i wysokopoziomowe sterowniki są niezależne od docelowej dystrybucji i działają poprawnie na wielu różnych platformach.