2011/02/12

Sterowanie silnikiem krokowym

Fajny artykuł o sterowaniu silnikami krokowymi.

http://www.codeproject.com/KB/system/MotorController.aspx

Design patterns

Polecam strone m.in. o design patterns, bardzo dobrze przygotowany materiał.

http://sourcemaking.com/

2011/01/31

ARM w SIM

Szukałem informacji na temat Cortex-M0 a tym czasem trafiłem na coś takiego:

Jak się okazuje można opchnąć 320KB flash i Cortexa-M3 w karcie SIM!!! Ciekawe czy zwykły zjadacz chleba może sobie kupić parę sztuk tych czipów. Już widzę urządzenia do podpisu cyfrowego Made In Home :D, lub inteligentne karty SIM do GSM. Ehhh ... gdyby tylko wróciły stare czasy wyciągania kluczy z SIM :)

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/CD00252313.pdf

2011/01/30

Skróty klawiaturowe konsoli

Nie wiem czy znacie następujące skróty klawiaturowe konsoli:

!!
Powtórzenie ostatniego polecenia
!foo
Powtórzenie polecenia zaczynającego się od ‘foo…’ (np. !ps, !mysqladmin)
Ctrl-a
Skocz na początek linii
Ctrl-e
Skocz na koniec linii
Ctrl-l
Wyczyść ekran
Ctrl-r
Wyszukaj polecenie w historii (szukanie wstecz). Jeżeli chcemy edytować polecenie - wciskamy strzałkę w prawo
Alt-?
Podpowiedzi uzupełnienia komend
Ctrl-k
Wytnij tekst do końca linii
Ctrl-u
Wytnij tekst ad początku linii do kursora
Ctrl-y
Wklej wycięty tekst

ARM w pigułce

Kto chce się szybko i w skrócie zapoznać z asemblerem i kodem startowym dla ARM polecam:
http://www.bravegnu.org/gnu-eprog/index.html

Dla mnie najciekawsze było streszczenie architektury rozkazów ARM:
http://www.bravegnu.org/gnu-eprog/arm-iset.html


Do tego polecam
http://www.stm32.eu/index.php?option=com_content&view=category&layout=blog&id=35&Itemid=57

2010/12/22

Niewinne static

Czym różną się zmienne globalne oznaczone jako static:
- ich definicja nie jest dołączana do tablicy exportu
- są inicjalizowane tylko raz (podczas uruchomienia kodu startowego, domyślnie 0 (sekcja bss) lub wartością podana przy deklaracji (sekcja .data))

O ile pierwsza właściwość jest mało inwazyjna to druga ma pewne konsekwencje jeśli o niej zapomnimy.
Gdybyśmy np chcieli pisać pseudo obiektowo wykorzystując czyste C, i zapomnieli o konstruktorze statycznym a uprościli sprawę inicjalizujac zmienne współdzielone w miejscu deklaracji.

Np załóżmy ze mamy do napisania prosta klasę która ma jedna zmienna współdzielona przez wszystkie instancje oraz funkcje Create, Destroy i DoSome.

static int mod_state_variable = 10; //dla uproszczenia pomijam mutexy
typedef struct Mod_Tag
{
      int some_var;
} Mod_T;

void Mod_Creat(Mod_T *mod)
{

    mod->some_var = 0;
}

void Mod_Destroy(Mod_T *mod)
{
}

void Mod_DoSome(Mod_T *mod)
{
   if( 10 == mod_state_variable )
       mod_state_variable = 50;
   mod_state_variable++;
   mod->some_var++;
}

sekwencja
Mod_Init();
Mod_DoSome();
Mod_DoSome();
Mod_Finalize();

da wynik
mod_state_variable = 51 mod->some_var = 1 po pierwszym DoSome
mod_state_variable = 52 mod->some_var = 2 po drugim DoSome

powtórzenie sekwencji
Mod_Init();
Mod_DoSome();
Mod_DoSome();
Mod_Finalize();

da nam
mod_state_variable = 53 mod->some_var = 1 po pierwszym DoSome
mod_state_variable = 54 mod->some_var = 2 po drugim DoSome

ponieważ zmienna statyczna mod_state_variable inicjalizowana jest tylko raz.
Jeśli chcemy przywrócić pierwotny stan zmiennej współdzielonej musieli byśmy użyć coś na wzór konstruktora statycznego.

Podobnie, inicjalizacja w miejscu deklaracji nie spełni swojego zadania np w przypadku bibliotek dynamicznych które posiadają tak inicjalizowane zmienne statyczne. Dopiero odłączenie biblioteki i ponowne jej podłączenie spowoduje przeinicjalizowanie takich zmiennych.

2010/10/14

Amnezja

Czasami mam wrażenie że metodą optymalizacji zapominam co mniej istotne aspekty. Kiedyś już chyba głowiłem się nad zagadnieniem przekazywania tablic w parametrach funkcji.

Przywykłem do tego ze tablice deklarujemy w parametrach funkcji jako
fkt(int tab[])

W kodzie kolegi zobaczyłem
fkt(int tab[10])

Pierwsze skojarzenie jakie mi się nasunęło, to że ta tablica przejdzie przez stos jako kopia pamięci (40bajtow)...

Okazalo sie ze jest inaczej:
#include

struct ss {
    int field1;
    int field2;
    int tab[100];
};

void fkt(char tab[10])
{
    printf("%p\n", tab);
}

void fkt2(struct ss param)
{
    printf("%p\n", &param);
}

int main()
{
    char tab[10] = { 0, 1, 2 };
    char tab2[] = { 1, 1, 1};
    struct ss param;

    fkt(tab);
    printf("%p\n", tab);
    fkt(tab2);
    printf("%p\n", tab2);

    fkt2(param);
    printf("%p\n", &param);

    return 0;
}


Wynik:
[xzs6ts@TVBuildAlfa BWL]$ ./a
0xbfa01916
0xbfa01916
0xbfa01913
0xbfa01913
0xbfa015d0
0xbfa01778


Dlaczego przekazywanie struktur przez stos jest wykonywane jako kopia a tablic jako referencja ?
"nazwa zmiennej tablicowej jest jednoczenie wskaźnikiem do pierwszego elementu"
Z tego tez powodu w języku C nie możemy powiedzieć "przekaz tablice", bo "się po prostu nie da" :)
Za to możemy powiedzieć "przekaz strukturę" co tez kompilator czyni.