Mulhacén

Jakiś czas temu dostałem maila od Radka, że wybierają się do Hiszpani i Andory w góry. Celem miał być Mulhacen i Coma Pedrosa, wypad miał zająć tydzień. Niestety tydzień z punktu widzenia mojego urlopu to trochę za długo, dlatego postanowiłem wybrać się tylko na Mulhacen. Zarezerwowałem bilety lotnicze do Malagi, zabukowałem samochód i pozostało tylko czekać. W końcu nadzchodzi 27 września i lecę. Z Ekipą miałem się spotkać w niedzielę o 7.30 powyżej Sierra Nevada w Albergue Hoya de la Mora. Dojeżdzam na miejsce koło 8 i na parkingu witam Katarzynę, Gregora, Jędrka i oczywiście Radka. Okazuje się, że rozbili sobie namiot przy parkingu i tam nocowali. W trakcie oczekiwania na wycieczkę kontakowałem się z przewoźnikiem kursującym między Hoya de la Mora a Veletą i powiedzieli mi, że na przejazd o 8 rano wszystko jest zarezerwowane. Mimo wszystko idziemy do centrum informacyjnego spytać, czy jest jakiś transport i ku naszej uciesze okazuje się, że jedziemy! Jest to powód do radości, bo zaoszczędza nam spory kawałek marszu. W trakcie jazdy pani kierowca informuje nas, że ostatni bus zjeżdza o 18.45. Po dojechaniu na górę, ruszamy drogą w kierunku Mulhacena. Oczywiście pogoda się załamuje i przychodzą gęste chmury z których co jakiś czas pada deszcz. Po drodze zatrzymujemy się w Refugio de la Carihuela, które wygląda bardzo przyzwoicie. Radek zadecydował, że będziemy schodzić do samochodów, więc nikt nie wziął śpiworów i teraz tego sromotnie żałujemy. Przynajmniej ja z Gregorem, bo nocleg tam wyglądałby w zasadzie jak w hotelu 4 gwiazdkowym. Nawet nie potrzebna jest mata, bo prycze są drewniane- wystarczy mieć śpiwór. Dochodzimy w końcu pod kopułę Mulhacena i po około godzinie stajemy na szczycie. Pana śnieg z deszczem i mocno wieje, więc po krótkiej sesji zdjęciowej schodzimy na dół. Po zejsciu, w pobliżu Refugio Vivac de la Caldera chmury się rozstępują i pokazuje się niebieskie niebo a nas o mało nie trafia szlag. Podobno za szczytu widać góry Rif o tej porze roku- my nie bardzo widzieliśmy się nawzajem. Siadamy na chwilę Refugio i po chwili ruszamy z powrotem. Oczywiście spóźniamy się na autobus o 18.45. Kontaktujemy się z panią od busa, która grzecznie informuje nas, że o 19 zamykają szlaban na dole i nie może po nas przyjechać. Radek zaczyna bluzgać pod nosem, a my kolejny raz żałujemy, że nie mamy śpiworów. Z czołówkami na głowach dochodzimy do parkingu około 21.30. W poniedziałek rzut okiem na Granadę i we wtorek wracam do Manchesteru. Reasumując Mulhacen jest banalną górą do zrobienia. W zasadzie cały czas idzie się bitą drogą, tylko podejście pod pik jest nieco stromsze. Długość trasy jest trochę nużąca. Trasa jest do zrobienia w jeden dzień- przy skorzystaniu z busa to w ogóle pikuś. Wszystkie trzy Refugio są w bardzo dobrym stanie- można śmiało w nich nocować jeżeli ma się śpiwór. Poniżej materiał, tutaj trasa, a tu link do zdjęć.

Alpy retyckie

Materiał z wycieczki w Alpy:

Zamiana wartości 2 zmiennych bez zmiennej pomocniczej

Popularny sposób na zamianę wartości 2 zmiennych polega na użyciu zmiennej pomocniczej:

int a = 1;
int b = 2;
int tmp;

tmp = a;
a = b;
b = tmp;

A to metoda bez użycia zmiennej pomocniczej:

int a = 1;
int b = 2;

a ^= b;
b ^= a;
a ^ =b;

Opaque pointers i embedded C

Pisząc aplikację w C programista często chce ukryć niektóre dane przed użytkownikiem. Jednym ze sposobów jest użycie opaque pointer- http://en.wikipedia.org/wiki/Opaque_pointer. Struktura z danymi do ukrycia jest zdefiniowana w pliku *.c, natomiast w interfejsie dostępne jest tylko

typedef struct hiddenData *hiddenData;

Tym samym dane nieistotne dla użytkownika są niewidoczne.
Jak można wykorzystać opaque pointers w aplikacji embedded? Jako przykład posłuży kontroler GPDMA, procesora LPC2478. Kontroler ten ma 4 kluczowe ustawienia, które muszą być aktualizowane przy każdym transferze. Są to: adres źródłowy, adres przeznaczenia, słowo kontrolne i słowo konfiguracyjne. W polach bitowych słowa kontrolnego i konfiguracyjnego określane są inne ustawienia jak szczerokość słowa, rozmiar burst'u, kontorla przepływu, itp- szczegóły hardware'owe, które użytkownika w ogóle nie interesują. Dlatego w interfejsie dostaje on strukturę konfiguracyjną z podstawowymi ustawieniami i zestaw funkcji:

/* struktura konfiguracyjna */
struct gpdmaConf {
    enum transferType;
    uint32_t srcAddress;
    uint32_t dstAddress;
    /* itd... */
};
/* funkcje dla użytkownika */
void gpdmaInit(void);
gpdmaChnl gpdmaChnl0Init (const struct gpdmaConf *gpdmaConf);
void gpdmaChnl0Enable(const gpdmaChannel gpdmaChnl, const uint16_t size);


Zwracany typ przez funkcję gpdmaChnl0Init to:

typedef struct gpdmaChnl *gpdmaChnl;


Jest on dostępny w pliku *.h ale definicja struct gpdmaChannel jest ukryta w *.c. Wywołanie transferu wygląda następująco:

/* konfiguracja kontrolera- wypełnia użytkownik */
static struct gpdmaConf mygpdma;    
/* zmienna przechowująca ustawienia po inicjalizacji kanału */
static gpdmaChnl channel0;        

gpdmaInit();
/* do channel0 są zwracane ustawienia hardware'u... */
channel0 = gpdmaChnl0Init(&mygpdma); 
/* ...które następnie przekazywane są do gpdmaChnl0Enable */   
gpdmaChnl0Enable(channel0, 32);    


W przykładzie na wikipedii (http://en.wikipedia.org/wiki/Opaque_pointer#C) została wykorzystana funkcja malloc. Ponieważ jej użycie może nie być pożądane, można na sztywno zdefinować tablicę kanałów- ich liczba jest znana.

Wadą opisanej metody kodowania jest nieco bardziej skomplikowane wywołanie transferu. Są też opinie, że takie podejście nie nadaje się do tworzenia sterowników dla bare metal applications. Zalety to ukrycie przed użytkownikiem szczegółow implementacji hardware'owej- nie ma on pojęcia, o słowie kontrolnym czy konfiguracyjnym, w których są pola bitowe. Dobrze zaprojektowany interfejs, pozwala na używanie zestawu tego samego API, zmienia się tylko ciało funkcji w pliku źródłowym.

 

Bałkany 2012

Poniżej film z majowego wypadu na Bałkany.

Tutaj jest trochę zdjęć.

Pointer na tablicę czy tablica pointerów

Dlaczego deklaracja

char *p[3];

nie jest pointerem na 3-elementową tablicę char'ów? Odpowiedź: nawiasy [] mają wyższy priorytet niż asterisk * więc deklaracja to 3-elementowa tablica pointerów na char'y.

Funkcje asemblera inline w GCC

Pracując ostatnio nad procesorem ARM (na Ubuntu 10.1, kompilator Sourcery G++ Lite 2010q1-188) , korzystałem z książki Lucjana Bryndzy "ARM9 w przykładach". Przy okazji omawiania przerwań programowych (strona 105), autor zastosował mniej więcej takie podejście:

static inline void myFunction (unsigned int arg)

{

   asm volatile

   (

      "mov r0, %[ledon]n"

      "swi #1n"

      ::[ledon]"r"(arg):"r0"

   );

}

I co? GCC z uporem wypluwa komunikaty "immediate expression requires a # prefix" a jak zmienimy % na # pojawia się za to błąd "garbage following instruction". Żeby rozwiązać problem należy nieco zmodyfikować kod:

static inline void myFunction (unsigned int arg)

{

   asm volatile

   (

      "mov r0, %[ledon]\n\t"

      "swi #1\n\t"

      ::[ledon]"r"(arg):"r0"

   );

}

W stringach zawierających kod asemblera musi występować znacznik nowej lini plus tabulacja i voila!

Instalacja pluginów w Eclipse

W Eclipse powszechnie znane są dwa sposoby instalacji pluginów. Pierwszy przez menedżera nowego oprogramowania (Help->Install New Software...), a drugi poprzez umieszczenie zawartości paczki- konkretnie jej folderów features i plugins- do ich odpowiedników w głównym folderze Eclipse. Dziś przypadkowo natknąłem się na trzeci sposób. W skrócie:

1. zakładamy folder Eclipse_plugins (jego nazwa i lokalizacja dowolne). Posłuży on do przechowywania rzeszy instalowanych w przyszłości pluginów. Wewnątrz zakładamy następny o nazwie opisującej naszą wtyczkę. Mój nazwywa się avr.

2. w avr należy stworzyć kolejny folder o obowiązkowej nazwie: eclipse. Dopiero tutaj rozpakowywujemy zawartość wtyczki. Taka hierarchia jest wymagana dla wszystkich kolejnych wtyczek:

Eclipse_plugins

|-avr

          |-eclipse

                    |-features

                    |-plugins

|-inna_wtyczka

          |-eclipse

                    |-features

                    |-plugins

2. w katalogu głównym eclipse zakładamy folder links

3.  w 'links' tworzymy plik nasza_wtyczka.link (ważne jest rozszerzenie). U mnie avr.link

4. edytujemy plik wpisując path=[ścieżka do Eclipse_plugins]/avr/eclipse. UWAGA: autor tego sposobu instalacji wtyczek sugeruje zakończyć ścieżkę na folderze z nazwą wtyczki (path=/home/kuba-pc/eclipse/Eclipse_plugins/avr) jednak u mnie taki sposób definicji path nie działał (Ubuntu 10.4, Eclipse Helios). Musiałem dodać też folder eclipse, tak że zmienna ma postać path=/home/kuba-pc/eclipse/Eclipse_plugins/avr/eclipse.

5. uruchamiamy ponownie eclipse. Mój plugin avr pojawił się w opcjach wyboru projektu C.

Metoda zapewnia selektywność w zarządzaniu wtyczkami. Można tworzyć osobne foldery dla nowych wtyczek i dodawać odpowiadające im pliki z rozszerzeniem link. Usunięcie wtyczki jest prostsze niż przeszukiwanie folderu eclipse/plugins i eclipse/features i usuwanie niepotrzebnej zawartości (w przypadku gdy kopiowaliśmy tam zawartość wtyczki). Należy zwrócić uwagę na strukturę katalogów, nazwę katalogu przechowywującego linki (links) i rozszerzenie pliku ze ścieżką (*.link). Ponadto autor pisze, że zalecane jest tworzenie jednego pliku z jednym wpisem dla dużych wtyczek. Dla małych lepiej jest przygotować wspólny plik i umieścić kilka ścieżek do odpowiednich wtyczek (patrz Points to note na dole tekstu).

Materiały

W sekcji Wykonanie PCB umieściłem filmy skrótowo prezentujące przygotowanie druku i lutowanie.

Nowy adres

Od 20 maja strona ma adres www.jdorzak.pl

Subskrybuje zawartość