<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Truly Integrated &#187; SW</title>
	<atom:link href="http://truly-integrated.net/category/sw/feed/" rel="self" type="application/rss+xml" />
	<link>http://truly-integrated.net</link>
	<description>electronics microcontrollers fpga vhdl</description>
	<lastBuildDate>Fri, 19 Feb 2010 21:22:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>pl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>GCC i funkcje o zmiennej liczbie argumentów</title>
		<link>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/</link>
		<comments>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 22:52:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[SW]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=91</guid>
		<description><![CDATA[Niniejszy wpis jest poświęcony zagadnieniu wykorzystania funkcji o zmiennej liczbie argumentów w swoich projektach. Najpopularniejszym przykładem funkcji posiadającą taką właściwość jest funkcja printf, której prototyp wygląda mniej-więcej tak:
int printf(char *fmt, ...);
Notacja &#8216;&#8230;&#8217; w polu argumentów funkcji informuje kompilator o tym, iż funkcja może przybierać dowolną liczbę argumentów. Powstaje podstawowe pytanie:  w jaki sposób takie argumenty [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Niniejszy wpis jest poświęcony zagadnieniu wykorzystania funkcji o zmiennej liczbie argumentów w swoich projektach. Najpopularniejszym przykładem funkcji posiadającą taką właściwość jest funkcja <em>printf, </em>której prototyp wygląda mniej-więcej tak:</p>
<pre>int printf(char *fmt, ...);</pre>
<p style="text-align: justify;">Notacja <em>&#8216;&#8230;&#8217;</em> w polu argumentów funkcji informuje kompilator o tym, iż funkcja może przybierać dowolną liczbę argumentów. Powstaje podstawowe pytanie:  w jaki sposób takie argumenty są przekazywane do funkcji skoro ich liczba nie jest wprost określona? Jak się do nich odwoływać?</p>
<p style="text-align: justify;">Twórcy kompilatora GCC rozwiązali sprawę przekazując takie parametry w formie obszaru pamięci zorganizowanego w specyficzny sposób. Na potrzeby rozważań ustalmy, iż funkcja, którą będziemy badać  będzie posiadała następujący prototyp:</p>
<pre>void foo(char *arg, ...);</pre>
<p>Jeżeli kolejne argumenty funkcji oznaczymy przez <em>arg0 &#8230; arg n</em> to zostaną one umieszczone w pamięci w sposób przedstawiony na poniższym rysunku:<img class="aligncenter size-full wp-image-107" title="gcc_va_args" src="http://truly-integrated.net/wp-content/uploads/2009/07/gcc_va_args.png" alt="gcc_va_args" width="318" height="272" /></p>
<p style="text-align: center;">
<p style="text-align: justify;">Wyjaśnienia wymaga zapis <em>a_sizeof(x). </em>Jest to makro zwracające rozmiar zmiennej (w bajtach) będącej jego argumentem w postaci &#8216;wyrównanej&#8217; do architektury dla której kompilujemy oprogramowanie. Przykładowo, jeśli architektura jest 32 bitowa to wartość dla zmiennej 1-bajtowej wynosi 4, a dla zmiennej 5-bajtowej wynosi 8. Powyższy rysunek mówi nam, iż każdy kolejny argument jest umieszczony po poprzednim w odległości równej <em>a_sizeof(x)</em>, gdzie <em>x</em> to argument poprzedni.</p>
<p style="text-align: justify;">Skoro wiemy już jak zmienne są rozmieszczone w pamięci to możemy zdefiniować sobie makra do poruszania się po nich i odczytywania ich wartości. Zestaw makr przygotowanych przeze mnie ma następującą postać:</p>
<div class="codesnip-container" >
<div class="c codesnip" style="font-family:monospace;"><span class="co2">#define __a_size(n)           ((sizeof(n) + sizeof(char *) &#8211; 1) &amp;amp; ~(sizeof(char *) &#8211; 1))</span></p>
<p><span class="co2">#define va_start(ptr, v)        (ptr = (va_list)(&amp;amp;v) + __a_size(v))</span><br />
<span class="co2">#define va_arg(ptr, t)          ( *(t *)((ptr += __a_size(v)) &#8211; __a_size(t)))</span><br />
<span class="co2">#define va_end(ptr)             (ptr = (va_list) 0)</span></p>
<p><span class="kw4">typedef</span> <span class="kw4">char</span> <span class="sy0">*</span> va_list</div>
</div>
<p style="text-align: justify;">Makro <em>__a_size(n)</em> jest odpowiednikiem notacji <em>a_sizeof(n)</em> z rysunku. Makro <em>va_start(ptr, v)</em> ustawia wskaźnik <em>ptr</em>, tak aby wskazywał na pierwszą zmienną ze zbioru. Aby poprawnie ustawić wskaźnik niezbędny jest adres ostatniej &#8216;normalnej&#8217; zmiennej (na rysunku jest zmienna <em>arg</em>). Makro <em>va_arg(ptr, t)</em> powoduje zwrócenie zmiennej wskazywanej przez ptr oraz ustawienie <em>ptr</em> tak by wskazywał na następną zmienną. Parametr <em>t</em> makra określa typ zmiennej jaką chcemy zwrócić. Jest on niezbędny, gdyż od niego zależy &#8216;odległość&#8217; do następnej zmiennej w pamięci. Makro <em>va_end(ptr)</em> służy do wyczyszczenia wartości wskaźnika ptr.</p>
<p style="text-align: justify;">Wyposażeni w taki zestaw makr możemy zacząć naszą przygodę z funkcjami o zmiennej liczbie argumentów. Dla przykładu napiszemy funkcję wypisującą wartość wszystkich zmiennych typu int podanych jako argumenty. Listing funkcji jest następujący:</p>
<div class="codesnip-container" >
<div class="c codesnip" style="font-family:monospace;"><span class="kw4">void</span> foo<span class="br0">&#40;</span><span class="kw4">int</span> num_ints<span class="sy0">,</span> &#8230;<span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
<span class="kw4">int</span> i<span class="sy0">,</span> x<span class="sy0">;</span><br />
va_list va<span class="sy0">;</span></p>
<p>va_start<span class="br0">&#40;</span>va<span class="sy0">,</span> num_ints<span class="br0">&#41;</span><span class="sy0">;</span></p>
<p><span class="kw1">for</span><span class="br0">&#40;</span>i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&amp;</span>lt<span class="sy0">;</span> num_ints<span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
x <span class="sy0">=</span> va_arg<span class="br0">&#40;</span>va<span class="sy0">,</span> <span class="kw4">int</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;arg: %d, val: %d<span class="es1">\n</span>&quot;</span><span class="sy0">,</span> i<span class="sy0">,</span> x<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p style="text-align: justify;">Przykładowe wywołanie:</p>
<pre style="text-align: justify;">foo(3, 1, 2, 3);</pre>
<p style="text-align: justify;">I jego rezultat:</p>
<pre style="text-align: justify;">arg: 0, val: 1
arg: 1, val: 2
arg: 2, val: 3</pre>
<p style="text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/07/gcc-i-funkcje-o-zmiennej-liczbie-argumentow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>USB JTAG i OpenOCD 0.1.0 + Eclipse</title>
		<link>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/</link>
		<comments>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 16:24:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[HW]]></category>
		<category><![CDATA[SW]]></category>

		<guid isPermaLink="false">http://truly-integrated.net/?p=32</guid>
		<description><![CDATA[Jakiś czas temu światło dzienne ujrzała nowa wersja popularnego oprogramowania OpenOCD, służącego do programowania i debugowania uC. W związku z tym, jakże wspaniałym, wydarzeniem uznałem za zasadne przedstawienie Czytelnikowi treści skryptów, służących do programowania pamięci flash mikrokontrolerów AT91SAM7S64. Wybór mikrokontrolera jest podyktowany tym, iż znalazł on zastosowanie w dużej części wykonanych przeze mnie urządzeń. W [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu światło dzienne ujrzała nowa wersja popularnego oprogramowania <a title="OpenOCD" href="http://openocd.berlios.de/web/">OpenOCD</a>, służącego do programowania i debugowania uC. W związku z tym, jakże wspaniałym, wydarzeniem uznałem za zasadne przedstawienie Czytelnikowi treści skryptów, służących do programowania pamięci flash mikrokontrolerów AT91SAM7S64. Wybór mikrokontrolera jest podyktowany tym, iż znalazł on zastosowanie w dużej części wykonanych przeze mnie urządzeń. W roli JTAG&#8217;a wykorzystałem, własnoręcznie wykonany,<a href="http://truly-integrated.net/archives/3"> klon Turtelizera 2</a>.</p>
<p>W pakiecie OpenOCD dołączono wiele skryptów opisujących sposób pracy interfejsów JTAG, jak również dla poszczególnych układów docelowych (targetów). Nic nie stoi na przeszkodzie aby je wykorzystać i znacząco ułatwić sobie życie. Przykładowy skrypt flashujący uC plikiem<em> main.hex </em> wygląda następująco:</p>
<pre>source [find openocd-0.1.0/src/target/interface/turtelizer2.cfg] # (1)
source [find openocd-0.1.0/src/target/target/sam7s64.cfg]        # (2)

init                                  # (3)
reset halt                            # (4)
flash write_image main.hex 0          # (5)
reset run                             # (6)
shutdown                              # (7)</pre>
<p>Pierwsza linia zawiera ściężkę prowadzącą do opisu użytego interfejsu JTAG, zaś linia (2) wskazuje na plik z opisem układu docelowego. Jeśli Czytelnik w swej pracy wykorzystuje inne uklady docelowe należy przejrzeć katalog <em>target</em> w folderze instalacyjnym OpenOCD w poszukiwaniu odpowiedniego pliku. Z każdym dniem społeczność pracująca nad OpenOCD uzupełnia zbiór plików konfiguracyjnych o nowe targety. Pozostałe linie mają składnię podobną do znanej z poprzednich wersji OpenOCD. Powodują one inicjalizację komunikacji z targetem oraz jego zresetowanie i wstrzymanie (3, 4). Flashowanie odbywa się dzięki komendzie zawartej w linii (5), której pierwszym parametrem jest operacja jaką wykonujemy na pamięci flash, po niej następuje nazwa pliku oraz offset od początku przestrzeni adresowej uC pod jaki zostaną zapisane dane. Linie (6, 7) kolejno resetują mikrokontroler i &#8220;wprawiają go w ruch&#8221; oraz kończą pracę OpenOCD. Jak wynika z załączonego przykładu skrypty, dzięki gotowym zbiorom plików konfiguracyjnych, uległy znacznemu uproszczeniu.</p>
<p>Skrypt służący do debugowania jest równie prosty co powyższy, używany do flashowania. Jego treść przedstawia się w sposób zgodny z przdestawionym na listingu:</p>
<pre>source [find ./openocd-0.1.0/src/target/interface/turtelizer2.cfg] # (1)

# Change the default telnet port...
telnet_port 4444                     # (2)

# GDB connects here
gdb_port 3333                        # (3)

# GDB can also flash my flash!
gdb_memory_map enable                # (4)
gdb_flash_program enable             # (5)
gdb_breakpoint_override hard         # (6)

source [find ./openocd-0.1.0/src/target/target/sam7s64.cfg]        # (7)

init                                 # (8)</pre>
<p>Przeznaczenie linii  (1, 7)  jest znane z poprzedniego skryptu. Linia (2) służy do konfiguracji portu na którym będzie nasłuchiwać OpenOCD. Linia (3) ustawia port pracy samego debuggera GDB. Linie (4, 5) umożliwiają programowanie pamięci flash uC z wykorzystaniem GDB. Linia (6) ustawia rodzaj stosowanych breakpoinów na breakpointy hardwareowe. Opcja ta jest niezbędna w momencie gdy firmware został zlinkowany tak by pracować w pamięci flash a nie w pamięci ram. Należy mieć świadomość, iż liczba jednocześnie stosowanych breakpointów hardwareowych jest bardzo ograniczona, a w przypadku AT91SAM7S64 wynosi dokładnie dwa. Linia (8) służy do uruchomienia procesu debugującego.</p>
<p style="text-align: justify;">Tak przygotowany skrypt wyśmienicie współpracuje ze środowiskiem Eclipse. Konfigurację Eclipsa z doinstalowanym pluginem <a title="Zylin CDT plugin" href="http://opensource.zylin.com/embeddedcdt.html">Zylin Embedded CDT</a> rozpoczynamy od dodania nowej <em>Debug Configuration</em> typu <em>Zylin Embedded Debug (Native)</em>. Należy wybrać nazwę projektu dla którego konfigurujemy debug oraz plik wykonywalny w formacie <em>elf</em>, który zawiera m. in. symbole niezbędne dla debugu. Plik taki powstaje każdorazowo w wyniku zlinkowania skompilowanych źródeł projektu.</p>
<p style="text-align: center;"><a href="http://truly-integrated.net/wp-content/uploads/2009/07/debug_conf.png"><img class="aligncenter size-medium wp-image-63" title="debug_conf" src="http://truly-integrated.net/wp-content/uploads/2009/07/debug_conf-570x427.png" alt="debug_conf" width="570" height="427" /></a></p>
<p style="text-align: justify;">Następnie przechodzimy do zakładki <em>Debbuger</em>, gdzie ustawiamy jako aplikację debugującą <em>arm-elf-gcc</em> lub innym, w zależności z jakich kompilatorów korzystamy. W zakładce <em>Commands</em> ustawiamy komendy wysyłane podczas inicjalizacji oraz samego uruchomienia trybu debug. Komendy, jakie należy umieścić w sekcji <em>Initialize commands</em> są następujące:</p>
<pre style="text-align: justify;">target remote localhost:3333
monitor reset halt</pre>
<p>Sekcję<em> &#8216;Run commands&#8217;</em> pozostawiamy pustą. Tak przygotowany Eclipse jest gotowy do odpluskwiania (ech&#8230;), zaraz po uruchomieniu opisanego wcześniej skryptu uruchamiającego <em>debug mode</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://truly-integrated.net/2009/07/usb-jtag-i-openocd-010-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
