wtorek, 9 maja 2017

ESP32 - Konfiguracja środowiska

Co będzie nam potrzebne

Najpierw trzeba sobie przygotować środowisko w którym będziemy pisać i kompilować oprogramowanie. Potrzebne nam będzie:

  • komputer PC z dowolnym systemem operacyjnym: Windows, Linux lub Mac. Ja będę używał Windowsa ale poza Toolchainem reszta powinna wyglądać identycznie na każdym systemie.
  • Toolchain do kompilacji aplikacji na ESP32. Toolchain to w uproszczeniu kross-kompilator i biblioteka standardowa C
  • ESP-IDF który zasadniczo zawiera API dla ESP32 i skrypty do obsługi Toolchaina
  • Edytor tekstowy  do pisania programów w C np. Eclipse, Notepad++, Visual Studio Code albo cokolwiek w czym lubisz pisać
  • no i oczywiście moduł ESP32. Ja będę używał ESP‑DevKitC, który ma na pokładzie ESP-WROOM-32, przyciski do resetu i wgrywania firmware'u, interfejs USB i wyprowadzone większość pinów. Przyda się również kabel microUSB.


Konfiguracja Toolchaina

Przygotować Toolchain można sobie na dwa sposoby. Najszybszym i najprostszym sposobem na rozpoczęcie pracy z ESP32 jest zainstalowanie gotowego Toolchaina. 
Zamiast pobierać binarny toolchain z witryny Espressif, możesz samodzielnie zbudować narzędzie.
Jeśli nie przychodzą Ci do głowy powody, dla których musisz go samodzielnie zbudować, prawdopodobnie lepiej jest trzymać się wersji binarnej. Oto niektóre z przyczyn, dla których warto skompilować toolchain ze źródła:
  • chcesz użyć innej wersji GCC (np. 7.1)
  • chcesz użyć jakiejś alternatywy dla newlib np. newlib-nano
  • jesteś ciekawy i / lub masz dużo wolnego czasu
  • nie masz zaufania do plików binarnych pobranych z Internetu
Ja wybieram opcję pierwszą i pobieram toolchain ze strony Espressif: https://dl.espressif.com/dl/esp32_win32_msys2_environment_and_toolchain-20170330.zip a następnie rozpakowuję na dysku D. Po rozpakowaniu w katalogu d:/msys32 możesz uruchomić terminal mingw32.exe.


Pobranie ESP-IDF

Oprócz toolchaina potrzebne są nam również biblioteki/API do ESP32. Są one udostępniane przez Espressif w repozytorum na githubie https://github.com/espressif/esp-idf . Użyjemy je i w tym celu tworzymy otwieramy terminal, tworzymy katalog w którym chcemy umieścić ESP-IDF, przechodzimy do niego i robimy klona za pomocą polecenie git clone:
mkdir ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git

Toolchain potrzebuje dostępu do ESP-IDF, bo w przeciwnym razie projekty nie będą się budować. Aby wskazać gdzie ESP-IDF się znajduje należy ustawić zmienną środowiskową IDF_PATH. Można to robić ręcznie po każdym uruchomieniu komputera lub na trwałe ustawić to w profilu użytkownika. W tym celu w katalogu D:\msys32\etc\profile.d tworzymy nowy skrypt o nazwie export_idf_path.sh w którym umieszczamy:

export IDF_PATH="D:/msys32/home/Mateusz/esp/esp-idf"

Oczywiście ścieżkę trzeba odpowiednio zmodyfikować, bo nie każdy ma na imię Mateusz ;)
Teraz zapisujemy plik, zamykamy konsolę i ponownie otwieramy. Aby sprawdzić czy wszystko poszło ok, wklepujemy: printenv IDF_PATH Powinniśmy dostać coś takiego:

Zasadniczo już teraz mamy przygotowane całe środowisko do zabawy z ESP32. Sprawdźmy teraz czy jesteśmy w stanie skompilować jakiś przykład i wgrać do ESP-DevKitC


Hello world!

Skopiujmy sobie przykład hello_world dostarczony przez Espresiff do nowego katalogu:

cd ~/esp/
cp -r $IDF_PATH/examples/get-started/hello_world .

Zauważ, że na końcu drugiego polecenia jest kropka, która oznacza: "skopiuj do katalogu w którym jestem".

Teraz potrzebna nam będzie informacja pod jakim numerem portu COM pojawia się moduł. Podłączamy więc moduł do komputera i sprawdzamy w menadżerze urządzeń:
W moim przypadku jest to port COM4 - trzeba tę informację zapamiętać.
Przejdźmy teraz do katalogu z projektem i go skonfigurujmy:

cd ~/esp/hello_world 
make menuconfig

Po chwili pokaże się menu znajome każdemu kto próbował kiedykolwiek zmienić coś w jądrze Linuksa. 

Przechodzimy do Serial flasher config > Default serial port i ustawiamy odpowiednio port, po czym wychodzimy i na końcu zapisujemy.

Teraz pozostało nam jedynie skompilować projekt i wgrać do urządzenia. Można to zrobić jednym poleceniem:

make flash

Jeśli wszystko pójdzie dobrze na końcu powinieneś zobaczyć coś takiego:

Przykład, który wgraliśmy wysyła Hello world! na konsolę i po chwili się resetuje. Możemy to podejrzeć w dowolnym terminalem np Putty (baudrate 115200) lub za pomocą wbudowanych narzędzi w ESP-IDF:

make monitor


No to tyle na dzisiaj. Następnym razem odpalimy GPIO, podłączymy LED i może jakiś switch i spróbujemy to oprogramować.

niedziela, 7 maja 2017

Wznawiam działalność bloga. Parę słów o ESP32

Minęły ponad 3 lata od ostatniego wpisu, więc zostały przekroczone wszelkie możliwe timeouty. Czas zatem na reaktywację. Impulsem do tego są dary, które zamówione od naszych żółtych braci właśnie dotarły.
Post udostępniony przez Mateusz Klatecki (@kltcki)
Jakiś czas temu zamówiłem moduły ESP-WROOM-32 oraz ESP-DevKitC żeby ułatwić sobie prototypowanie.
Cena modułów ESP-WROOM-32 jest stosunkowo niewielka ok. $5 jeśli zamówi się w Chinach.  W Polsce można znaleźć poniżej 30zł. A możliwości takiej kosteczki o rozmiarach 18x25 mm są naprawdę duże. Na pokładzie znajdziemy m.in. :

  • dwurdzeniowy MCU taktowany zegarem do 240MHz
  • Wi-Fi z wbudowaną anteną na PCB
  • Bluetooth 4.2 i BLE
  • 448 kB wewnętrznej pamięci Flash i 4 MB zewnętrznej
  • 520 kB wewnętrznej pamięci SRAM
  • wbudowany czujnik temperatury i Halla
  • RTC (potrzebny zewnętrzny kwarc)
  • i 32 wyprowadzenia GPIO ze sporą ilością interfejsów:
    • 3x UART
    • 3x SPI
    • 2x I2C 
    • 2x I2S
    • 2x 12-bitowy przetwornik ADC z sukcesywną aproksymacją
    • 2x 8-bitowy przetwornik DAC
    • Wyjścia PWM
    • Interfejs kart SD
Ważną rzeczą jest również to, że moduły mają certyfikaty: FCC, CE, IC, TELEC, SRRC & KCC, dzięki czemu wprowadzenie komercyjnego produktu na rynek będzie dużo łatwiejsze.

Pomysłów na wykorzystanie tego modułu mam w głowie kilka a proces poznawania modułu i odpalania poszczególnych peryferiów postanowiłem uwiecznić na blogu. So, stay tuned :)

piątek, 4 października 2013

Unikanie błędów programując w C - #3 Operacje bitowe na liczbach ze znakiem


Nie należy używać operacji bitowych ( &, |, ~, ^, << i >> ) na liczbach ze znakiem.

    // Nie rób tego ...
    int8_t  signed_data = -4;
    signed_data >>= 1;  // niekoniecznie -2


Standard C nie definiuje formatu danych liczb ze znakiem (na przykład U2 - uzupełnień do dwóch) i efekt niektórych operacji bitowych zależy od zastosowanej przez autora kompilatora implementacji zapisu takich liczb.

niedziela, 15 września 2013

Liczenie pola powierzchni wielokąta nieforemnego

Ostatnio musiałem napisać funkcję, która liczy pole powierzchni dowolnego wielokąta nieforemnego na podstawie współrzędnych wierzchołków. Straciłem trochę czasu na znalezienie prostego i uniwersalnego algorytmu, więc podzielę się moim znaleziskiem.

Jest to metoda analityczna obliczania pola powierzchni ze współrzędnych wzorami Gaussa.
Metoda analityczna bazuje na punktach o znanych współrzędnych. Do wyznaczenia pola powierzchni wzorami Gaussa musimy znać współrzędne wierzchołków wielokąta.

Pole P wieloboku obliczamy ze wzoru (wystarczy jeden - oba dają ten sam wynik) Gaussa:
 P = \frac{1}{2}\left| \sum\limits_{i=1}^n {X_i(Y_{i+1}-Y_{i-1}})\right| = \frac{1}{2}\left| \sum\limits_{i=1}^n {Y_i(X_{i-1}-X_{i+1}})\right|

gdzie: 
P - to wyliczane pole powierzchni
n -to liczba wierzchołków wielokąta
i = to współrzędne i-tego wierzchołka (wierzchołki numerowane są kolejno od 1 do n, poczynając od dowolnego z nich).

zakłada się przy tym, że:
X_0=X_n, Y_0=Y_n\;
X_{n+1}=X_1, Y_{n+1}=Y_1\;

Wartość bezwzględna we wzorze jest konieczna, gdyż przy zmianie kierunku numeracji wierzchołków wielokąta, zmienia się znak sum po prawej stronie. Ponadto sumy te mają zawsze przeciwne znaki.

I na koniec przykład implementacji w języku C:

#include <stdio.h>

typedef struct {
    int x;
    int y;
} point_t;

double liczPow(point_t *punkty, size_t N){
    size_t i;
    double pow;
    for (i=0;i<N;i++){
        if (i==0) {
            pow += punkty[i].x*(punkty[N-1].y-punkty[i+1].y);
        } else if (i==(N-1)){
            pow += punkty[i].x*(punkty[i-1].y-punkty[0].y);
        } else {
            pow += punkty[i].x*(punkty[i-1].y-punkty[i+1].y);
        }
    }

    if (pow < 0){
        pow = -pow;
    }

    pow /= 2;
    return pow;
}

int main(void) {
    point_t punkty[] = {
        {2,1},
        {5,2},
        {7,5},
        {4,7}
    };

    int N = sizeof(punkty)/sizeof(point_t);

    double powierzchnia = liczPow(punkty,N);

    printf("Powierzchnia: %f\n",powierzchnia);

    return 0;

}

Unikanie błędów programując w C - #2 Makra vs funkcje inline

Nie używaj makr parametryzowanych (makrodefinicji) jeśli można napisać funkcję inline, która wykona to samo zadanie.

//Nie rób tak:
#define MAX(A,B) ((A) > (B) ? (A) : (B))
// jeśli możesz zrobić tak:
inline int max(int a, int b)

Powód: Przy używaniu dyrektywy preprocesora #define jest dużo związanych z nią zagrożeń a w szczególności gdy są to makra parametryzowalne. Ważne jest odpowiednie (najczęściej w dużej ilości) użycie nawiasów (tak jak w przykładzie powyżej), ale nie wyeliminuje przypadkowego użycia inkrementacji jak np. MAX(i++,j++), która zwiększy zmienne o 2 zamiast o 1 jak to na pierwszy rzut oka wygląda.
Inne ryzyko nadużycia makr to porównanie liczb ze znakiem i bez (wspominałem o tym w poprzednim odcinku) lub jakiekolwiek porównania z liczbami zmiennoprzecinkowymi.

środa, 11 września 2013

Unikanie błędów programując w C - #1 liczby całkowite ze znakiem i bez

Postanowiłem napisać cykl krótkich artykułów (a właściwie porad) dla osób, które zaczynają programować systemy wbudowane w języku C. Skłonił mnie do tego sposób w jaki piszą studenci, którzy odbywają praktyki (lub dorabiają sobie) u nas w firmie. Ich kod jest mało czytelny, zajmuje dużo miejsca po skompilowaniu i zawiera dużo błędów, które nie ujawniają się od razu ale dopiero np. po włączeniu optymalizacji, dopisaniu kolejnego fragmentu kodu lub w losowych momentach.

Na pierwszy ogień idą liczby całkowite ze znakiem i bez.

Liczby całkowite ze znakiem nie powinny być używane z liczbami całkowitymi bez znaku w porównaniach lub innych wyrażeniach.

//Nie rób tego...
uint8_t a = 6u;
int8_t b = -9;

if (a + b < 4) {
    //program powinien iść tą prawidłową ścieżką
    //bo -9 + 6 = -3 < 4
} else {
    //ale wykona się ten fragment ponieważ 
    // -9 + 6 stanie się dla kompilatora
    // (256 - 9) + 6 = 253.
    // 247 (bez znaku) == -9 ze znakiem
}

Powyższy program skompilowany i uruchomiony na 8-bitowym AVR wykona się tak jak opisałem w komentarzach. Co ciekawe jeśli skompilujesz ten kod u siebie na komputerze to wykona się poprawnie (zgodnie z przewidywaniami). Dzieje się to dlatego, że pracujesz na 32 lub 64 bitowym procesorze i rejestry mają taką długość. Zmień jednak typ zmiennych na np. uint32_t i int32_t a zadziała jak na AVR :)

niedziela, 24 lutego 2013

Projekty anten na PCB

Zestaw anten na różne częstotliwości (2.4GHz, 868 / 915 / 920 MHz, 433 MHz, 315 MHz, 136 - 240 MHz), o różnych rozmiarach i pasmach do wykonania na PCB od Texas Instruments http://www.ti.com/lit/an/swra351a/swra351a.pdf

poniedziałek, 3 września 2012

Kolejny Eval Board za grosze

TI rozpoczął przedsprzedaż eval boarda za symboliczne $5 (z przesyłką, także do Polski):
https://estore.ti.com/Stellaris-LaunchPad.aspx

Płytka ta jest kompletnym systemem uruchomieniowym zawierającym mikrokontroler oraz zintegrowany interfejs sprzętowy (programator/debuger).

Na pokładzie znajduje się mikrokontroler LM4F120H5QR z rdzeniem Cortex M4F w obudowie LQFP64. Jest on całkiem nieźle wyposażony:
  • 256 kB Flash
  • 32 kB SRAM
  • zegar do 80MHz
  • 4 x I2C
  • 4 x SPI
  • 8 x UART
  • 12 bitowe ADC (próbkowanie do 1000kSPS)
  • 2 Analogowe komparatory
  • 16 Cyfrowych komparatorów
  • wewnętrzny czujnik temperatury
  • CAN
  • RTC
  • USB Device

poniedziałek, 13 sierpnia 2012

Kilka słów o imporcie z Chin

Nie jestem ekspertem w dziedzinie importu spoza Unii Europejskiej ale postaram się przedstawić moje pierwsze doświadczenia w tej materii. Od jakiegoś czasu robiłem mniejsze zakupy, ale niedawno postanowiliśmy z moim wspólnikiem sprowadzić trochę części elektronicznych z Dalekiego Wschodu, jako, że ceny oferowane przez lokalnych dystrybutorów nawet przy kilku tysiącach były kilkukrotnie wyższe niż te oferowane przez Chińczyków. Opiszę więc w krokach co i jak.

1. Szukanie producenta / sprzedawcy w Chinach
Ja zwykle szukam ofert firm w popularnych serwisach typu AlibabaMade in ChinaDHgateDealextreme
Dealextreme to w zasadzie sklep z podanymi cenami. W zasadzie nie pasuje tu do całej reszty ale korzystałem z niego już niejednokrotnie i postanowiłem wspomnieć o nim w kilku słowach. Cenami może nie powala (zdarza się, że na allegro jest taniej) ale czasami można znaleźć coś przydatnego w okazyjnej cenie. 
Paczka wysyłana jest zwykłą pocztą (przesyłka nierejestrowana) i jest to opcja bezpłatna. Przy bardziej kosztownych zakupach można wybrać przesyłkę rejestrowaną (niewielka dopłata) lub nawet kuriera ale to już trochę kosztuje (jeszcze nie sprawdzałem tej opcji). Paczka do Polski idzie od 3 do 5 tygodni. 
Płatności dokonuje się za pomocą PayPala lub kartą kredytową. Chińczyk zazwyczaj zaniża wartość przesyłki i oznacza ją jako próbka. Jeszcze nie zdarzyło mi się płacić cła za zakupy z DX. Cała procedura zakupów jest prosta i nie jest wymagany bezpośredni kontakt z Chińczykiem. 

Trochę trudniejsza sprawa jest z pozostałymi serwisami. Są to w zasadzie katalogi producentów / sprzedawców reklamujących się i swoje produkty. Przy wyborze trzeba kierować się ocenami kupujących, długością stażu jak również ilością transakcji zakończonych sukcesem (w zasadzie jak na allegro). Po znalezieniu interesującego nas towaru wysyłamy zapytanie ofertowe do kilku czy kilkunastu firm. O zasadach jak takie zapytanie skonstruować w internecie znajdziecie dużo informacji. Następnie przychodzi czas na negocjacje. Zazwyczaj udaje się jeszcze zejść z ceny podawanej przez sprzedawcę. Przydają się argumenty w stylu, że jest to zamówienie próbne, następne będą większe i regularne, widzicie duże zapotrzebowanie w Polsce na te towary itp. Oczywiście zawsze należy kierować się zdrowym rozsądkiem. Przy zbyt dobrej ofercie lub znacznie różniącej się od tej zaoferowanej przez pozostałych sprzedawców powinno się Wam zapalić czerwone światełko :). Niestety oszuści również używają tych serwisów.
Przydatne w rozmowach z Chińczykami są różnego rodzaju czaty czy też Skype - podobno oni to lubią :). Niestety ze względu na różnicę czasu (ok 6-7 godzin) rozmowy te muszą odbywać się w nocy lub wcześnie rano (chociaż zdarza się, że niektórzy pracują do 20 ichniego czasu - 12-13 u nas)

2. Płatność za towary
Testowałem dwie metody płatności: przelew bankowy oraz płatność kartą. 
Przelew bankowy niestety nie jest najtańszą i najszybszą opcją, ale czasami jesteśmy na niego skazani (szczególnie przy dużych kwotach). Sam przelew idzie do odbiorcy kilka dni i kosztuje nawet kilkadziesiąt złotych (lub więcej w zależności od kwoty przelewu) - trzeba zajrzeć w cennik swojego banku.
Płatności kartą kredytową są wygodne jeżeli korzystamy np. z  Escrow . Sam osobiście bałbym się podać numer karty Chińczykowi.

3. Transport
Dotychczas przy większych zakupach korzystałem z usług firm kurierskich. Nie jestem jeszcze na tyle dużym importerem żeby sprowadzać całe kontenery statkiem. Sprzedawcy najczęściej mają podpisane umowy z DHLem czy UPSem i mają całkiem niezłe ceny (nawet $20 przy mniejszych paczkach). Paczka do Polski leci w zasadzie 2-3 dni robocze. Zaletą firm przewozowych jest to, że działają przy nich agencje celne ale o tym w kolejnym punkcie. 
Przy większych zakupach bardziej opłacalne jest zapakowanie towaru na statek. Niestety nie mam doświadczenie w tym temacie więc nie będę się rozpisywał.

4. Cło i podatek
Przy większych zakupach trzeba się liczyć niestety z zapłatą cła i podatku. Cło w zależności od tego co sprowadzamy może się różnić. Kupując części elektroniczne i wszystko co z tym związanie płaciłem 0 lub 3.7% cła i oczywiście 23% VATu jako, że jestem vatowcem. I tu drobna uwaga. W cenę towaru wlicza się również koszt transportu.
Przy wszystkich formalnościach z cłem warto skorzystać z agencji celnej. Wystarczy podpisać stosowną umowę/upoważnienie do reprezentacji w naszym imieniu przed urzędem celnym. Do podpisania takiej umowy potrzebne są dokumenty firmy (NIP, REGON) oraz numer EORI (więcej o tym w następnym punkcie)

Nie wiem z czego to wynika ale Chińczycy zazwyczaj zaniżają koszty produktu (z jednej strony dobrze bo płacimy mniejsze cło :) ), nie podają kosztów transportu, załączają do przesyłki błędne faktury (brak numeru faktury, nieprawidłowy adres nadawcy i odbiorcy, błędnie opisana zawartość itp.). Niestety z taką przesyłką najczęściej są problemy przy odprawie celnej. Paczka taka może nie wyjść z  Agent celny może np. wziąć standardową cenę za przesyłkę z Chin (a ta jest horrendalnie wysoka) a my będziemy musieli zapłacić za to cło i podatek. Dlatego zawczasu warto poprosić Chińczyka o to by wystawił prawidłową fakturę, bo później  będziemy musieli się o nią postarać gdy paczka będzie już w Polsce w urzędzie celnym. A to wydłuża czas transportu a nawet może zwiększyć koszty (np. w DHL'u jeżeli paczka leży powyżej 3 dni to naliczana jest kwota 100zł i 25zł za każdy następny dzień)

5. EORI
EORI to Wspólnotowy System Rejestracji i Identyfikacji Podmiotów Gospodarczych (ang. Economic Operators’ Registration and Identification - EORI). Każdy importer (eksporter chyba też) musi posiadać numer EORI. Aby go uzyskać należy wypełnić odpowiedni formularz (do pobrania ze strony Ministerstwa Finansów) i złożyć go w odpowiednim dla swojego miejsca Urzędzie Celnym. Cała procedura jest bezpłatna a numer uzyskuje się na miejscu lub w ciągu paru godzin zostaje przesłany na podany adres e-mail.

Jeśli ktoś chce uzyskać numer w Gdyni to może mieć pewien problem ze znalezieniem właściwego urzędu (przynajmniej ja miałem). Nie znajduje się on wbrew temu co można znaleźć w internecie na ulicy Północnej. Poniżej poglądowa mapka gdzie dokładnie należy złożyć formularz (punkt oznaczony Urząd Celny). (Tak wiem, na mapie nawet nie ma tam zaznaczonej drogi, a zaznaczone miejsce na większości map to jakaś firma)


czwartek, 12 lipca 2012

[Ku pamięci] Online Gerber viewer

Jakiś już czas temu natknąłem się na fajną stronkę do oglądania plików gerber. Ostatnio musiałem się znowu jej trochę naszukać więc wrzucam ją tu aby mieć na przyszłość :)

http://mayhewlabs.com/webGerber/

czwartek, 5 kwietnia 2012

USB VID i PID dla każdego od NXP

Następna niespodzianka od NXP.
Dla osób które tworzą urządzenia z USB i wykorzystują do tego celu mikrokontrolery z rodziny LPC11Uxx producent umożliwia uzyskanie do 3 darmowych numerów PID.
Dzięki temu nie musimy płacić za członkostwo w USB-IF. Minusem niestety jest to, że licencja obejmuje tylko do 10k urządzeń.

Czekamy teraz na podobny program dla LPC13xx , LPC17xx i pozostałych :)

Źródło: http://www.lpcware.com/content/project/usb-vid-pid-program

wtorek, 3 kwietnia 2012

"Product Longevity Program" dla mikrokontrolerów NXP z rdzeniem ARM Cortex-M

Ostatnio będąc na szkoleniu Freescale firma ta chwaliła się, że jako jedyna gwarantuje, że ich mikrokontrolery będą produkowane przez ileś następnych lat.

Okazuje się, że NXP postanowił również uruchomić podobny program. Firma gwarantuje, że mikrokontrolery z rdzeniem Cortex-M będą w ofercie co najmniej przez 10 lat od wprowadzenia do sprzedaży. Na razie programem objęte są najprostsze mikrokontrolery z rodziny LPC11xx (rdzeń Cortex-M)

źródło: http://www.nxp.com/news/press-releases/2012/03/nxp-introduces-longevity-program-for-arm-cortex-m-microcontrollers.html



wtorek, 20 grudnia 2011

Używanie słówka kluczowego inline zamiast makr w C



Dobry kod zawiera zwykle dużą liczbę relatywnie małych funkcji czy metod, które mogą być łączone ze sobą na wiele sposobów (jak klocki Lego). Często jednak pisząc kod tworzymy mniej, bardziej złożonych i mniej uniwersalnych funkcji. Sprawia to, że kod jest bardziej podatny na błędy i często sprawia problemy przy testowaniu czy szukaniu błędów.

Często powodem takiego stanu rzeczy jest nieużywanie małych funkcji aby nie obniżać wydajności systemu. Ciągłe wywoływanie  małej funkcji może znacznie zmniejszyć prędkość wykonywania całego programu. Oczywiście można zainwestować w szybszy procesor ale nie zawsze jest to możliwe do wykonania. Może nam zależeć na minimalizacji czasu wykonania jakiejś funkcji.

Rozważmy taki przykład. Mamy funkcję, która dodaje 1 do jakiejś wartości ale z tzw. nasyceniem aby nie przekroczyć maksymalnej wartości (żeby zmienna się nie "przekręciła"):

  int SaturatingIncrement(int x)
  { if (x != MAXINT)
    { x++;
    }
    return(x);
  }

Możemy mieć więc kod wyglądający jak poniżej:
  ...
  x = SaturatingIncrement(x);
  ...
  z = SaturatingIncrement(z);

Na pewno zauważysz, że jeśli wielokrotnie funkcja ta będzie wykonywana to kod będzie wykonywał się wolno. Zwykle rozwiązania są 2. Niektórzy, kopiują kod z funkcji i używają go mniej więcej tak:
  ...
  if (x != MAXINT)  { x++; }
  ...
  if (z != MAXINT)  { z++; }

Dużym problemem z tym jest to, że jeśli znajdziesz błąd, musisz przejrzeć cały program i poszukać wszystkich wystąpień takich fragmentów kodu i ręcznie je poprawić.

Trochę lepszym rozwiązaniem jest użycie makr:
#define SaturatingIncrement(w)  { if ((w) != MAXINT)  { (w)++; } }

które, pozwala wrócić mniej więcej do oryginalnego kodu. Kod więc może wówczas wyglądać tak:
  ...
  SaturatingIncrement(x);
  ...
  SaturatingIncrement(z);

ale preprocesor wykryje użycie makra i zamieni to na taki kod dla kompilatora:
  ...
  if (x != MAXINT)  { x++; }
  ...
  if (z != MAXINT)  { z++; }

eliminując tym samym kilka niepotrzebnych taktów przy wywołaniu funkcji.

Fajną rzeczą w makrach jest to, że jeśli znajdziesz błąd to musisz poprawić go tylko w jednym miejscu i sprawia, że kod jest dużo bardziej czytelny. Tak czy inaczej złożone makra mogą być niewygodne i być źródłem tajemniczych błędów (np. wiesz dlaczego jest "(w)" zamiast po prostu w?).

Dobrą wiadomością jest to, że we większości kompilatorów C jest lepsze rozwiązanie. Zamiast używać makr można użyć funkcji ze słówkiem kluczowym "inline".

  inline int SaturatingIncrement(int x)
  { if (x != MAXINT)
    { x++; }
    return(x);
  }

Słówko inline mówi kompilatorowi aby rozwinął kod funkcji w linii gdzie wywołana jest funkcja (tak jak makro). Ale zamiast zamiany tekstu w preprocesorze jest do dokonywane przez sam kompilator. Można więc pisać tyle funkcji inline ile się chce bez płacenie niepotrzebnymi taktami zegara. Dodatkowo, kompilator sprawdzi poprawność typów czy inne analizy aby pomóc wykryć błędy co nie było możliwe z makrami.

Można się jednak spotkać z kilkoma dziwactwami związanymi z inline. Niektóre kompilatory ignorują słówko inline jeśli funkcja przekracza jakąś określoną liczbę linii kodu. Inne z kolei pozwalają wywołać w ten sposób funkcje która jest zdefiniowana w tym samym pliku .c. Niektóre kompilatory muszą mieć zaznaczoną flagę aby wymusić inline zamiast zwykłego słówka inline przy definicji funkcji. Niestety aby być pewnym, że inline działa poprawnie, trzeba sprawdzić kod wyjściowy (w asemblerze) i zobaczyć jak nasz kompilator to obsługuje.

sobota, 10 grudnia 2011

Nowe zastosowania dla rejestrów RTC

Chcę dzisiaj pokazać nowe zastosowanie rejestrów zegara czasu rzeczywistego, które są dostępne w niektórych (wielu?) procesorach ARM jak również jak podejrzewam we wielu innych architekturach. Fragment z dokumentacji procesora firmy NXP przedstawiłem na rysunku poniżej.
Rejestry RTC procesorów z rodziny LPC17xx
Najbardziej interesująca jest kolumna Reset Value. Można zauważyć, że wartości zaznaczone na czerwono mają wartość "NC". "NC" oznacza, że rejestry te są nienaruszone podczas resetu procesora. Ponadto, rejestry te mogą być również zasilane z alternatywnego źródła zasilania, więc są one również odporne na utratę zasilania. Do czego to się przydaj? Otóż znalazłem kilka zastosowań dla nich poza oczywistym przeznaczeniem jakim jest przechowywanie daty i czasu (dla rejestrów RTC) i zapewnienia nieulotnej pamięci przez rejestów ogólnego przeznaczenia (General Purpose Registers).

Komunikacja z Bootloaderem
Większość dzisiejszych aplikacji wbudowanych zawiera program ładujący (bootloader). Chociaż istnieje kilka sposobów uruchamiana bootloadera, to najpopularniejszym i dostępnym we większości mikrokontrolerów sposobem jest wymuszenie resetu przez watchdog. Jednak sam reset nie wystarczy. Wymagana jest zwykle jakaś komunikacja między główna aplikacją a aplikacją ładującą. Bootloader musi co najmniej wiedzieć, że został celowo uruchomiony w celu wykonania aktualizacji oprogramowania a nie zostało to spowodowane przez błąd w programie i nieprzewidziany reset przez watchdoga. Może również się zdarzyć, że wymagana będzie informacja o tym z jakiego źródła ma być pobrany nowy program. W przeszłości istniała tendencja do przekazywania tych informacji poprzez pamięć EEPROM. Teraz mając powyższe rejestry można je wykorzystać do tego celu.

Debugowanie
Jeśli borykasz się z niespodziewanymi resetami systemu, to jest to stosunkowo prostą sprawą, aby napisać kilka linii kodu, który zapisuje w tych rejestrach informacje o kontekście. Na przykład większość RTOSów zapewnia mechanizmy wywołania funkcji użytkownika przez przełączeniem zadania. W funkcji tej banalne jest zapisanie do jednego z rejestrów ID zadania. Wtedy to tylko kwestia ustawienia breakpointa na wejściu do funkcji main() i odczyt które zadanie było uruchomione w momencie resetu. Zawężenie podejrzanych bardzo ułatwia sprawę.

Podejrzewał, że można znaleźć jeszcze wile zastosowań tych rejestrów. Na prawdę chciałbym aby rejestry tego typu były powszechne i dostępne w każdej rodzinie procesorów.

piątek, 25 listopada 2011

Szansa na darmowe Rasberry Pi od Nokii

Na blogu Nokia Qt pojawiła się informacja o tym, że Nokia sponsoruje 400 Raspberry Pi dla developerów. Szczegóły na: http://blog.qt.nokia.com/2011/11/24/qt-5-with-rasberry-pi-a-delicious-mix-with-home-delivery/

Zgłosiłem już własny pomysł - może się uda. Jak nie to trudno i tak sobie kupię układzik, $25 to w sumie nie wiele jak za takie coś :)

Play - promocja świąteczna (dla naiwnych)

Rzecznik Play umieścił na swoim blogu informacje o promocji świątecznej. Po przeczytaniu tej wiadomości nawet się ucieszyłem wysyłam SMSa i dostaję 50zł na rozmowy i SMS/MMSy. Jedynym warunkiem było to aby na koncie znajdowało się 30zł.
Niestety uśmiech z twarzy znikł mi gdy pobrałem regulamin, z którego wynika że nie dostajemy 50zł a kupujemy sobie pakiet 50zł za 30zł :(
Aktywna jest w tej chwili również inna promocja w ramach której za 10zł możemy kupić pakiet 30zł.
Nawet dziecko zauważyłoby, że to jakiś przekręt...