CROOK-5 w EM400 pod Windows.

crook5windows

Dziś z ciekawości skompilowałem EM400 w MSYS2 pod Windows.

Aby uruchomić (snapshot git b4794ce, aktualizacja z 24.04.2017):

  1. Instalujemy MSYS2 w wersji x86_64 lub i686 w zależności od wersji systemu Windows.
  2. Pobieramy i rozpakowujemy archiwum  w wersji 64-ro lub 32-bitowej zawierające binaria EM400. Znajdziemy w nim też cross-assemblery, plik konfiguracyjny i inne narzędzia, ale obraz Crook5 oraz EEPROM pamięci Mega trzeba pobrać ze strony mera400.pl.
  3. Odpalamy Msys2 Shell z menu Windows. W shell-u wchodzimy do katalogu gdzie rozpakowaliśmy em400.zip i obraz systemu CROOK. MSYS2 jest środowiskiem uniksopodobnym, więc dyski z Windows mapowane są np. na /c/jakiś/katalog.
  4. Uruchamiamy emulator: ./em400.exe -c em400.cfg
  5. Odpalamy jeszcze jeden Msys2 Shell, telnet 127.0.0.1 32000
  6. Wpisujemy run w debuggerze.

fib_on_crook

Miłej zabawy Mera400 (MX-16) i CROOK-5.

Reklamy

AspeQt dla Windows.

Piętnaście emulowanych napędów w AspeQt to było dla mnie zdecydowanie za dużo 🙂 więc „zandroidyzowałem” plik projektu z repo dla Androida i wydzieliłem co androidowe, dzięki czemu mój fork AspeQt dla Antka kompiluje się też pod Windows i pod Linuksem. Obsługa portu odbywa się wtedy przez standardowy moduł serialport-{win32,linux}.cpp. Przy okazji poprawiłem kodowanie znaków, które w AspeQt pod Windows było skopane od dawna:

AspeQt_WindowsBinarka dla Windows z wymaganymi bibliotekami tutaj.

winandroidlinux

Printf() pod Windows.

Printf() pod Windows okazuje się sporo wolniejszy niż pod Linuksem.

printf_windowsParadoksalnie, jak widać powyżej, pythonowy print() jest ~3x szybszy od printf() z biblioteki standardowej Mingw-w64. Pod Linuksem na odwrót, 4x wolniejszy względem tego z libc.stdio:

print_linux


Poczytałem stdio.h i doszedłem do tego, że gdy  -D__USE_MINGW_ANSI_STDIO=1 używana jest funkcja printf() z Mingw (ponad 11 razy wolniejsza od printf() pod Linuksem) i tak jest „by default”.

Jeśli do gcc dodam  -D__USE_MINGW_ANSI_STDIO=0, używana jest wersja printf() z msvcrt.dll. Mimo, że ta funkcja ma swoje braki, różnica jest dość znaczna:

$ time ./fib_mingw_printf.exe 300000 > /dev/null

real 0m5.513s
user 0m0.000s
sys 0m0.031s

$ time ./fib_msvcrt_printf.exe 300000 > /dev/null

real 0m1.081s
user 0m0.015s
sys 0m0.000s


Jeszcze jedna ciekawostka: przekierowanie do /dev/null w MSYS2 (które jest prawdopodobnie mapowane na NUL) pod Windows jest powolne. Przekierowanie do pliku jest ~2x szybsze:

$ time ./fib_msvcrt_printf.exe 300000 > output.txt

real 0m0.562s
user 0m0.000s
sys 0m0.015s

(Pod Linuksem bez różnicy).


Na szczęście %timeit pozwala się przekonać, że kod generowany w tej samej wersji gcc pod Windows i pod Linuksem jest niemal tak samo wydajny.

Msys2 – toolchain idealny.

Idąc jak po nitce do kłębka, w końcu trafiłem na Msys2, czyli minimalny zestaw narzędzi systemowych, oparty o narzędzia uniksowe (głównie GNU) dla Windows.

msys2
Co się najbardziej rzuca w oczy w tym zrzucie? 🙂 Ano pacman. Tak, ten sam pacman co w Arch Linuksie, którego używam na co dzień. Co za tym idzie? Wszystkie pakiety (kompilator, biblioteki, python, narzędzia) i kompletne środowisko GNU, są w repo projektu, więc aktualizacja (pod Windows!) to standardowe: pacman -Suy, a przebudowanie pakietu wg własnego uznania to edycja prostych, jak konstrukcja przysłowiowego cepa plików PKGBUILD.

Dla mnie Msys2 to brakujący element systemów Windowsowych.

Cython – kompilacja programów w Pythonie mingw-w64 dla Windows.

Dawno nie miałem takiej motywacji do programowania. Cztery dni poszukiwań, grzebania w strzępkach dokumentacji i przykładach. W końcu się udało. Ale od początku. Postanowiłem trochę odświeżyć wiadomości o Pythonie i natrafiłem na Cythona, który mnie zafascynował, ale miałem problem z kodowaniem argumentów programów (sys.argv) do obiektów unikodowych pod Windows (argv w Windows jest w UTF-16, wchar_t **). W żaden sposób nie dało się ich dekodować do Unicode, a binarki dla Linuksa działały bez problemu. Pal licho argv ale to samo dotyczyło kodowania nazw plików. Przetestowałem kilkadziesiąt funkcji C-API Pythona i nic.  Skonwertowanie windowsowych szerokich argumentow (wchar_t **) argv z UTF-16 do UTF-8 wydawało się niemożliwe. Aż w jakimś archiwum ircowym trafiłem na wzmiankę, że bez flagi -municode mingw-gcc nie obsługuje pod Windows poprawnie kodowania linii cmd.

Co ciekawe, od początku wydawało mi się celowe generowanie entrypoint-a przez Cythona dla Windows jako:

int wmain(int argc, wchar_t **argv)

Okazuje się, że po dodaniu -municode do gcc mingw-w64 jako entrypoint traktuje właśnie wmain() i używa odpowiednich wersji funkcji z obsługą unicode. Niestety w mingw-gcc 4.8.1 nie ma opcji -municode i wiele osób pewnie z tego powodu ma problemy.  W gcc-4.8.1 z mingw-w64 działa jak należy, jest nawet o tym informacja na stronie projektu:

http://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/

Szkoda, że wcześniej tego nie znalazłem ;(.

aconv

Przykładowa konwersja i kompilacja wygląda tak, w Windows w MSYS:

/c/Python34/Scripts/cython.exe -3 --embed aconv.py
gcc aconv.c -I /c/mingw/python/include/python3.4m -L /c/mingw/python/lib/ -lpyth
on3.4m -municode -o aconv

Podsumowując. Bardzo mnie to cieszy. W Cythonie, poza niemal pełną zgodnością z Pythonem można includować nagłówki z bibliotek w C i bezpośrednio z nich korzystać w modułach pythonowych, z całą dobrocią typów C a pozwala na przyspieszenie kluczowych fragmentów kodu i kompilację nawet całych programów skonwertowanych do C. A w składni wygląda to jak Python.

Pełen respect dla twórców Cythona.

 

Pypy, Cython, mingw-w64, static libpython3.4m.a.

Mój powrót do Pythona po kilkuletniej przerwie skończył się fascynacją. Po pierwsze Pypy – ale to szybkie i całkowicie zgodne z Pythonem! Po drugie Cython (opcja –embed) szok, udało mi się skompilować statyczne binarki skryptu aconv.py dla Linuksa i Windows (walczę jeszcze trochę z kodowaniem konsoli cmd w Windows, bo tu oczywiście są niemałe problemy z 16bit kodowaniem – muszę zrozumieć PyUnicode w Pythonie i Cythonie). Po trzecie: konfiguracja i działanie MSYS z mingw i mingw-w64 – niesamowity toolchain (instalowałem z win-builds), wszystko działa jak na Linuksie, trzeba tylko skonfigurować /c/mingw/msys/1.0/etc/fstab, czyli dodać c:\mingw /mingw, uruchamiać C:\MinGW\msys\1.0>msys.bat a potem konfigurację mingw-w64 (uwaga na kropkę) . /c/mingw/msys/1.0/opt/windows_32/bin/win-builds-switch 32 najlepiej dodać do ~/.bash_profile, ścieżka do gcc z mingw-w64 i bibliotek będzie się sama ustawiać po odpaleniu msys.bat.

Kompilację Pythona 3.4.2 ze statyczną i dynamiczną biblioteką libpython3.4m udostępniłem tutaj). Zbudowany po nałożeniu łatek z repo mingw-w64 i wykonaniu autoreconf-2.68.

W powyższym zipie zmodyfikowałem python/include/pyconfig.h w taki sposób, aby po dodaniu do wywołania gcc opcji -DPy_ENABLE_STATIC -static linkował z libpython3.4m.a, a bez tych opcji z libpython3.4m.dll:

#if defined Py_ENABLE_STATIC
#undef Py_ENABLE_SHARED
#else
#define Py_ENABLE_SHARED 1
#endif

PS: Aby interaktywny interpreter Pythona z tej kompilacji zadziałał, trzeba uruchomić polecenie:
. /c/mingw/msys/1.0/opt/windows_32/bin/win-builds-switch 32 w przeciwnym razie będzie mu brakować bibliotek.

Ext4 pod Windows.

Ameryki tym wpisem nie odkryje, ale wreszcie trafiłem na dobrze działające narzędzie, pozwalające na dostęp do plików ext4 pod Windows:

http://fsproxy.masterm.org/HomePage

Program to niezła kombinacja alpejska i zbitek różnych technologii (kernel linuksowy w qemu i interfejs do tego), jednak jak się zastanowić, ma to sens i co najważniejsze – działa jak trzeba 🙂