<?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>NTREXGO - 디바이스마트, 엔티렉스 컨텐츠 통합 사이트 &#187; applications</title>
	<atom:link href="http://www.ntrexgo.com/archives/tag/applications/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ntrexgo.com</link>
	<description>엔티렉스, 디바이스마트 컨텐츠 통합 사이트</description>
	<lastBuildDate>Thu, 03 Mar 2022 06:47:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[18호]JK전자와 함께하는 ARM 완전정복(4)-2</title>
		<link>http://www.ntrexgo.com/archives/13757</link>
		<comments>http://www.ntrexgo.com/archives/13757#comments</comments>
		<pubDate>Fri, 10 May 2013 04:22:34 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[18호]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[jk전자]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=13757</guid>
		<description><![CDATA[디바이스마트매거진 18호 &#124; ARM Architecture 강의에서는 특정 CPU(S3C2440, STM32Fxx) 에 대한 내용 보다는 ARM Core의 이론적인 구조 자체에 대해서 많은 설명을 하였습니다. 이번 강의에서는 Samsung의 ARM9 CPU S3C2440 개발보드를 이용해서 실제 실습을 통해서 ARM에 대해서 공부해 보도록 하겠습니다.]]></description>
				<content:encoded><![CDATA[<table style="width: 600px" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자.jpg" rel="lightbox[13757]"><img class="alignnone wp-image-13318" alt="jk전자" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자-300x222.jpg" width="192" height="142" /></a></td>
<td><span style="color: #000080"><strong><span style="font-size: large">JK전자와 함/께/하/는 ARM 완전 정복</span></strong></span></p>
<p><strong style="line-height: 19px"><span>Ⅱ.ARM Applications &#8211; 2부</span></strong></p>
<p>글 | JK전자</td>
</tr>
</tbody>
</table>
<p><span style="color: #00ccff"><strong>(7) Stack Pointer 초기화</strong></span></p>
<p>각 프로세서 모드별(7개 동작모드)로 Processor Mode를 전환하면서 Stack을 초기화해야 합니다. 이전 강좌인 ARM Architecture의 ARM Register 부분을 다시 보시면 R13(SP)는 각 동작 모드별로 뱅크 되어 있는 레지스터임을 확인 할 수 있습니다. 여기서 주의해야 할 점은 User Mode Stack은 제일 마지막에 초기화해야 합니다. 왜 그럴까요? User Mode는 비특권 모드이므로 한번 User Mode로 진입을 하여 SWI 명령등을 사용하지 않으면 다시 특권 모드로 진입을 할 수 없어서 다른 Processor Mode의 Stack Pointer를 초기화할 수가 없습니다. 이런 이유로 해서 User Mode의 Stack Pointer를 제일 마지막에 초기화하도록 해야 합니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #ff0000">;function initializing stacks </span><br />
<span style="color: #ff0000">InitStacks </span><br />
<span style="color: #ff0000">;Don&#8217;t use DRAM,such as stmfd,ldmfd&#8230;&#8230; </span><br />
<span style="color: #ff0000">;SVCstack is initialized before </span><br />
<span style="color: #ff0000">;Under toolkit ver 2.5, &#8216;msr cpsr,r1&#8242; can be used instead of &#8216;msr cpsr_cxsf,r1&#8242; </span><br />
<span style="color: #ff0000">mrs r0,cpsr </span><br />
<span style="color: #ff0000">bic r0,r0,#MODEMASK </span><br />
<span style="color: #ff0000">orr r1,r0,#UNDEFMODE|NOINT </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;UndefMode </span><br />
<span style="color: #ff0000">ldr sp,=UndefStack</span><span style="color: #ff0000">orr r1,r0,#ABORTMODE|NOINT </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;AbortMode </span><br />
<span style="color: #ff0000">ldr sp,=AbortStack</span><span style="color: #ff0000">orr r1,r0,#IRQMODE|NOINT </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;IRQMode </span><br />
<span style="color: #ff0000">ldr sp,=IRQStack</span><span style="color: #ff0000">orr r 1,r0,#FIQMODE|NOINT </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;FIQMode </span><br />
<span style="color: #ff0000">ldr sp,=FIQStack ;// 아래(System Mode Stack) 부분 추가 함.</span><span style="color: #ff0000">bic r0,r0,#MODEMASK|NOINT </span><br />
<span style="color: #ff0000">orr r1,r0,#SYSMODE </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;SYSMode </span><br />
<span style="color: #ff0000">ldr sp,=SYSStack</span><span style="color: #ff0000">bic r0,r0,#MODEMASK|NOINT </span><br />
<span style="color: #ff0000">orr r1,r0,#SVCMODE </span><br />
<span style="color: #ff0000">msr cpsr_cxsf,r1 ;SVCMode </span><br />
<span style="color: #ff0000">ldr sp,=SVCStack</span><span style="color: #ff0000">;USER mode has not be initialized. We use always SVC mode.</span><span style="color: #ff0000">mov pc,lr ;The LR register won&#8217;t be valid if the current mode is not SVC mode.</span></td>
</tr>
</tbody>
</table>
<p><strong style="color: #00ccff">(8) Segment Initialization</strong></p>
<p>ROM Binary가 만들어 지고 나서 프로그램이 실행되기 위해서는 반드시 RAM이 있어야 합니다. Segment Initialization은 RAM에서 프로그램이 올바른 데이터를 가지고 실행될 수 있도록 RAM 영역에 전역변수의 초기값들을 저장하는 일을 합니다. 좀 더 자세한 사항은 이전 강좌인 ARM Architecture 4.4 Linker 부분을 참조하시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm042.jpg" rel="lightbox[13757]"><img class="alignnone  wp-image-13728" alt="18feajkarm042" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm042-620x239.jpg" width="496" height="191" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm043.jpg" rel="lightbox[13757]"><img class="alignnone  wp-image-13729" alt="18feajkarm043" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm043-620x120.jpg" width="496" height="96" /></a></p>
<p>위의 그림에서 왼쪽이 ROM Binary 이고 오른쪽이 RAM 영역입니다.<br />
- .data : C언어 등에서 선언한 전역변수들의 초기값이 저장되어 있는 영역입니다.<br />
- .bss : 0으로 초기화 되는 영역입니다. 초기값을 지정하지 않은 전역변수등이 여기에 해당합니다.<br />
- .textrw : 컴파일러에 의해 생성된 RAM에서 실행되는 함수들 입니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>#pragma segment = &#8220;.bss&#8221;<br />
#pragma segment = &#8220;.data&#8221;<br />
#pragma segment = &#8220;.data_init&#8221;<br />
#pragma segment = &#8220;.rodata&#8221;<br />
#pragma segment = &#8220;.textrw&#8221;<br />
#pragma segment = &#8220;.textrw_init&#8221;<br />
#pragma segment = &#8220;CSTACK&#8221;<br />
void InitSegment()<br />
{<br />
unsigned int k, n;<br />
unsigned char *pdst, *psrc;//<br />
// initialize zero-initialized segment<br />
//<br />
n = (unsigned int)__section_end(&#8220;.bss&#8221;) &#8211; (unsigned int)__section_begin(&#8220;.bss&#8221;);<br />
pdst = (unsigned char *)__section_begin(&#8220;.bss&#8221;);for(k=0; k&lt;n; k++)<br />
{<br />
*(pdst + k) = 0;<br />
}<br />
//<br />
// initialize non-zero-initialized segment<br />
//<br />
n = (unsigned int)__section_end(&#8220;.data_init&#8221;) &#8211; (unsigned int)__section_begin(&#8220;.data_init&#8221;);<br />
pdst = (unsigned char *)__section_begin(&#8220;.data&#8221;);<br />
psrc = (unsigned char *)__section_begin(&#8220;.data_init&#8221;);<br />
for(k=0; k&lt;n; k++)<br />
{<br />
*(pdst + k) = *(psrc + k);<br />
}//<br />
// initialize segment for ram-function<br />
//<br />
n = (unsigned int)__section_end(&#8220;.textrw_init&#8221;) &#8211; (unsignedint)__section_begin(&#8220;.textrw_init&#8221;);<br />
pdst = (unsigned char *)__section_begin(&#8220;.textrw&#8221;);<br />
psrc = (unsigned char *)__section_begin(&#8220;.textrw_init&#8221;);<br />
for(k=0; k&lt;n; k++)<br />
{<br />
*(pdst + k) = *(psrc + k);<br />
}return;<br />
}</td>
</tr>
</tbody>
</table>
<p><strong style="color: #00ccff">(9) main 함수로 이동</strong></p>
<p>EXTERN main<br />
ldr pc, =main</p>
<p>드디어 모든 Stack초기화와 Segment 초기화 과정을 끝내고 C 함수를 호출할 수 있게 되었습니다. 이제부터는 C 코드를 이용해서 각 디바이스들을 테스트할 수 있게 되었네요.</p>
<p>&nbsp;</p>
<p><span style="color: #3366ff"><strong>5.2 GPIO Output(LED On/Off)</strong></span></p>
<p>LED를 컨트롤 하기 위해서는 포트를 Output으로 설정한 후에 GPIO(General Purpose Input Output) 포트에 Low or High를 출력하면 됩니다. 아래 회로도는 우리가 실습에 사용하고 있는 Mini2440의 LED 회로도입니다. 4개의 LED가 있는데 각 LED는 GPB5 ~ 8 에 연결이 되어 있습니다. 그렇다면 LED1을 켜기 위해서 GPB5 포트에 Low(0)로 해야 할까요? 아니면 High(1)로 해야 할까요? 정답은 LED의 한쪽 끝이 VDD33V에 연결이 되어 있기 때문에 Low로 설정해야 전류의 흐름이 발생하여 LED가 켜지게 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm045.jpg" rel="lightbox[13757]"><img class="alignnone  wp-image-13731" alt="18feajkarm045" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm045-620x370.jpg" width="496" height="296" /></a><br />
<span style="text-decoration: underline">실험예제</span><br />
LED1, LED2는 On을 하고, LED3, LED4는 Off 시켜 봅니다.<br />
<span style="color: #33cccc">(1) GPBCON 레지스터에 GPB5 ~ GPB8을 Output으로 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm014.jpg" rel="lightbox[13757]"><img class="size-full wp-image-13697 alignleft" alt="18feajkarm014" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm014.jpg" width="453" height="580" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// GPB5 Output</span><br />
<span style="color: #808080">(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) &amp; ~(0&#215;3 &lt;&lt; 10);</span><br />
<span style="color: #808080">(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) | (0&#215;1 &lt;&lt; 10);</span><span style="color: #808080">// GPB6 Output</span><br />
<span style="color: #808080">rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 12);</span><br />
<span style="color: #808080">rGPBCON = rGPBCON | (0&#215;1 &lt;&lt; 12);</span><span style="color: #808080">// GPB7 Output</span><br />
<span style="color: #808080">rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 14);</span><br />
<span style="color: #808080">rGPBCON = rGPBCON | (0&#215;1 &lt;&lt; 14);</span><span style="color: #808080">// GPB8 Output</span><br />
<span style="color: #808080">rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 16);</span><br />
<span style="color: #808080">rGPBCON <span style="line-height: 19px">= rGPBCON | (0&#215;1 &lt;&lt; 16);</span></span></td>
</tr>
</tbody>
</table>
<p><span style="color: #33cccc">(2) GPBDAT 레지스터의 GPB5, GPB6을 Low로, GPB7, GPB8을 High로 세팅합니다.</span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// LED1 On</span><br />
<span style="color: #808080">rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 5);</span><br />
<span style="color: #808080">// LED2 On</span><br />
<span style="color: #808080">rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 6);</span><br />
<span style="color: #808080">//rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 6);</span><br />
<span style="color: #808080">// LED3 Off</span><br />
<span style="color: #808080">rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 7);</span><br />
<span style="color: #808080">// LED4 Off</span><br />
<span style="color: #808080">rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 8);</span></td>
</tr>
</tbody>
</table>
<p>diag.c &#8211; led_test()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// GPB5 Output<br />
(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) &amp; ~(0&#215;3 &lt;&lt; 10);<br />
(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) | (0&#215;1 &lt;&lt; 10);// GPB6 Output<br />
rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 12);<br />
rGPBCON = rGPBCON | (0&#215;1 &lt;&lt; 12);// GPB7 Output<br />
rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 14);<br />
rGPBCON = rGPBCON | (0&#215;1 &lt;&lt; 14);// GPB8 Output<br />
rGPBCON = rGPBCON &amp; ~(0&#215;3 &lt;&lt; 16);<br />
rGPBCON = rGPBCON | (0&#215;1 &lt;&lt; 16);// LED1 On<br />
rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 5);<br />
// LED2 On<br />
rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 6);// LED3 Off<br />
rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 7);<br />
// LED4 Off<br />
rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 8);</td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline">소스코드 분석</span></p>
<p>(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) &amp; ~(0&#215;3 &lt;&lt; 10);<br />
GPBCON 레지스터의 주소가 0&#215;50000010입니다. 0&#215;3(b11)을 왼쪽으로 10번 쉬프트를 하면 b110000000000이고 이것을 &#8220;~&#8221; (Bit clear) 시키면 GPB5[11:10] 부분이 &#8220;00&#8243; 으로 Clear 됩니다.</p>
<p>(*(volatile unsigned *)0&#215;56000010) = (*(volatile unsigned *)0&#215;56000010) | (0&#215;1 &lt;&lt; 10);<br />
0&#215;1(b01)을 왼쪽으로 10번 쉬프트를 하면 b010000000000 이고 이것을 &#8220;|&#8221; (OR) 시키면 GPB5[11:10] 부분이 &#8220;01&#8243; 으로 Output 설정됩니다.</p>
<p>소스 코드중에 volatile 이라는 것을 사용하고 있습니다. 이것은 컴파일러 최적화에서 제외되는 효과가 있습니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>컴파일러 최적화 전</td>
<td>컴파일러 최적화 전</td>
</tr>
<tr>
<td>int a = 0; // 전역 변수<br />
int b = 0; // 전역 변수<br />
int i; // 로컬 변수for(i=0;i&lt;100;i++)<br />
b = b + a * 100;</td>
<td>int a = 0; // 전역 변수<br />
int b = 0; // 전역 변수<br />
int i; // 로컬 변수for(i=0;i&lt;100;i++)<br />
b = b + 0; // a * 100;</td>
</tr>
</tbody>
</table>
<p>위의 코드에서 오른쪽 코드처럼 개발자가 의도하지 않게 컴파일러에 의해 최적화가 되어 &#8220;a*100&#8243; 부분을 최적화하여 b 변수에 항상 0으로 저장이 되도록 할 수도 있습니다. 물론 일반적인 상황에서는 아무 문제가 되지 않지만 for 루프 수행중에 외부 인터럽트가 발생하여 인터럽트 서비스 루틴에서 a의 값을 0이 아닌 다른 값으로 변하게 한 후 다시 for 루프를 수행하면 개발자는 b에 0이 아닌 다른값이 저장되기를 기대하고 있겠지만 최적화된 코드에서는 b에 항상 0 이 저장이 되어 있을 것입니다. 이것은 개발자가 의도한 결과가 아닙니다. 이런 현상을 방지하기 위해서는 변수 a 를 volatile로 선언을 하면 됩니다. 특히나 SFR 레지스터 등에 값을 세팅하는 작업을 한다면 항상 volatile 로 선언을 해서 사용하는 것이 좋습니다.</p>
<p><span style="color: #3366ff"><strong>5.3 GPIO Input( KEY Input) &#8211; Polling</strong></span></p>
<p>LED를 켰을 때와 반대로 이번에는 GPIO포트를 이용해서 입력을 받아 보도록 하겠습니다. 포트에서 입력을 받기 위해서는 포트를 Input으로 설정한 후에 GPIO(General Purpose Input Output) 포트를 읽으면 됩니다. 6개의 KEY가 있는데 우리는 INT11, INT13에 연결되어 있는 K2, K3에 대해서 폴링 방식으로 입력을 감지해 보도록 하겠습니다. 참고로 폴링 방식이란 코드에서 무한 루프를 돌면서 특정 행위를 하는 것을 말합니다. 이번 경우에는 Key가 눌러졌는지를 감시하는 것이겠지요. 폴링과 다른 방식으로는 인터럽트 방식이 있습니다. 다음 절에서 공부하게 될 내용입니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm044.jpg" rel="lightbox[13757]"><img class="alignnone  wp-image-13730" alt="18feajkarm044" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm044-620x268.jpg" width="496" height="214" /></a></p>
<p><span style="text-decoration: underline">실험예제</span><br />
K2, K3 를 읽어서 KEY가 눌러져 있으면 LED2, LED3 를 On으로 하고, 눌러져 있지 않으면 Off로 설정해봅시다.</p>
<p><span style="color: #33cccc">(1) GPGCON 레지스터에 GPG3, GPG5를 Input으로 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm015.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13698" alt="18feajkarm015" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm015.jpg" width="459" height="452" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// KEY3, GPG5 Input</span><br />
<span style="color: #808080">rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 10); </span><br />
<span style="color: #808080">// KEY2, GPG3 Input</span><br />
<span style="color: #808080">rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 6);</span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(2) GPGDAT 레지스터의 GPG3, GPG5를 읽어서 &#8220;0&#8243; 이면 KEY가 눌린 상태이고, &#8220;1&#8243; 이면 KEY가 눌러지지 않은 상태입니다.</span></p>
<p>diag.c &#8211; key_test()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// KEY3, GPG5 Input<br />
rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 10);<br />
// KEY2, GPG3 Input<br />
rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 6);while(1)<br />
{<br />
if( (rGPGDAT &amp; (0&#215;1 &lt;&lt; 3)) == 0 ) // KEY2 pressed<br />
// LED2 On<br />
rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 6);<br />
else<br />
// LED2 Off<br />
rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 6);<br />
if( (rGPGDAT &amp; (0&#215;1 &lt;&lt; 5)) == 0 ) // KEY3 pressed<br />
// LED3 On<br />
rGPBDAT = rGPBDAT &amp; ~(0&#215;1 &lt;&lt; 7);<br />
else<br />
// LED3 Off<br />
rGPBDAT = rGPBDAT | (0&#215;1 &lt;&lt; 7);Delay(80);<br />
};</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong style="color: #3366ff">5.4 GPIO Input( KEY Input) &#8211; Interrupt</strong></p>
<p>이번에는 인터럽트 방식으로 K2, K3 입력을 감지해보도록 하겠습니다. 인터럽트 방식은 폴링방식보다 효율적이기는 하지만 좀 더 복잡합니다. 여기서 효율적이라고 하는 것은 CPU사용을 효과적으로 한다는 것이지 폴링방식보다 빠르다는 말은 아닙니다. 인터럽트 방식은 인터럽트 요청이 왔을때 인터럽트 서비스 루틴으로 분기할 때까지 지연시간이 있어 폴링 방식보다 느릴 수 있습니다. 하지만 폴링방식처럼 계속 루프를 돌면서 대기하지 않아도 되기 때문에 CPU활용면에서는 효율적입니다.</p>
<p><span style="text-decoration: underline">실험예제</span><br />
K2, K3를 읽어서 KEY가 눌러져 있으면 LED2, LED3를 On으로 하고 눌러져 있지 않으면 Off로 설정해봅시다.</p>
<p><span style="color: #33cccc">(1) GPGCON 레지스터에 GPG3, GPG5를 EINT(0&#215;2)으로 설정합니다.</span></p>
<p><span style="color: #33cccc"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm017.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13700" alt="18feajkarm017" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm017.jpg" width="450" height="235" /></a></span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// KEY3, GPG5 EINT13</span><br />
<span style="color: #808080">rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 10);</span><br />
<span style="color: #808080">rGPGCON = rGPGCON | (0&#215;2 &lt;&lt; 10);</span><span style="color: #808080">// KEY2, GPG3 EINT11</span><br />
<span style="color: #808080">rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 6); </span><br />
<span style="color: #808080">rGPGCON = rGPGCON | (0&#215;2 &lt;&lt; 6);</span></td>
</tr>
</tbody>
</table>
<p><span style="color: #33cccc">(2) EXTINT1 레지스터에 EINT11, EINT13을 Falling Edge로 설정합니다.</span></p>
<p><strong>Extintn(External Interrupt Control Register n)</strong></p>
<p>The 8 external interrupts can be requested by various signaling methods. The EXTINT register configures configures the signaling method between the level trigger and edge trigger for the extemal interrupt request, and also configuress the signal polarity.<br />
To recognize the level interrupt, the valid logic level on EXTINTn pin must be retained for 40ns at least because of the noise filter.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm018.jpg" rel="lightbox[13757]"><img class="alignnone size-large wp-image-13701" alt="18feajkarm018" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm018-388x620.jpg" width="388" height="620" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// set eint13 falling edge trigger </span><br />
<span style="color: #808080">rEXTINT1 &amp;= ~(0&#215;7 &lt;&lt; 20);</span><br />
<span style="color: #808080">rEXTINT1 |= (0&#215;2 &lt;&lt; 20);</span><span style="color: #808080">// set eint11 falling edge trigger</span><br />
<span style="color: #808080">rEXTINT1 &amp;= ~(0&#215;7 &lt;&lt; 12);</span><br />
<span style="color: #808080">rEXTINT1 |= (0&#215;2 &lt;&lt; 12);</span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(3) EINTPEND 레지스터의 Pending bit를 Clear 합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm019.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13702" alt="18feajkarm019" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm019.jpg" width="452" height="305" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// clear eint 11,13</span><br />
<span style="color: #808080">rEINTPEND |= (1 &lt;&lt; 11)|(1 &lt;&lt; 13);</span></td>
</tr>
</tbody>
</table>
<p>&#8220;It is cleard by writing 1&#8243; 이라는 문구가 보이는데요. 무슨 의미 일까요? 일반적으로 우리가 SFR 레지스터를 설정할 때에 아래와 같이 먼저 Bit를 Clear 시키고 Set 하는 2단계 과정을 거치게 됩니다.</p>
<p>rEXTINT1 &amp;= ~(0&#215;7 &lt;&lt; 20);<br />
rEXTINT1 |= (0&#215;2 &lt;&lt; 20);</p>
<p>하지만 인터럽트 서비스 루틴 안에서는 이것 조차도 비효율적일수 있고 Atmoic Operation이 아니기 때문에 Pending Clear를 하는 과정에서 새로운 인터럽트가 발생할 경우에 새로운 인터럽트가 지연될 수도 있습니다.</p>
<p>rEINTPEND |= (1 &lt;&lt; 11)|(1 &lt;&lt; 13);</p>
<p>이러한 이유로 위와 같이 &#8220;1&#8243; 을 써넣어서 바로 Pending을 Clear 할 수 있도록 한 것입니다.</p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(4) EINTMASK 레지스터에서 Interrupt를 Enable 합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm020.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13703" alt="18feajkarm020" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm020.jpg" width="451" height="446" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td><span style="color: #808080">// enable eint 11,13</span><br />
<span style="color: #808080">rEINTMASK &amp;= ~((1 &lt;&lt; 11)|(1 &lt;&lt; 13));</span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(5) SRCPND 레지스터의 Pending bit를 Clear 합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm021.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13704" alt="18feajkarm021" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm021.jpg" width="450" height="139" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rSRCPND = (0&#215;1&lt;&lt;5); // Clear pending bit</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(6) INTPND 레지스터의 Pending bit를 Clear 합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm022.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13705" alt="18feajkarm022" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm022.jpg" width="448" height="299" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rINTPND = (0&#215;1&lt;&lt;5); // Clear pending bit</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(7) EINT 인터럽트 서비스 루틴의 함수 포인터를 설정합니다.</span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>pISR_EINT8_23 = (U32)isr_eint_8_23;</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(8) INTMSK에서 EINT8_23 의 인터럽트를 Enable 합니다.</span><br />
<strong>INTERRUPT MASK(INTMSK) REGISTER</strong><br />
This register also has 32 bits each of which is related to an interrupt source. If a specific bit is set to 1, the CPU does not service the interrupt request from the corresponding interrupt source(note that even in such a case, the corresponding bit of SRCPND register is set to 1). If the mask bit is 0, the interrupt request can be serviced.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm023.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13706" alt="18feajkarm023" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm023.jpg" width="455" height="289" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rINTMSK &amp;= ~((0&#215;1&lt;&lt;5));</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(9) Startup코드의 IRQ Exception에서 인터럽트 번호를 확인하고 인터럽트 서비스 루틴으로 분기합니다.</span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>IsrIRQ<br />
sub sp,sp,#4 ;reserved for PC &#8211;&gt; 1<br />
stmfd sp!,{r8-r9} ; &#8211;&gt; 2<br />
ldr r9,=INTOFFSET ; &#8211;&gt; 3<br />
ldr r9,[r9] ; &#8211;&gt; 4<br />
ldr r8,=HandleEINT0 ; &#8211;&gt; 5<br />
add r8,r8,r9,lsl #2 ; &#8211;&gt; 6<br />
ldr r8,[r8] ; &#8211;&gt; 7<br />
str r8,[sp,#8] ; &#8211;&gt; 8<br />
ldmfd sp!,{r8-r9,pc} ; &#8211;&gt; 9</td>
</tr>
</tbody>
</table>
<p>▶ 1 : 스택포인터를 1 감소하여 빈 공간을 만듭니다. 인터럽트 핸들러 함수의 주소값이 저장될 공간입니다.<br />
▶ 2 : r8, r9를 사용하고 복원해야 하므로 stack에 저장합니다. stmfd는 먼저 어드레스를 감소하고 저장하므로 1에서 만들어진 빈공간은 그대로 남아 있습니다.<br />
▶ 3, 4 : INTOFFSET을 r9에 로드합니다.<br />
▶ 5 : HandleEINT0를 r8에 로드합니다. HandleEINT0는 Startup 코드의 아래 부분에 정의되어 있습니다.<br />
▶ 6,7 : HandleEINT0 + INTOFFSET*4의 수식이 됩니다. INTOFFSET 레지스터에는 발생한 인터럽트 소스의 Offset 값이 들어있는 레지스터입니다.</p>
<p>우리는 EINT8_23을 이용할 것이기 때문에 INTOFFSET 레지스터에는 5가 저장되어 있을 것입니다. 그러므로 HandleEINT0 + 5*4 즉 HandleEINT8_23의 주소가 됩니다.<br />
소스코드에서 key_test_eint() 함수에서 pISR_EINT8_23 = (U32)isr_eint_8_23; 의 코드를 삽입하면 EINT8_23 인터럽트가 발생하면 isr_eint_8_23 함수로 분기를 하게 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm024.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13707" alt="18feajkarm024" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm024.jpg" width="451" height="469" /></a><br />
▶ 8 : str r8,[sp,#8] 에 의해서 맨 처음에 Stack의 빈공간을 만들어 두었던 곳으로 인터럽트 핸들러 함수의 포인터 주소값을 저장합니다.<br />
▶ 9 : r8, r9 를 Stack에서 복원하고 pc 에 인터럽트 핸들러 함수의 주소가 저장이 되어 실제로 인터럽트 핸들러 함수가 실행이 됩니다.</p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(10) 인터럽트 서비스 루틴에서 GPGDAT 레지스터의 GPG3, GPG5를 읽어서 &#8220;0&#8243; 이면 KEY가 눌린 상태이고, &#8220;1&#8243; 이면 KEY 눌러지지 않은 상태입니다.</span></p>
<p>지금까지 설명한 인터럽트 관련 설정들을 S3C2440 인터럽트 컨트롤러 블럭도와 비교해서 보시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm046.jpg" rel="lightbox[13757]"><img class="alignnone size-large wp-image-13732" alt="18feajkarm046" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm046-620x278.jpg" width="620" height="278" /></a><br />
Interrupt MODE도 IRQ/FIQ 설정을 해야 하지만 S3C2440의 기본 인터럽트 설정 값이 IRQ 이기 때문에 생략하였습니다.<br />
외부 인터럽트 1개를 서비스 받기 위해서 정말 많은 과정이 필요 하네요. ARM Applications 이후에 하게될 Cortex-M3 Architecture 부분에서도 인터럽트 서비스에 대해서 설명을 할텐데, 그때 Cortex-M3가 얼마나 간결하고 효율적인지 비교해 보시기 바랍니다.</p>
<p>diag.c &#8211; key_test_eint()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>__irq __arm void isr_eint_8_23(void)<br />
{<br />
if(rINTPND==BIT_EINT8_23)<br />
{<br />
ClearPending(BIT_EINT8_23);<br />
if(rEINTPEND&amp;(1&lt;&lt;11))<br />
{<br />
rEINTPEND |= 1 &lt;&lt; 11;<br />
rGPBDAT = rGPBDAT ^ (0&#215;1 &lt;&lt; 6); // toggle<br />
}<br />
if(rEINTPEND&amp;(1&lt;&lt;13))<br />
{<br />
rEINTPEND |= 1 &lt;&lt; 13;<br />
rGPBDAT = rGPBDAT ^ (0&#215;1 &lt;&lt; 7); // toggle<br />
}<br />
}<br />
}<br />
void key_test_eint(void)<br />
{// KEY3, GPG5 EINT13<br />
rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 10);<br />
rGPGCON = rGPGCON | (0&#215;2 &lt;&lt; 10);<br />
// KEY2, GPG3 EINT11<br />
rGPGCON = rGPGCON &amp; ~(0&#215;3 &lt;&lt; 6);<br />
rGPGCON = rGPGCON | (0&#215;2 &lt;&lt; 6);// set eint13 falling edge trigger<br />
rEXTINT1 &amp;= ~(0&#215;7 &lt;&lt; 20);<br />
rEXTINT1 |= (0&#215;2 &lt;&lt; 20);// set eint11 falling edge trigger<br />
rEXTINT1 &amp;= ~(0&#215;7 &lt;&lt; 12);<br />
rEXTINT1 |= (0&#215;2 &lt;&lt; 12);// clear eint 11,13 &#8211;&gt; clear by writing &#8220;1&#8243; test<br />
rEINTPEND |= (1 &lt;&lt; 11)|(1 &lt;&lt; 13);// enable eint 11,13<br />
rEINTMASK &amp;= ~((1 &lt;&lt; 11)|(1 &lt;&lt; 13));<br />
rSRCPND = (0&#215;1&lt;&lt;5); // Clear pending bit &#8211;&gt; clear by writing &#8220;1&#8243; test<br />
rINTPND = (0&#215;1&lt;&lt;5); // Clear pending bit &#8211;&gt; clear by writing &#8220;1&#8243; testpISR_EINT8_23 = (U32)isr_eint_8_23;<br />
// Enable EINT8_23 Interrupt<br />
rINTMSK &amp;= ~((0&#215;1&lt;&lt;5));}</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong><span style="color: #3366ff">5.5 Timer</span></strong></p>
<p>임베디드 시스템에서 Timer는 가장 중요하고 필수적인 요소중의 하나로 OS에서 Task 스케줄링을 위해서 사용되기도 합니다. 전자액자, 차량용 블랙박스 등의 응용 어플리케이션에서도 특정 시간 이후에 인터럽트를 발생시켜 정해진 일을 수행하는 경우등 응용분야는 무수히 많습니다.<br />
시간 이야기가 나와서 이야기 하는데 CPU의 클럭 속도가 1Hz 라는 것은 무엇을 의미하는 것일까요? 이것은 1초에 1번의 Tick이 발생한다는 것입니다. 아주 정확한 것은 아니지만 캐시가 있는 시스템에서 캐시 Hit(캐시에서 데이터 혹은 명령어를 가지고 올 경우)일 경우에 1초에 1개의 명령어를 수행한다는 것과 같습니다. S3C2440이 400MHz 로 동작한다면 1초에 4억번의 Tick이 발생하는 것입니다. 정말 어마어마 하지요. 상상해 보세요. 요즘 최신 스마트폰들은 2GHz CPU이면서 그것도 듀얼 코어입니다. 아래는 시간과 주파수 사이의 관계입니다. Timer 설정하는데 이정도는 알고 있어야 합니다. 잘 기억하시기 바랍니다.</p>
<p>- 1sec = 1,000ms = 1,000,000us = 1,000,000,000ns<br />
- 1Hz = 1KHz = 1MHz = 1GHz</p>
<p><span style="text-decoration: underline">실험예제</span><br />
S3C2440 CPU의 내장된 Timer4를 이용해서 1초에 한번씩 Timer 인터럽트를 발생시켜 LDE2를 Blink(On/Off) 하는 실험을 해보도록 하겠습니다.</p>
<p><span style="color: #33cccc">(1) TCFG0 레지스터의 Timer4 Prescaler를 15로 설정합니다.</span></p>
<p><strong>Timer CONFIGURATION REGISTER0 (TCFG0)</strong><br />
Timer input clock Frequency = PCLK/{prescaler value+1}/{divider value}<br />
{prescaler value} = 0~255<br />
{divider value} = 2,4,8,16</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm025.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13708" alt="18feajkarm025" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm025.jpg" width="451" height="244" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// Timer4 Prescaler = 15<br />
rTCFG0 = 0&#215;0;<br />
rTCFG0 = (15 &lt;&lt; 8);</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(2) TCFG1 레지스터의 Timer4 Divider를 1/2 로 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm026.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13709" alt="18feajkarm026" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm026.jpg" width="453" height="337" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// Timer4 Divider = 2<br />
rTCFG1 = 0&#215;0;<br />
rTCFG1 = (0&#215;0 &lt;&lt; 16);</td>
</tr>
</tbody>
</table>
<p>위와 같이 설정하면 Datasheet 에 있는 아래 공식에 의해서</p>
<p>Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}<br />
Timer input clock Frequency = 50000000/(15+1)/2 = 1562500</p>
<p>위의 계산식의 의미는 Timer4의 클럭이 1초에 1562500번 발생 한다는 의미입니다. 그러므로 Timer4 buffer count(TCNTB4)를 15625 로 설정해 주면 10ms마다 Auto Reload(Timer Overflow)가 되어 인터럽트가 발생하게 됩니다. 물론 간단하게 TCNTB4를 1562500로 설정해 주면 1초에 한번 발생하는 인터럽트를 만들 수 있겠지만, 안타깝게도 S3C2440의 타이머는 16비트 타이머이므로 최대 값으로 0xFFFF(65535) 이상을 사용할 수가 없습니다.</p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(3) TCNTB4 레지스터에 Timer4 buffer count를 15625로 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm027.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13710" alt="18feajkarm027" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm027.jpg" width="454" height="147" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// buffer count<br />
rTCNTB4 = 15625; // interrupt resolution 10msec</td>
</tr>
</tbody>
</table>
<p><span style="color: #33cccc">(4) TCON 레지스터에 Update TCNTB4와 Auto Reload를 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm028.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13711" alt="18feajkarm028" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm028.jpg" width="453" height="245" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(5) TCON 레지스터를 설정하여 Timer를 Start 시킵니다.</span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// Start Timer 4<br />
rTCON |= (1&lt;&lt;20);</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(6) TCON에서 Manual Update를 해제하고 INTMSK에서 인터럽트 마스크를 Clear 시킵니다.</span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>// clean manual update<br />
rTCON &amp;= ~(1&lt;&lt;21);// Enable interrupt<br />
rINTMSK &amp;= ~(0&#215;1&lt;&lt;14);</td>
</tr>
</tbody>
</table>
<p>이렇게 하면 Timer4 인터럽트가 10msec마다 한번씩 발생하게 됩니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm040.jpg" rel="lightbox[13757]"><img class="alignnone size-large wp-image-13726" alt="18feajkarm040" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm040-620x343.jpg" width="620" height="343" /></a><br />
diag.c &#8211; timer4_test()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>__irq __arm void isr_timer4(void)<br />
{<br />
rSRCPND = BIT_TIMER4; //Clear pending bit<br />
rINTPND = BIT_TIMER4;// Timer가 10msec 마다 발생하므로 1초에 한번씩 toggle 시키기 위해서<br />
if( ++one_seconds_var == 100 )<br />
{<br />
rGPBDAT = rGPBDAT ^ (0&#215;1 &lt;&lt; 6); // toggle LED2<br />
one_seconds_var = 0;<br />
}void timer4_test(void)<br />
{/*<br />
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}<br />
{prescaler value} = 0~255<br />
{divider value} = 2, 4, 8, 16<br />
period = (prescaler value + 1) * (divider value) * buffer count / PCLK = 10 ms<br />
e.g.; PCLK = 50 Mhz<br />
10 ms = (15 + 1) * 2 * 15625 / (50000 * 1000)<br />
15626 = 10 ms * (50000 * 1000) / 2 / (15 + 1)<br />
*/// Timer4 Prescaler = 15<br />
rTCFG0 = 0&#215;0;<br />
rTCFG0 = (15 &lt;&lt; 8);// Timer4 Divider = 2<br />
rTCFG1 = 0&#215;0;<br />
rTCFG1 = (0&#215;0 &lt;&lt; 16); // Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value} // 50000000/(15+1)/2 = 1562500 &#8211;&gt; 1초에 발생하는 Timer Tick// buffer count<br />
rTCNTB4 = 15625; // interrupt resolution 10msecrTCON = rTCON &amp; ~(0xffffff) | 0&#215;1&lt; rTCON = rTCON | (1 &lt;&lt; 22); // Auto reloadpISR_TIMER4 = (int)isr_timer4;// Start Timer 4<br />
rTCON |= (1&lt;&lt;20);// clean manual update<br />
rTCON &amp;= ~(1&lt;&lt;21);// Enable interrupt<br />
rINTMSK &amp;= ~(0&#215;1&lt;&lt;14);</p>
<p>}</td>
</tr>
</tbody>
</table>
<p>여기서 잠깐! 일반함수와 &#8220;__irq __arm&#8221; 가 있는 함수의 차이점은 무엇일까요?</p>
<p><span style="text-decoration: underline">일반 함수의 Return 부분</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm039.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13725" alt="18feajkarm039" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm039.jpg" width="525" height="71" /></a></p>
<p><span style="text-decoration: underline">ISR 함수의 Return 부분</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm048.png" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13769" alt="18feajkarm048" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm048.png" width="524" height="121" /></a><br />
ISR 함수는 ARM Architecture에서 배운대로 Return을 SUBS PC,LR,#4로 하고 있습니다. 잘 기억이 나지 않으시면 ARM Architecture 자료에서 Pipeline과 Interrupt 부분을 다시 보시기 바랍니다.</p>
<p><span style="color: #3366ff"><strong>5.6 PWM Buzzer</strong></span></p>
<p>Buzzer, LED 등의 밝기 조정 등에 응용할 수 있습니다.</p>
<p><span style="text-decoration: underline">실험예제</span><br />
Buzzer을 울리도록 하고 외부 인터럽트 방식으로 Key K2를 누르면 주파수를 10Hz 올리고 K3를 누르면 10Hz 주파수가 내려가도록 해봅시다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm049.png" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13768" alt="18feajkarm049" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm049.png" width="404" height="268" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(1) GPBCON 레지스터에서 GPB0를 TOUT0(Timer0 Output)으로 설정합니다.</span></p>
<p><span style="color: #33cccc"><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm029.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13712" alt="18feajkarm029" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm029.jpg" width="454" height="242" /></a></span></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rGPBCON &amp;= ~0&#215;3; // set GPB0 as tout0, pwm output<br />
rGPBCON |= 0&#215;2;</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(2) TCFG0 레지스터의 Timer0 Prescaler를 15로 설정합니다.</span></p>
<p><strong>PWM TIMER CONTROL REGISTERS</strong><br />
<strong>TIMER CONFIGURATION REGISTER0 (TCFG0)</strong><br />
Timer input clock Frequency = PCLK /{prescaler value+1} / {divider value}<br />
{prescaler value} = 0~255<br />
{divider value} = 2, 4, 8, 16</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm030.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13713" alt="18feajkarm030" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm030.jpg" width="453" height="258" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rTCFG0 &amp;= ~0xff;<br />
rTCFG0 |= 15; // prescaler = 15+1</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(3) Timer0의 Divider 를 1/8 로 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm031.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13714" alt="18feajkarm031" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm031.jpg" width="453" height="98" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rTCFG1 &amp;= ~0xf;<br />
rTCFG1 |= 2; // mux = 1/8</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(4) Timer0의 Count buffer register, compare buffer register를 설정합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm032.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13715" alt="18feajkarm032" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm032.jpg" width="451" height="262" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rTCNTB0 = (Pclk&gt;&gt;7)/buzzer_freq;<br />
rTCMPB0 = rTCNTB0&gt;&gt;1; // rTCNTB0/2</td>
</tr>
</tbody>
</table>
<p>여기까지 설정을 하면 아래와 같이 1KHz의 주파수가 만들어집니다.</p>
<p>Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}<br />
Timer input clock Frequency = 50000000/(15+1)/8 = 390625 → 1초에 발생하는 Timer Tick</p>
<p>50000000Hz(PCLK) &gt;&gt; 7 = 390625 → 결국은 1초에 1번 1Hz값, buzzer_freq(1000)으로 나누어 주면 TCNTBn은 1KHz가 됩니다.</p>
<p>추가로 TCMPBn은 TCNTBn/2로 하면 최종적으로 1KHz인 Timer0(TOUT0)으로 1KHz인 PWM 파형이 출력됩니다.</p>
<p>&nbsp;</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm050.png" rel="lightbox[13757]"><img class="alignnone  wp-image-13767" alt="18feajkarm050" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm050.png" width="519" height="221" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(5) Timer0를 Start 시킵니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm033.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13716" alt="18feajkarm033" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm033.jpg" width="452" height="298" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rTCON &amp;= ~0x1f;<br />
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&amp;TCMPB0, start timer 0<br />
rTCON &amp;= ~2; //clear manual update bit</td>
</tr>
</tbody>
</table>
<p>diag.c &#8211; pwm_buzzer_test()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>__irq __arm void isr_eint_8_23(void)<br />
{if(rINTPND==BIT_EINT8_23)<br />
{<br />
ClearPending(BIT_EINT8_23);if(rEINTPEND&amp;(1&lt;&lt;11)) // KEY2<br />
{<br />
rEINTPEND |= 1 &lt;&lt; 11;<br />
rGPBDAT = rGPBDAT ^ (0&#215;1 &lt;&lt; 6); // LED2 togglebuzzer_freq += 100;<br />
pwm_buzzer_test();<br />
}<br />
if(rEINTPEND&amp;(1&lt;&lt;13)) // KEY3<br />
{<br />
rEINTPEND |= 1 &lt;&lt; 13;<br />
rGPBDAT = rGPBDAT ^ (0&#215;1 &lt;&lt; 7); // LED3 togglebuzzer_freq -= 100;<br />
pwm_buzzer_test();<br />
}<br />
}<br />
}void pwm_buzzer_test(void)<br />
{<br />
rGPBCON &amp;= ~0&#215;3; // set GPB0 as tout0, pwm output<br />
rGPBCON |= 0&#215;2;rTCFG0 &amp;= ~0xff;<br />
rTCFG0 |= 15; // prescaler = 15+1rTCFG1 &amp;= ~0xf;<br />
rTCFG1 |= 2; // mux = 1/8// Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}<br />
// 50000000/(15+1)/8 = 390625 &#8211;&gt; 1초에 발생하는 Timer Tick// PCLK = 50000000Hz &gt;&gt; 7 = 390625 &#8211;&gt; 결국은 1초에 1번 1Hz 값이다.<br />
// buzzer_freq(1000) 으로 나누어 주면 1KHz가 된다.<br />
rTCNTB0 = (PCLK&gt;&gt;7)/buzzer_freq;rTCMPB0 = rTCNTB0&gt;&gt;1; // rTCNTB0/2</p>
<p>rTCON &amp;= ~0x1f;<br />
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&amp;TCMPB0, start timer 0<br />
rTCON &amp;= ~2; //clear manual update bit<br />
}</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><strong style="color: #3366ff">5.7 UART</strong></p>
<p>임베디드 프로그램에서 Timer와 함께 UART도 필수적인 인터페이스입니다. 개발초기에 디버그 모니터용으로 활용하기도 하고 개발이 완료된 이후에는 제품의 Setting, Firmware 업그레이드 등에도 활용합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm051.png" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13771" alt="18feajkarm051" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm051.png" width="348" height="242" /></a></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm052.png" rel="lightbox[13757]"><img class="alignnone  wp-image-13770" alt="18feajkarm052" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm052.png" width="565" height="303" /></a></p>
<p><span style="text-decoration: underline">실험예제</span><br />
UART0를 PC와 115200bps Baudrate로 통신(RX, TX)을 하는 Echo server로 만들어 봅시다.</p>
<p><span style="color: #33cccc">(1) GPH2를 TXD로 GPH3을 RXD로 설정하고, GPH의 Pullup을 Disable 합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm034.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13717" alt="18feajkarm034" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm034.jpg" width="453" height="341" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rGPHCON &amp;= ~( (0&#215;3 &lt;&lt; 6) | (0&#215;3 &lt;&lt; 4) );<br />
rGPHCON |= ( (0&#215;2 &lt;&lt; 6) | (0&#215;2 &lt;&lt; 4) );<br />
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(2) UART0의 FIFO Buffer를 Disable 합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm035.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13718" alt="18feajkarm035" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm035.jpg" width="455" height="446" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rUFCON0 = 0&#215;0; //UART channel 0 FIFO control register, FIFO disable</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(3) UART0의 Auto Flow Control을 Disable 합니다.</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm036.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13719" alt="18feajkarm036" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm036.jpg" width="452" height="460" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rUMCON0 = 0&#215;0; //UART chaneel 0 MODEM control register, AFC disable</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(4) UART Line Control Regier 설정</span> <span style="color: #33cccc">(Normal Mode, No Parity, One Stop Bit, Word Length = 8)</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm037.jpg" rel="lightbox[13757]"><img class="alignnone size-large wp-image-13720" alt="18feajkarm037" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm037-437x620.jpg" width="437" height="620" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rULCON0 = 0&#215;3; //Line control register : Normal,No parity,1 stop,8 bits</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(5) UART Control Regier 설정</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm038.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13721" alt="18feajkarm038" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm038.jpg" width="451" height="906" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rUCON0 = (0&#215;0 &lt;&lt; 10) | (0&#215;1 &lt;&lt; 6) | (0&#215;0 &lt;&lt; 5) | (0&#215;0 &lt;&lt; 4) | (0&#215;1 &lt;&lt; 2) | (0&#215;1 &lt;&lt; 0);</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p><span style="color: #33cccc">(6) UART Baudrate Divisor Register 설정</span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm047.jpg" rel="lightbox[13757]"><img class="alignnone size-full wp-image-13764" alt="18feajkarm047" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/18feajkarm047.jpg" width="451" height="211" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26</td>
</tr>
</tbody>
</table>
<p>UBRDIV = (int)( UART clock / ( buad rate x 16) ) -1<br />
( UART clock : PCLK, FCLK/n or UEXTCLK )</p>
<p>우리는 UART Clock으로 PCLK 50MHz(50000000)을 사용하고 있으므로 계산식은 다음과 같습니다.</p>
<p>UBRDIV = ( PCLK / (115200*16) ) &#8211; 1 = 26</p>
<p>diag.c &#8211; uart0_test()</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<td>void uart0_send_byte(int data)<br />
{<br />
while(!(rUTRSTAT0 &amp; 0&#215;2)); //Wait until THR is empty.<br />
Delay(10);<br />
WrUTXH0(data);}void uart0_test(unsigned int baud)<br />
{<br />
rGPHCON &amp;= ~( (0&#215;3 &lt;&lt; 6) | (0&#215;3 &lt;&lt; 4) );<br />
rGPHCON |= ( (0&#215;2 &lt;&lt; 6) | (0&#215;2 &lt;&lt; 4) );rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]rUFCON0 = 0&#215;0; //UART channel 0 FIFO control register, FIFO disable<br />
rUMCON0 = 0&#215;0; //UART chaneel 0 MODEM control register, AFC disable//UART0<br />
rULCON0 = 0&#215;3; //Line control register : Normal,No parity,1 stop,8 bitsrUCON0 = (0&#215;0 &lt;&lt; 10) | (0&#215;1 &lt;&lt; 6) | (0&#215;0 &lt;&lt; 5) | (0&#215;0 &lt;&lt; 4) | (0&#215;1 &lt;&lt; 2) | (0&#215;1 &lt;&lt; 0);rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26while(!(rUTRSTAT0 &amp; 0&#215;4)); //Wait until tx shifter is empty.uart0_send_byte(&#8216;E&#8217;);<br />
uart0_send_byte(&#8216;c&#8217;);<br />
uart0_send_byte(&#8216;h&#8217;);<br />
uart0_send_byte(&#8216;o&#8217;);<br />
uart0_send_byte(&#8216;\r&#8217;);<br />
uart0_send_byte(&#8216;\n&#8217;);while(1)<br />
{<br />
Delay(10);<br />
while(!(rUTRSTAT0 &amp; 0&#215;1)); //Receive data ready<br />
uart0_send_byte((*(volatile unsigned char *)0&#215;50000024));<br />
}</p>
<p>}</td>
</tr>
</tbody>
</table>
<p>위의 코드는 터미널창에 &#8220;Echo&#8221; 를 Display 하고 터미널에서 입력한 문자를 바로 Echo 하여 다시 터미널 창에 표시하게 됩니다.</p>
<p>&nbsp;</p>
<p><span style="background-color: #ffff00"><strong>이것으로 ARM Applications 4부를 마치며, </strong></span><br />
<span style="background-color: #ffff00"><strong>다음호에서는 III. Cortex-M3 Architecture에 대하여 살펴보도록 하겠습니다. </strong></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/13757/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[17호]JK전자와 함께하는 ARM 완전정복(3)-3</title>
		<link>http://www.ntrexgo.com/archives/13367</link>
		<comments>http://www.ntrexgo.com/archives/13367#comments</comments>
		<pubDate>Sun, 10 Mar 2013 06:20:23 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[17호]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[jk전자]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=13367</guid>
		<description><![CDATA[디바이스마트 매거진 17호 &#124; 3부 3편. 자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다.]]></description>
				<content:encoded><![CDATA[<table style="width: 600px" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자.jpg" rel="lightbox[13367]"><img class="alignnone  wp-image-13318" alt="jk전자" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자-300x222.jpg" width="192" height="142" /></a></td>
<td><span style="color: #000080"><strong><span style="font-size: large">JK전자와 함/께/하/는 ARM 완전 정복</span></strong></span><span style="color: #666699"><strong><span style="line-height: 19px">Ⅱ.ARM Applications &#8211; 1부</span></strong></span>글 | JK전자</td>
</tr>
</tbody>
</table>
<p><span style="color: #008000;background-color: #ffff99"><strong>4. 개발환경 설정</strong></span></p>
<p><strong><span style="color: #008000">4.1 IAR Workbench 개발환경 설정</span></strong></p>
<p>ARM Simulator 기반의 실습 프로젝트와 유사하지만 디버거 설정 부분과 Pre-include directory 설정 등이 추가됩니다.<br />
<span style="background-color: #ffff00">(1) Create New Project</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK060.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13291" alt="17featureJK060" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK060-620x446.jpg" width="620" height="446" /></a></p>
<p><span style="background-color: #ffff00">(2) Empty project 생성</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK061.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13292" alt="17featureJK061" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK061.jpg" width="408" height="347" /></a></p>
<p><span style="background-color: #ffff00">(3) 프로젝트 파일이름 입력 &#8211; “mini2440_test”</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK062.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13293" alt="17featureJK062" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK062-620x435.jpg" width="620" height="435" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK077.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13308" alt="17featureJK077" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK077-620x428.jpg" width="620" height="428" /></a></p>
<p><span style="background-color: #ffff00">(4) 그룹생성 &#8211; “base”, “testcode”그룹 생성</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK078.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13309" alt="17featureJK078" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK078-620x427.jpg" width="620" height="427" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK079.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13310" alt="17featureJK079" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK079-620x428.jpg" width="620" height="428" /></a></p>
<p><span style="background-color: #ffff00">(5) 소스 파일추가</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK080.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13311" alt="17featureJK080" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK080-620x428.jpg" width="620" height="428" /></a><br />
- “base”그룹 : base 폴더 안의 *.s, *.c 파일들 추가<br />
- “testcode”그룹 : testcode 폴더 안의 *.c 파일들 추가<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK081.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13312" alt="17featureJK081" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK081-620x428.jpg" width="620" height="428" /></a></p>
<p><span style="background-color: #ffff00">(6) 프로젝트 옵션 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK082.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13313" alt="17featureJK082" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK082-620x429.jpg" width="620" height="429" /></a></p>
<p><span style="background-color: #ffff99">(6.1) Target Device 설정 : Samsung S3C2440A로 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK066.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13297" alt="17featureJK066" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK066-620x437.jpg" width="620" height="437" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK067.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13298" alt="17featureJK067" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK067.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(7) Processor Mode 설정 : “ARM”모드로 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK068.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13299" alt="17featureJK068" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK068.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(8) C/C++ Compiler Pre-include 디렉토리 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK084.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13315" alt="17featureJK084" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK084.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(9) Assembler Pre-include 디렉토리 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK085.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13316" alt="17featureJK085" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK085.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(10) Scattor Loading 파일 설정 : 프로젝트 디렉토리에 “mini2440_lnk.icf”파일을 선택합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK083.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13314" alt="17featureJK083" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK083.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(11) Program Start Entry 설정 : “ __program_start”라고 입력합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK070.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13301" alt="17featureJK070" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK070.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(12) 디버깅 정보를 포함하도록 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK071.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13302" alt="17featureJK071" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK071.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(13) Map 파일을 생성하도록 합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK072.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13303" alt="17featureJK072" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK072.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(14) Debugger 정보 설정 : Dirver &#8211; Simulator, Run to main은 반드시 설정 해제합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK073.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13304" alt="17featureJK073" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK073-620x456.jpg" width="620" height="456" /></a></p>
<p><span style="color: #339966"><strong>4.2 JTAG 을 이용한 프로그램 다운로드</strong></span></p>
<p><span style="color: #99cc00"><strong>4.2.1 ARM-JTAG을 이용한 프로그램 다운로드 </strong></span></p>
<p><span style="background-color: #ffff00">(1) ARM-JTAG Standard 버젼 이상을 사용해야 합니다.</span></p>
<p><span style="background-color: #ffff00">(2) IAR 개발환경에서 Debugger를 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK074.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13305" alt="17featureJK074" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK074-620x446.jpg" width="620" height="446" /></a><br />
RDI Driver를 JICE.dll 로 설정합니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK075.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13306" alt="17featureJK075" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK075-620x446.jpg" width="620" height="446" /></a></p>
<p><span style="background-color: #ffff00">(3) Windows7 사용자일 경우 IAR IDE 프로그램과, JICE Server의 실행 환경을 관리자 권한으로 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK048.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13279" alt="17featureJK048" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK048-620x367.jpg" width="620" height="367" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK049.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13280" alt="17featureJK049" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK049-620x430.jpg" width="620" height="430" /></a></p>
<p><span style="background-color: #ffff00">(4) JICE Server 를 실행한 후 Target Detect 를 합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK050.jpg" rel="lightbox[13367]"><img class="alignnone size-full wp-image-13281" alt="17featureJK050" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK050.jpg" width="410" height="400" /></a></p>
<p><span style="background-color: #ffff00">(5) IAR Workbench 에서 “Download and Debugging”을 실행합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK051.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13282" alt="17featureJK051" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK051-620x401.jpg" width="620" height="401" /></a></p>
<p>위와 같은 화면이 나왔으면 정상적으로 실행이 완료된 상태입니다. 참고로 “mini2440_lnk.icf”파일은 S3C2440의 RAM(0&#215;30000000)영역에서 실행이 되도록 되어 있습니다. NOR 플래시에 다운로드해서 실행을 할 수도 있지만 NOR 플래시도 10만번 이상 Erase하게 되면 수명이 다하기 때문에 테스트용으로는 주로 RAM에서 실행되도록 합니다.</p>
<p><span style="background-color: #ffff00">(6) NOR 플래시에 프로그램을 다운로드 하는 방법</span><br />
- “mini2440_lnk.icf”파일에서 “define symbol EXECUTE_IN_SDRAM=1;”부분을 “define symbol EXECUTE_IN_SDRAM=0;”으로 수정합니다.<br />
- IAR 프로젝트를 Rebuild 합니다.<br />
- jcs 스크립트 파일에서 “mini2440_test.bin”파일의 이름과 경로를 수정합니다.<br />
- JICE Commander를 실행 -&gt; Script Run -&gt; “S3C2440_NOR(SST39VF1601)_PROGRAM_WITH_FLASHAGENT.jcs”를 실행합니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK052.jpg" rel="lightbox[13367]"><img class="alignnone size-large wp-image-13283" alt="17featureJK052" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK052-620x215.jpg" width="620" height="215" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small"><strong>■ 이것으로 ARM Applications 1부를 마치며, 다음호에는 아래 내용에 대하여 살펴보도록 하겠습니다.</strong></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/13367/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[17호]JK전자와 함께하는 ARM 완전정복(3)-2</title>
		<link>http://www.ntrexgo.com/archives/13348</link>
		<comments>http://www.ntrexgo.com/archives/13348#comments</comments>
		<pubDate>Sun, 10 Mar 2013 05:43:18 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[17호]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[jk전자]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=13348</guid>
		<description><![CDATA[디바이스마트 매거진 17호 &#124; 3부 2편. 자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다.]]></description>
				<content:encoded><![CDATA[<table style="width: 600px" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자.jpg" rel="lightbox[13348]"><img class="alignnone wp-image-13318" alt="jk전자" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자-300x222.jpg" width="192" height="142" /></a></td>
<td><span style="color: #000080"><strong><span style="font-size: large">JK전자와 함/께/하/는 ARM 완전 정복</span></strong></span><span style="color: #666699"><br />
<strong><span style="line-height: 19px">Ⅱ.ARM Applications &#8211; 1부</span></strong></span>글 | JK전자</td>
</tr>
</tbody>
</table>
<p><span style="background-color: #ffff99;color: #008000"><strong>2. 어셈블리어 실습</strong></span></p>
<p><span style="color: #339966"><strong>2.1 ARM Simulator 환경 설정</strong></span></p>
<p>IAR ARM용 컴파일러는 가격이 그렇게 싸지는 않습니다. 다행히도 www.iar.com 에서 시간 제한(30일), 사이즈 제한(32Kbyte) 버젼을 다운 받아서 사용해 볼 수 있습니다.</p>
<p><span style="color: #99cc00"><strong>2.1.1 IAR Evaluation 버젼 다운로드</strong></span><br />
- 다운로드 사이트 방문<br />
<a href="http://supp.iar.com/Download/SW/?item=EWARM-EVAL" target="_blank">http://supp.iar.com/Download/SW/?item=EWARM-EVAL</a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK034.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13265" alt="17featureJK034" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK034-620x372.jpg" width="620" height="372" /></a><br />
패키지 사이즈가 약 830MB정도 입니다. 다운 받아서 설치하시기 바랍니다.</p>
<p>다음은 Evaluation 버젼을 다운로드 받기 위한 절차대로 화면을 캡쳐해 놓은 것입니다. 참조하시기 바랍니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK057.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13288" alt="17featureJK057" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK057-620x434.jpg" width="620" height="434" /></a><br />
반드시 “Code size limited”를 선택하시기 바랍니다. 그렇지 않으면 30일 이후에 더이상 IAR 컴파일러를 사용할 수 없게 됩니다.</p>
<p><span style="background-color: #ffff00">(2) IAR Evaluation 버젼 설치 </span></p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK054.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13285" alt="17featureJK054" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK054-620x387.jpg" width="620" height="387" /></a><br />
설치가 완료되면 마지막에 License 를 입력하는 화면이 나옵니다. 여기에서 “Register with IAR System to get an evaluation license”를 선택하시기 바랍니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK055.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13286" alt="17featureJK055" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK055-620x387.jpg" width="620" height="387" /></a><br />
현재 설치된 제품 중에 라이센스가 없는 제품의 리스트가 나옵니다. 선택을 하고 “다음”으로 진행합니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK056.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13287" alt="17featureJK056" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK056-620x387.jpg" width="620" height="387" /></a><br />
IAR Evaluation 버젼을 다운받기 위해서 입력했던 Email 주소로 Registeration Confirm 메일이 와있을 것입니다.<br />
Confirm 메일에 있는 Confirm 링크를 클릭하면 “Registration Complete”와 함께 Evaluation License 번호를 알 수가 있습니다. 그 번호를 위의 화면의 빈 칸에 입력하고 나서 “Regiser”버튼을 누르면 잠시 후에 네트워크를 통해서 Evaluation 라이센스 번호를 받게 됩니다. 경우에 따라서 Fail 이라는 메세지가 나올 수도 있습니다. 그때는 “Register”버튼을 다시 한번 클릭해서 재시도해 보시기 바랍니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK058.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13289" alt="17featureJK058" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK058-620x387.jpg" width="620" height="387" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK059.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13290" alt="17featureJK059" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK059-620x387.jpg" width="620" height="387" /></a><br />
모든 설치가 완료된 화면입니다.</p>
<p><span style="color: #99cc00"><strong>2.1.2 ARM Simulator 프로젝트 생성</strong></span><br />
아래 화면대로 따라서 ARM Simulator 기반의 실습 프로젝트를 생성해 보시기 바랍니다.</p>
<p><span style="background-color: #ffff00">(1) Create New Project</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK060.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13291" alt="17featureJK060" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK060-620x446.jpg" width="620" height="446" /></a></p>
<p><span style="background-color: #ffff00">(2) Empty project 생성<strong> </strong></span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK061.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13292" alt="17featureJK061" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK061.jpg" width="408" height="347" /></a></p>
<p><span style="background-color: #ffff00">(3) 프로젝트 파일이름 입력 &#8211; “arm_simulator”</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK062.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13293" alt="17featureJK062" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK062-620x435.jpg" width="620" height="435" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK063.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13294" alt="17featureJK063" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK063-620x447.jpg" width="620" height="447" /></a></p>
<p><span style="background-color: #ffff00">(4) 그룹생성 &#8211; “base”, “testcode”그룹 생성</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK064.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13295" alt="17featureJK064" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK064-620x444.jpg" width="620" height="444" /></a><br />
- “base”그룹 : 2440init_ewarm.s 추가<br />
- “testcode”그룹 : main.c, SegInit.c 추가</p>
<p><span style="background-color: #ffff00">(6) 프로젝트 옵션 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK065.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13296" alt="17featureJK065" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK065-620x445.jpg" width="620" height="445" /></a></p>
<p><span style="background-color: #ffff99">(6.1) Target Device 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK066.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13297" alt="17featureJK066" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK066-620x437.jpg" width="620" height="437" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK067.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13298" alt="17featureJK067" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK067.jpg" width="614" height="474" /></a><br />
Samsung S3C2440A 로 설정합니다.</p>
<p><span style="background-color: #ffff00">(7) Processor Mode 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK068.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13299" alt="17featureJK068" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK068.jpg" width="614" height="474" /></a><br />
“ARM”모드로 설정합니다.</p>
<p><span style="background-color: #ffff00">(8) Scattor Loading 파일 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK069.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13300" alt="17featureJK069" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK069.jpg" width="614" height="474" /></a><br />
프로젝트 디렉토리에 “arm_simulator.icf”파일을 선택합니다.</p>
<p><span style="background-color: #ffff00">(9) Program Start Entry 설정</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK070.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13301" alt="17featureJK070" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK070.jpg" width="614" height="474" /></a><br />
“ __program_start”라고 입력합니다.</p>
<p><span style="background-color: #ffff00">(10) 디버깅 정보를 포함하도록 설정합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK071.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13302" alt="17featureJK071" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK071.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(11) Map 파일을 생성하도록 합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK072.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13303" alt="17featureJK072" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK072.jpg" width="614" height="474" /></a></p>
<p><span style="background-color: #ffff00">(12) Debugger 정보 설정 : Dirver &#8211; Simulator, Run to main은 반드시 설정 해제합니다.</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK073.jpg" rel="lightbox[13348]"><img class="alignnone size-large wp-image-13304" alt="17featureJK073" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK073-620x456.jpg" width="620" height="456" /></a></p>
<p><span style="color: #339966"><strong>2.2 Data Processing Instructions</strong></span></p>
<p>2장에서는 ARM Simulator를 활용한 어셈블리어 실습을 해보도록 하겠습니다. 이 내용들은 ARM Architecture Instruction의 이론 부분을 설명할 때 한번씩 나왔던 내용입니다. 여기서는 이론으로 공부했던 내용들을 실제로 ARM Simulator에서 코드를 작성한 후 컴파일하고 실행해서 결과 값을 직접 확인해 보는데 의미가 있습니다.</p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="5">
<tbody>
<tr>
<td>R0 = 0&#215;00<br />
R1 = 0&#215;22<br />
R2 = 0&#215;02<br />
R3 = 0&#215;00<br />
R4 = 0&#215;00</td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK000.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13231" alt="17featureJK000" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK000.jpg" width="388" height="150" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터 값이 위와 같을 때 아래 예제들을 차례대로 수행해 보세요.</p>
<p><span style="color: #000000;background-color: #ffff00">(1) AND R0, R0, #0xFF</span><br />
2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.</p>
<table style="width: 620px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td>SECTION IMAGE_STARTUP:CODE (2)<br />
PUBLIC __program_start<br />
CODE32<br />
__program_start<br />
b ResetHandler<br />
b HandlerUndef ;handler for Undefined mode<br />
b HandlerSWI ;handler for SWI interrupt<br />
b HandlerPabort ;handler for PAbort<br />
b HandlerDabort ;handler for DAbort<br />
b . ;reserved<br />
b HandlerIRQ ;handler for IRQ interrupt<br />
b HandlerFIQ ;handler for FIQ interrupt<br />
ResetHandler<br />
MOV R0, #0&#215;00<br />
MOV R1, #0&#215;22<br />
MOV R2, #0&#215;02<br />
MOV R3, #0&#215;00<br />
MOV R4, #0x00AND R0, R0, #0xFF<br />
ADD R0, R0, #1<br />
ADD R0, R0, R1<br />
LSL R1, R0, #2<br />
SUB R3, R2, R1, LSR R2HandlerFIQ<br />
b .HandlerIRQ<br />
b .HandlerUndef<br />
b .HandlerSWI<br />
b .HandlerDabort<br />
b .HandlerPabort<br />
b .END</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK000.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13231" alt="17featureJK000" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK000.jpg" width="388" height="150" /></a></p>
<p><span style="background-color: #ffff00">(2) ADD R0, R0, #1 ; R0 = R0 + 1 = 0&#215;1</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK001.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13232" alt="17featureJK001" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK001.jpg" width="396" height="148" /></a></p>
<p><span style="background-color: #ffff00">(3) ADD R0, R0, R1 ; R0 = R0 + R1 = 0&#215;01 + 0&#215;22 = 0&#215;23</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK002.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13233" alt="17featureJK002" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK002.jpg" width="406" height="148" /></a></p>
<p><span style="background-color: #ffff00">(4) LSL R1, R0, #2 ; 0&#215;23(100011) LSL #2 = 0x8C(10001100) -&gt; 참고로 왼쪽으로 2번 쉬프트 하면 *4 를 한 것과 같습니다.</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK003.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13234" alt="17featureJK003" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK003.jpg" width="408" height="146" /></a></p>
<p><span style="background-color: #ffff00">(5) SUB R3, R2, R1, LSR R2</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK004.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13235" alt="17featureJK004" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK004.jpg" width="405" height="148" /></a></p>
<p>R3의 값이 0xFFFFFFDF 로 복잡한 값이 나왔습니다. 왜 이런 결과가 나왔을까요? 우선 R1을 오른쪽으로 2번 쉬프트시키면 0&#215;23이 되고 R2(0&#215;02)에서 R1(0&#215;23)을 빼면 결과 값이 -0&#215;21가 되고 이 값을 2의 보수로 표시하면 0xFFFFFFDF가 됩니다.</p>
<p>0&#215;21 = 00000000000000000000000000100001<br />
-0&#215;21 = 11111111111111111111111111011111 &#8211;&gt; 0&#215;21의 2의 보수<br />
참고로 2의 보수를 취하는 방법은 원래의 2진수에서 0-&gt;1, 1-&gt;0 으로 바꾼 후에 1을 더하면 되겠지요.</p>
<p><span style="color: #339966"><strong>2.3 Multiply Instructions</strong></span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>R0 = 0&#215;01<br />
R1 = 0&#215;02<br />
R2 = 0&#215;03<br />
R3 = 0&#215;04</td>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK005.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13236" alt="17featureJK005" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK005.jpg" width="405" height="151" /></a></td>
</tr>
</tbody>
</table>
<p>레지스터 값이 위와 같을 때 아래 예제들을 차례대로 수행해보세요.</p>
<p><span style="background-color: #ffff00">(1) MUL R2, R0, R1 ; R2 = R0*R1 = 0&#215;02</span><br />
2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.</p>
<table style="width: 620px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, 0&#215;01<br />
MOV R1, 0&#215;02<br />
MOV R2, 0&#215;03<br />
MOV R3, 0x04MUL R2, R0, R1<br />
MULS R2, R0, R1<br />
MLA R3, R2, R1, R0</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK006.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13237" alt="17featureJK006" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK006.jpg" width="407" height="148" /></a></p>
<p><span style="background-color: #ffff00">(2) MULS R2, R0, R1 ; R2 = R0*R1 = 0&#215;02</span><br />
MUL 명령과 같은 명령입니다. 하지만 MUL뒤에 “S”가 붙으면 명령어 처리가 끝난 이후에 CPSR의 Flag Field가 연산 결과에 따라서 업데이트가 됩니다.<br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK006.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13237" alt="17featureJK006" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK006.jpg" width="407" height="148" /></a></p>
<p><span style="background-color: #ffff00">(3) MLA R3, R2, R1, R0 ; R3 = R2*R1 + R0</span><br />
참 효율적이네요. 명령어 하나로 곱하기 연산과 더하기 연산을 같이 할 수 있습니다.<br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK007.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13238" alt="17featureJK007" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK007.jpg" width="407" height="150" /></a></p>
<p><span style="color: #339966"><strong>2.4 Load/Store Instructions</strong></span></p>
<p><span style="color: #99cc00"><strong>2.4.1 Pre-index</strong></span><br />
R0 = 0&#215;31000000<br />
R1 = 0&#215;00<br />
R2 = 0&#215;00<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK008.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13239" alt="17featureJK008" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK008.jpg" width="407" height="149" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK009.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13240" alt="17featureJK009" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK009.jpg" width="387" height="181" /></a></p>
<p><span style="background-color: #ffff00">(1) LDR R1, [R0] ; R1 2440init_ewarm.s 파일에 다음과 같이 입력을 합니다.</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, 0&#215;31000000<br />
MOV R1, 0&#215;0<br />
MOV R2, 0x0LDR R1, [R0]
STR R1, [R0, #4]
STR R1, [R0, #4]!</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK010.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13241" alt="17featureJK010" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK010.jpg" width="408" height="146" /></a></p>
<p><span style="background-color: #ffff00">(2) STR R1, [R0, #4] ; R1</span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK011.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13242" alt="17featureJK011" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK011.jpg" width="385" height="120" /></a></p>
<p><span style="background-color: #ffff00">(3) STR R1, [R0, #4]! ; R1</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK012.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13243" alt="17featureJK012" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK012.jpg" width="403" height="150" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK013.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13244" alt="17featureJK013" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK013.jpg" width="388" height="121" /></a></p>
<p><span style="color: #99cc00"><strong>2.4.2 Post-index</strong></span><br />
R0 = 0&#215;31000000<br />
R1 = 0&#215;00<br />
R2 = 0&#215;04<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK014.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13245" alt="17featureJK014" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK014.jpg" width="393" height="148" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK009.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13240" alt="17featureJK009" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK009.jpg" width="387" height="181" /></a></p>
<p><span style="background-color: #ffff00">(1) LDR R1, [R0], R2 ; R1</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, 0&#215;31000000<br />
MOV R1, 0&#215;0<br />
MOV R2, 0x4LDR R1, [R0], R2<br />
STR R1, [R0], #4</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK015.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13246" alt="17featureJK015" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK015.jpg" width="394" height="149" /></a></p>
<p><span style="background-color: #ffff00">(2) STR R1, [R0], #4 ; R1</span><br />
- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK016.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13247" alt="17featureJK016" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK016.jpg" width="393" height="145" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK017.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13248" alt="17featureJK017" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK017.jpg" width="389" height="120" /></a></p>
<p><span style="color: #339966"><strong>2.5 Load/Store Multiple Instructions</strong></span></p>
<p>R0 = 0x000A<br />
R4 = 0x000B<br />
R5 = 0x000C<br />
R13 = 0xFFF0<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK035.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13266" alt="17featureJK035" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK035.jpg" width="402" height="172" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK036.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13267" alt="17featureJK036" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK036.jpg" width="392" height="170" /></a></p>
<p><span style="background-color: #ffff00">(1) STMIA R13!, {R0,R4-R5}</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #0x000A<br />
MOV R4, #0X000B<br />
MOV R5, #0x000C<br />
LDR R13, =0xFFF0STMIA R13!, {R0,R4-R5}</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK042.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13273" alt="17featureJK042" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK042.jpg" width="412" height="166" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK036.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13267" alt="17featureJK036" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK036.jpg" width="392" height="170" /></a></p>
<p><span style="background-color: #ffff00">(2) STMIB R13!, {R0,R4-R5}</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #0x000A<br />
MOV R4, #0X000B<br />
MOV R5, #0x000C<br />
LDR R13, =0xFFF0STMIB R13!, {R0,R4-R5}</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK043.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13274" alt="17featureJK043" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK043.jpg" width="402" height="167" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK038.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13269" alt="17featureJK038" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK038.jpg" width="392" height="171" /></a></p>
<p><span style="background-color: #ffff00">(3) STMDA R13!, {R0,R4-R5}</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #0x000A<br />
MOV R4, #0X000B<br />
MOV R5, #0x000C<br />
LDR R13, =0xFFF0STMDA R13!, {R0,R4-R5}</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK042.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13273" alt="17featureJK042" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK042.jpg" width="412" height="166" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK039.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13270" alt="17featureJK039" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK039.jpg" width="392" height="171" /></a></p>
<p><span style="background-color: #ffff00">(4) STMDB R13!, {R0,R4-R5}</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #0x000A<br />
MOV R4, #0X000B<br />
MOV R5, #0x000C<br />
LDR R13, =0xFFF0STMDB R13!, {R0,R4-R5}</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK041.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13272" alt="17featureJK041" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK041.jpg" width="406" height="171" /></a><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK040.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13271" alt="17featureJK040" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK040.jpg" width="386" height="167" /></a></p>
<p><span style="color: #339966"><strong>2.6 Branch Instructions</strong></span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandlersubsequent<br />
MOV R0, #1<br />
MOV R1, #2<br />
BL func1<br />
ADD R2, R0, R1func1<br />
MOV R0, #3<br />
MOV R1, #4<br />
BL func2<br />
ADD R2, R0, R1<br />
MOV PC, LRfunc2<br />
MOV R0, #5<br />
MOV R1, #6<br />
ADD R2, R0, R1<br />
MOV PC, LR</td>
</tr>
</tbody>
</table>
<p>위의 예제를 실행하면 R2 레지스터에 “3”이 저장이 되지 않습니다. R2 레지스터에 “3”이 저장이 될 수 있도록 예제를 수정해 보시기 바랍니다. 수정한 예제 코드는 아래와 같습니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK018.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13249" alt="17featureJK018" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK018.jpg" width="462" height="374" /></a><br />
서브 함수를 호출 할 경우에는 서브 함수에서 사용하는 레지스터와 LR 레지스터를 반드시 저장한 이후에 사용해야 한다는 것을 알 수 있습니다.</p>
<p><span style="color: #339966"><strong>2.7 Status Register Access Instructions</strong></span><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK019.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13250" alt="17featureJK019" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK019.jpg" width="413" height="227" /></a></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MRS R0, CPSR<br />
BIC R0, R0, #0&#215;80 ; 7번 비트를 clear 하면 인터럽트가 활성화 됩니다.<br />
MSR CPSR, R0</td>
</tr>
</tbody>
</table>
<p>- 실행 결과<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK020.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13251" alt="17featureJK020" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK020.jpg" width="411" height="227" /></a></p>
<p><span style="color: #339966"><strong>2.8 Conditional Execution</strong></span></p>
<p>지금까지 배운 모든 어셈블리어들을 활용해서 최종적으로 몇가지 예제를 풀어 보도록 하겠습니다. 예제를 구현하는데에는 여러가지 방법들이 많이 있겠지만 가장 최적화된 어셈블리 명령어를 사용하시기 바랍니다.</p>
<p><span style="background-color: #ffff00">(1) 1 ~ 10을 더하는 최적화된 어셈블리어로 작성해 보세요.</span></p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R5, #10<br />
MOV R6, #0<br />
loop_sum<br />
ADD R6, R6, R5<br />
SUBS R5, R5, #1<br />
BNE loop_sum ; Not Equal(Z=1)</td>
</tr>
</tbody>
</table>
<p>루프를 사용할 경우에는 거꾸로 도는 것이 효율적입니다.</p>
<p><span style="background-color: #ffff00">(2) 2개 변수 사이의 절대값을 구하세요.</span><br />
- [-2 - 3] 사이의 절대값</p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #-2<br />
MOV R1, #3SUBS R0, R0, R1V<br />
RSBMI R0, R0, #0</td>
</tr>
</tbody>
</table>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK046.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13277" alt="17featureJK046" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK046.jpg" width="612" height="172" /></a></p>
<p>“SUBS R0, R0, R1”명령을 실행했을 때의 그림입니다. R0, CPSR의 “N”Flag를 잘 살펴보시기 바랍니다. 참고로 RSBMI 명령어는 CPSR의 “N”Flag가 Set되어 있을 때 뺄셈을 하는데 SUB 명령과는 연산의 방향이 반대로 수행이 되는 명령어입니다. 그러니까 이번 예제에서는 “#0”에서 “R0”를 빼는 것입니다.</p>
<p>- [3 - 1] 사이의 절대값</p>
<table style="border-collapse: collapse;width: 620px" border="1" cellspacing="5" cellpadding="0">
<tbody>
<tr>
<td>ResetHandler<br />
MOV R0, #3<br />
MOV R1, #1SUBS R0, R0, R1<br />
RSBMI R0, R0, #0</td>
</tr>
</tbody>
</table>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK045.jpg" rel="lightbox[13348]"><img class="alignnone size-full wp-image-13276" alt="17featureJK045" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK045.jpg" width="611" height="172" /></a><br />
“SUBS R0, R0, R1”명령을 실행했을 때의 그림입니다. R0, CPSR의 “N”Flag를 잘 살펴 보시기 바랍니다.</p>
<p>3장에서는 우리가 실제로 실습에 사용할 S3C2440 ARM9 개발보드에 대해서 소개하도록 하겠습니다. ARM Simulator에서는 별다른 설정없이도 어셈블리어 실습을 할 수 있었으나 실제 타겟을 사용할 경우에는 개발보드의 메모리 컨트롤러, 부팅과정 등을 제대로 이해하고 있어야 코드 작성이 가능합니다. 실제 개발보드에서 실습을 하기 전에 S3C2440에 대해서 이론적으로 공부해보도록 하겠습니다.</p>
<p>&nbsp;</p>
<p style="text-align: right"><span style="color: #999999"> JK전자와 함께하는 ARM 완전정복(3)-2 에서 계속 됩니다.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/13348/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[17호]JK전자와 함께하는 ARM 완전정복(3)-1</title>
		<link>http://www.ntrexgo.com/archives/13132</link>
		<comments>http://www.ntrexgo.com/archives/13132#comments</comments>
		<pubDate>Sun, 10 Mar 2013 00:42:26 +0000</pubDate>
		<dc:creator>디바이스마트 매거진</dc:creator>
				<category><![CDATA[디바이스마트 매거진]]></category>
		<category><![CDATA[특집]]></category>
		<category><![CDATA[17호]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[arm]]></category>
		<category><![CDATA[jk전자]]></category>
		<category><![CDATA[매거진]]></category>

		<guid isPermaLink="false">http://www.ntrexgo.com/?p=13132</guid>
		<description><![CDATA[디바이스마트 매거진 17호 &#124; 3부 1편. 자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다.]]></description>
				<content:encoded><![CDATA[<table style="width: 600px" border="0">
<tbody>
<tr>
<td><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13318" alt="jk전자" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/jk전자-300x222.jpg" width="192" height="142" /></a></td>
<td><span style="color: #000080"><strong><span style="font-size: large">JK전자와 함/께/하/는 ARM 완전 정복</span></strong></span><span style="color: #666699"><strong><span style="line-height: 19px">Ⅱ.ARM Applications &#8211; 1부</span></strong></span>글 | JK전자</td>
</tr>
</tbody>
</table>
<p><span style="font-size: 13px;line-height: 19px">자료는 ARM을 처음 접하는 입문자로서 S/W 엔지니어 혹은 H/W 엔지니어를 대상으로 하였습니다. 처음에는 Cortex-M3 구조를 목표로 하였으나 전통적인 ARM(주로 ARM7, ARM9)의 구조에 대해서 먼저 이야기한 다음 Cortex-M3 구조에 대해서 하기로 마음을 고쳐 먹었습니다. Cortex-M3도 ARM 이기 때문에 전통적인 ARM의 구조에 대해서 잘 이해하고 Cortex-M3 구조와 비교해 보면서 공부한다면 큰 도움이 될 것입니다.</span></p>
<p>ARM Architecture 강의에서는 특정 CPU(S3C2440, STM32Fxx) 에 대한 내용 보다는 ARM Core의 이론적인 구조 자체에 대해서 많은 설명을 하였습니다. 이번 강의에서는 Samsung의 ARM9 CPU S3C2440 개발보드를 이용해서 실제 실습을 통해서 ARM에 대해서 공부해 보도록 하겠습니다.<br />
I. ARM Architecture ~ IV. Cortex-M3 Applications 까지 분명 쉽지 않은 지루하고도 먼 여행이 되겠지만 ARM을 공부하는 임베디드 관련 엔지니어라면 언젠가는 한 번은 넘어야 하는 산이라 생각됩니다. 부디 이 자료가 ARM을 정복하는데 조금이라도 도움이 되시길 바랍니다.</p>
<p>&nbsp;</p>
<p><span style="font-size: small;color: #f68412"><strong>강의 전체 로드맵</strong></span></p>
<p>I. ARM Architecture | 임베디드 시스템 개론에 대한 설명과 ARM7, ARM9 의 구조에 대해서 설명합니다.<br />
<span style="color: #808000"><strong>II. ARM Applications | 삼성의 S3C2440(ARM9) 개발보드(S3C2440 Mini 개발보드)를 이용해서 어셈블리어와 UART, GPIO 등을 실습합니다.</strong></span><br />
III. Cortex-M3 Architecture | Cortex-M3의 특징과 구조에 대해서 설명합니다.<br />
IV. Cortex-M3 Applications | STM32F103VCT6 Dragon 개발보드를 이용해서 GPIO, LCD, SPI, UART, MP3, SDIO, I2C 등을 실습합니다.</p>
<p>이 강의 자료에 대한 모든 질의사항은<a href="http://cafe.naver.com/avrstudio" target="_blank"> http://cafe.naver.com/avrstudio</a>의 ARM Architecture Q&amp;A게시판에 글을 남겨 주시거나 jk@deviceshop.net로 메일을 보내주시기 바랍니다. 가급적이면 여러 사람이 질문에 대한 답변을 공유할 수 있도록 네이버 카페 게시판을 이용해주셨으면 합니다. 감사합니다.</p>
<p><span style="font-size: small;color: #f68412"><strong>Ⅱ. ARM Applications 1부 목차</strong></span></p>
<table style="width: 620px" border="0">
<tbody>
<tr>
<td>1. Base of Software Engineering<br />
1.1 Memory Endian Formats<br />
1.2 보수 표현<br />
1.3 논리연산<br />
1.4 진수변환<br />
1.5 Data Types<br />
1.6 Aligned &amp; Un-Aligned Data<br />
2. 어셈블리어 실습<br />
2.1 ARM Simulator 환경 설정</td>
<td>2.2 Data Processing Instructions<br />
2.3 Multiply Instructions<br />
2.4 Load/Store Instructions<br />
2.5 Branch Instructions<br />
2.6 Status Register Access Instructions<br />
2.7 Conditional Execution<br />
3.1 S3C2440 CPU<br />
3.2 S3C2440 Features</td>
<td>3. S3C2440 개발보드 소개<br />
3.3 S3C2440 HW IPs<br />
3.4 Memory Controller<br />
3.5 Timer<br />
3.6 UART<br />
3.7 NAND Booting<br />
4. 개발환경 설정<br />
4.1 IAR Workbench 개발환경 설정<br />
4.2 ARM-JTAG 을 이용한 프로그램 다운로드</td>
</tr>
</tbody>
</table>
<p>1장의 내용은 컴퓨터를 전공한 사람이라면 누구나 다 아는 내용이지만 어셈블리어 실습을 하기위해서는 반드시 알아야 하는 내용입니다. 다 아는 내용이겠지만 기억을 되살리는 차원에서 간단하게만 설명 하도록 하겠습니다.</p>
<p><span style="color: #008080;background-color: #ffff99"><strong>1. Base of Software Engineering</strong></span></p>
<p><span style="color: #339966"><strong>1.1 Memory Endian Formats</strong></span></p>
<p>워드 데이터 안에서의 바이트 순서로 크게 빅 엔디언과 리틀 엔디언으로 나눌 수 있습니다. 빅 엔디언은 사람이 숫자를 쓰는 방법과 같이 큰 단위의 바이트가 앞에 오는 방법이고, 리틀 엔디언은 반대로 작은 단위의 바이트가 앞에 오는 방법입니다. 다시 한번 강조하지만 이것은 워드 범위 내에서의 바이트 단위의 순서입니다.<br />
또한 ARM 레지스터에 저장이 될 경우에는 엔디안의 구분이 없고 메모리 접근 측면에서만 구분이 필요합니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td><span style="font-size: small">엔디안 종류</span></td>
<td><span style="font-size: small">0&#215;1234</span></td>
<td><span style="font-size: small">0&#215;12345678</span></td>
<td><span style="font-size: small">아키텍쳐</span></td>
</tr>
<tr>
<td><span style="font-size: small">Big-endian</span></td>
<td><span style="font-size: small">12 34</span></td>
<td><span style="font-size: small">12 34 56 78</span></td>
<td><span style="font-size: small">모토로라 등</span></td>
</tr>
<tr>
<td><span style="font-size: small">Little-endian</span></td>
<td><span style="font-size: small">34 12</span></td>
<td><span style="font-size: small">78 56 34 12</span></td>
<td><span style="font-size: small">x86</span></td>
</tr>
</tbody>
</table>
<p>* 몇몇 아키텍처는 빅 엔디언과 리틀 엔디언 중 하나를 선택할 수 있도록 설계되어있고, 이를 바이 엔디언(Bi-endian)이라 부릅니다. PowerPC, DEC 알파, MIPS, PA-RISC, IA-64 등은 바이 엔디언을 사용하는 대표적인 아키텍처입니다. 우리가 공부하고 있는 ARM도 엔디언을 선택해서 사용할 수 있도록 설계되어 있습니다.<br />
x86 아키텍처가 리틀 엔디언을 쓰기 때문에, 오늘날 x86 아키텍처를 사용하는 대부분의 데스크톱 컴퓨터는 리틀 엔디언을 쓰며 이를 &#8220;인텔 포맷&#8221; 이라고 합니다</p>
<p style="padding-left: 30px">Example)<br />
32비트 숫자인 0x2A를 Little-endian으로 표시 하면?<br />
0&#215;00 00 00 2A = 2A 00 00 00</p>
<p><span style="color: #339966"><strong>1.2 보수 표현</strong></span><br />
컴퓨터에서 보수를 사용하는 이유는 무엇일까요? 모든 것이 0과 1로 표현되는 컴퓨터에서 음수를 표현하는데 편리하기 때문에 사용합니다. 물론 이를 이용해서 뺄셈도 합니다. 예를 들면 12-3의 수식을 컴퓨터(ALU)에서 계산을 하면 실제로는 12에서 3을 빼는 것이 아니라 12와 3의 2의 보수(3의 음수표현)를 더해서 계산을 하게 됩니다.</p>
<p><span style="color: #99cc00"><strong>1.2.1 &#8220;1&#8243; 의 보수</strong></span><br />
주어진 이진수의 모든 자리 숫자를 반전(0을 1로, 1을 0으로)시키면 1의 보수를 얻을 수 있습니다.</p>
<p style="padding-left: 30px">8자리의 이진수 01001011(십진수로 75)의 1의 보수를 구하면 아래와 같습니다.<br />
01001011 의 모든 자리의 수를 반전시킨다.<br />
10110100 &#8211;&gt; 1의 보수</p>
<p><span style="color: #99cc00"><strong>1.2.2 &#8220;2&#8243; 의 보수</strong></span><br />
1의 보수를 구한 다음 2진수 &#8220;1&#8243; 을 더하면 됩니다.<br />
8자리의 이진수 01001011(십진수로 75)의 2의 보수를 구하면 아래와 같습니다.</p>
<p style="padding-left: 30px">01001011 의 모든 자리의 수를 반전시킨다.<br />
10110100 &#8211;&gt; 1의 보수</p>
<p style="padding-left: 30px">10110100<br />
+) 00000001 &#8211;&gt; 1의 보수에서 1을 더합니다.<br />
&#8212;&#8212;&#8212;&#8212;&#8212;<br />
10110101 &#8211;&gt; 2의 보수</p>
<p>보수를 구할 때 한 자리가 더 길어질 경우에는 가장 높은 자리의 숫자는 버립니다.</p>
<p><span style="color: #99cc00"><strong>1.2.3 &#8220;2&#8243; 의 보수를 이용한 뺄셈</strong></span></p>
<p style="padding-left: 30px">예제) 100-75를 2의 보수를 이용해서 연산하시요.<br />
100-75는 100+(-75)와 같으므로</p>
<p style="padding-left: 30px">01100100 (10진수 100)<br />
+) 10110101 (10진수 75의 2의 보수)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;<br />
100011001</p>
<p>새로 생긴 가장 높은 자리의 숫자를 빼고 남은 00011001은 십진수로 25와 같으며 이는 계산하려던 식의 결과입니다.</p>
<p style="padding-left: 30px">예제) 10-75를 2의 보수를 이용해서 연산하시요.<br />
10-75는 10+(-75)와 같으므로</p>
<p style="padding-left: 30px">00001010 (10진수 10)<br />
+) 10110101 (10진수 75의 2의 보수)<br />
&#8212;&#8212;&#8212;&#8212;&#8212;<br />
10111111 (이 결과는 음수 : MSB가 1 이므로 다시 2의 보수를 취하면 65 즉 -65)</p>
<p style="padding-left: 30px">10111111 결과는 MSB가 1(음수)이므로 다시 2의 보수를 취해보면 01000001은 십진수로 65와 같으며 이는 계산하려던 식의 결과 -65가 됩니다.</p>
<p><span style="color: #339966"><strong>1.3 논리 연산</strong></span></p>
<p><span style="color: #99cc00"><strong>1.3.1 NOT</strong></span><br />
2진수 각 자리의 값을 반대로 바꾸는 연산입니다. 이 연산은 어떤 값의 보수를 구할 때 효과적으로 사용할 수 있습니다.</p>
<p style="padding-left: 30px">NOT 0111<br />
= 1000</p>
<p>C나 C++에는 &#8220;~&#8221; 연산을 통해 이 값을 구할 수 있습니다.</p>
<p style="padding-left: 30px">x = ~y;</p>
<p><span style="color: #99cc00"><strong>1.3.2 OR</strong></span><br />
두 값의 각 자릿수를 비교해, 둘 중 하나라도 1이 있다면 1을, 아니면 0을 계산합니다.</p>
<p style="text-align: left;padding-left: 30px">0101<br />
OR 0011<br />
= 0111</p>
<p>C/C++에는 “ | ” 연산자가 이 기능을 제공합니다.</p>
<p style="padding-left: 30px">x = y | z;</p>
<p><strong><span style="color: #99cc00">1.3.3 XOR</span> </strong><br />
두 값의 각 자릿수를 비교해, 값이 같으면 0, 다르면 1을 계산합니다.</p>
<p style="padding-left: 30px">0101<br />
XOR 0011<br />
= 0110</p>
<p>C/C++에는 “ ^ ” 연산자가 이 기능을 제공한다.</p>
<p style="padding-left: 30px">x = y ^ z;</p>
<p><span style="color: #99cc00"><strong>1.3.4 AND</strong></span><br />
두 값의 각 자릿수를 비교해, 두 값 모두에 1이 있을 때에만 1을, 나머지 경우에는 0을 계산합니다.</p>
<p style="padding-left: 30px">0101<br />
AND 0011<br />
= 0001</p>
<p>C/C++에는 “ &amp; ” 연산자가 이 기능을 제공한다.</p>
<p style="padding-left: 30px">x = y &amp; z;</p>
<p><span style="color: #339966"><strong>1.4. Shift 연산</strong></span></p>
<p><span style="color: #99cc00"><strong>1.4.1 왼쪽으로 쉬프트(&lt;&lt;)</strong></span><br />
“ &lt;&lt; ” 키워드는 데이터를 왼쪽으로 비트 수만큼 이동시키기 때문에 2의 “이동할 비트수”를 제곱한 값과 데이터가 곱해진 값이 결과 값으로 도출됩니다. 5(b00000101)를 왼쪽으로 3비트 이동시키면 5 &lt;&lt; 3 = 40(b00101000) 즉 5 * 8 한 것과 같은 효과가 나타납니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK023.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13254" alt="17featureJK023" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK023.jpg" width="382" height="191" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="text-align: center">가중치</td>
<td style="text-align: center">128</td>
<td style="text-align: center">64</td>
<td style="text-align: center">32</td>
<td style="text-align: center">16</td>
<td style="text-align: center">8</td>
<td style="text-align: center">4</td>
<td style="text-align: center">2</td>
<td style="text-align: center">1</td>
</tr>
<tr>
<td style="text-align: center">연산전</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
</tr>
<tr>
<td style="text-align: center">연산후</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
</tr>
</tbody>
</table>
<p><span style="color: #99cc00"><strong>1.4.2 오른쪽으로 쉬프트(&gt;&gt;)</strong></span><br />
“&gt;&gt;” 키워드는 데이터를 오른쪽으로 비트 수만큼 이동시키기 때문에 2의 “이동한 비트수”를 제곱한 값으로 데이터를 나눗셈 한 값이 도출됩니다.<br />
40(b00101000)를 오른쪽으로 1비트 이동시키면 40 &gt;&gt; 1 = 20(b00101000) 즉 40/2 한 것과 같은 효과가 있습니다.<br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK024.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13255" alt="17featureJK024" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK024.jpg" width="382" height="192" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="text-align: center">가중치</td>
<td style="text-align: center">128</td>
<td style="text-align: center">64</td>
<td style="text-align: center">32</td>
<td style="text-align: center">16</td>
<td style="text-align: center">8</td>
<td style="text-align: center">4</td>
<td style="text-align: center">2</td>
<td style="text-align: center">1</td>
</tr>
<tr>
<td style="text-align: center">연산전</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">2</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
</tr>
<tr>
<td style="text-align: center">연산후</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
</tr>
</tbody>
</table>
<p><span style="color: #99cc00"><strong>1.4.3 부호가 있는 왼쪽 쉬프트 연산(&lt;&lt;)</strong></span><br />
79(b01001111) &lt;&lt; 1 = -98(b10011110)<br />
부호 비트(“1”)와 그 다음 비트(“0”)가 서로 다른 값인 경우 부호가 바뀌고 Overflow가 발생하게 됩니다. 위의 예제에서는 양수에서 음수로 바뀌면서 Overflow가 발생하였습니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK025.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13256" alt="17featureJK025" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK025.jpg" width="382" height="191" /></a></p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="text-align: center">가중치</td>
<td style="text-align: center">부호</td>
<td style="text-align: center">64</td>
<td style="text-align: center">32</td>
<td style="text-align: center">16</td>
<td style="text-align: center">8</td>
<td style="text-align: center">4</td>
<td style="text-align: center">2</td>
<td style="text-align: center">1</td>
</tr>
<tr>
<td style="text-align: center">연산전</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
</tr>
<tr>
<td style="text-align: center">연산후</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
<td style="text-align: center">0</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">1</td>
<td style="text-align: center">0</td>
</tr>
</tbody>
</table>
<p><span style="color: #99cc00"><strong>1.4.4 부호가 있는 오른쪽 쉬프트 연산(&gt;&gt;)</strong></span><br />
여기서 65의 2의 보수를 이용해서 -65를 표현했습니다. -65(b10111111) &gt;&gt; 1 = -33(b11011111)<br />
예를 들어 위의 그림과 같이 “1011 1111” 값을 오른쪽으로 한번 이동하면 왼쪽에 생긴 빈 공간은 최상위 비트인 1 값으로 채워지는 것입니다. 만약 “-160 &gt;&gt; 4v 를 연산하면 -160 의 이진수 값인“1010 0000”가 오른쪽으로 4비트만큼 이동하고, 왼쪽에 생긴 네개의 빈 공간은 최상위 비트인 1 로 채워지므로 연산 결과는 “1111 1010”가 됩니다.</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK026.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13257" alt="17featureJK026" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK026.jpg" width="318" height="192" /></a></p>
<p>&nbsp;</p>
<p><span style="color: #339966"><strong>1.5 Rotate 연산</strong></span></p>
<p>데이터의 모든 비트들을 각각 서로 이웃한 비트의 자리로 옮기고 한 쪽 끝에서 밀려 나가는 비트가 다시 반대편 끝으로 들어오게 되는 연산입니다.</p>
<p><span style="color: #99cc00"><strong>1.5.1 부호 없는(Rotate no carry) 왼쪽 Rotate</strong></span><br />
23(b00010111) ROL 1 = 46(b00101110)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK027.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13258" alt="17featureJK027" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK027.jpg" width="318" height="192" /></a><br />
Left circular shift or rotate</p>
<p><span style="color: #99cc00"><strong>1.5.2 부호 없는(Rotate no carry) 오른쪽 Rotate</strong></span><br />
23(b00010111) ROR 1 = 139(b10001011)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK028.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13259" alt="17featureJK028" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK028.jpg" width="318" height="192" /></a><br />
Right circular shift or rotate</p>
<p><strong><span style="color: #99cc00">1.5.3 부호 있는(Rotate through carry) 왼쪽 Rotate</span> </strong><br />
ROL과 동일하지만 Carry Flag가 최하위 비트로 이동하고, 최상의 비트의 값이 Carry Flag 로 이동됩니다.<br />
23(b00010111) RCL 1 = 47(b00101111)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK029.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13260" alt="17featureJK029" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK029.jpg" width="363" height="192" /></a><br />
Left rotate through carry</p>
<p><span style="color: #99cc00"><strong>1.5.4 부호 있는(Rotate through carry) 오른쪽 Rotate</strong></span><br />
23(b00010111) RCR 1 = 267(b100001011)</p>
<p><a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK030.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13261" alt="17featureJK030" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK030.jpg" width="359" height="192" /></a><br />
Right rotate through carry<br />
아주 기본적인 내용들이지만 기본적인 것부터 정확하게 알고 있어야 합니다. 주로 데이터 암호화나, 고속의 그래픽 처리 작업 등에서 Shift, Rotate 연산을 많이 사용합니다.</p>
<p><span style="color: #339966"><strong>1.6 진수변환</strong></span></p>
<p>2진수를 16진수로 변환할 때 4자리씩 끊어서 계산하면 편리합니다. 자주 쓰이는 수들의 2진수와 16진수들의 예제들입니다.</p>
<p style="padding-left: 30px">2^4 = 16B = b0001 0000 = 0&#215;10<br />
2^5 = 32B = b0010 0000 = 0&#215;20<br />
2^6 = 64B = b0100 0000 = 0&#215;40<br />
2^7 = 128B = 0&#215;80<br />
2^8 = 256B = b0001 0000 0000 = 0&#215;100<br />
2^10 = 1KB = b0100 0000 0000 = 0&#215;400<br />
2^20 = 1MB = b0001 0000 0000 0000 0000 0000 = 0&#215;100000<br />
2^30 = 1GB = 0&#215;40000000<br />
2^40 = 1TB = 0X10000000000<br />
4KB = 0&#215;1000, 64KB = 0&#215;10000, 1MB = 0&#215;100000</p>
<p style="padding-left: 30px">Ex)<br />
4GB = 4*1GB = 4 * 2^30 = 2^2 * 2^30 = 2^32 = 0&#215;100000000<br />
256KB = 256*1KB = 2^8 * 2^10 = 2^18 = 0&#215;40000<br />
96KB = 64KB + 32KB = 2^6*2^10 + 2^5*2^10 = 0&#215;10000 + 0&#215;3000 = 0&#215;13000<br />
135KB = 128KB + 4KB + 2KB + 1KB = 2^17 + 2^12 + 2^11 + 2^10 = 0&#215;20000 + 0&#215;1000 + 0&#215;800 + 0&#215;400 = 0x21c00</p>
<p><span style="color: #339966"><strong>1.7 Data Types</strong></span></p>
<p>Byte(8 bits)<br />
Halfword(16 bits)<br />
Word (32 bits)<br />
Long Word (64 bits)</p>
<p>- Value ranges</p>
<p>unsigned char val;<br />
<span style="color: #3366ff">0 &lt;= val &lt;= 2^8(255)</span><br />
signed char val;<br />
-128(0&#215;80) &lt;= val &lt;= 127(0x7F)<br />
int(signed 32bit integer) val;<br />
<span style="color: #3366ff">0&#215;8000 0000 &lt;= val &lt;= 7FFFF FFFF</span></p>
<p><span style="color: #339966"><strong>1.8 Aligned &amp; Un-Aligned Data Access</strong></span></p>
<p><span style="color: #99cc00"><strong>1.8.1 Aligned Access</strong></span></p>
<p>(1) Halfword Data Access : 데이터의 주소 값이 짝수이어야 합니다.<br />
(2) Word Data Access : 데이터의 주소 값이 4의 배수이어야 합니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td bgcolor="#E4F7BA">Aligned Data Access</td>
</tr>
<tr>
<td>char buf[100];int *p;<br />
int gVar;p = (int *)&amp;buf[0];<br />
gVar = *p &#8211;&gt; Data Abort 가능성 1p = (int *)&amp;buf[1];<br />
gVar = *p &#8211;&gt; Data Abort 가능성 2</td>
</tr>
</tbody>
</table>
<p>- Data Abort 가능성 2 : buf의 데이터형이 char(8 bit) 이기 때문에 0번째 이후 부터는 4의 배수가 아니기 때문에 Data Abort 가능성이 있습니다.<br />
- Data Abort 가능성 1 : 0번째 인덱스인데 어떻게 보면 Data Abort 가능성이 없는 것처럼 보입니다. 보통은 Linker가 알아서 buf 변수의 할당 주소를 4의 배수에 맞추어 주지만 그렇지 않을 가능성도 있기 때문에 링커에 따라서는 Data Abort 가능성이 있는 것입니다. 그렇다면 Data Abort가 발생하지 않도록 char 배열 buf를 선언하려면 어떻게 해야 할까요? 컴파일러 지시자를 사용해서 char 배열 buf를 강제로 4의 배수로 맞추어 주는 것입니다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td bgcolor="#E4F7BA">Aligned Data Access</td>
</tr>
<tr>
<td>#pragma data_alignment = 2 &#8211;&gt; 강제로 4의 배수가 되도록 지시<br />
char buf[100];int *p;<br />
int gVar;p = (int *)&amp;buf[0];<br />
gVar = *p &#8211;&gt; 정상동작p = (int *)&amp;buf[1];<br />
gVar = *p &#8211;&gt; 1번째 배열에서는 여전히 Data Abort 가능성 2</td>
</tr>
</tbody>
</table>
<p>여기서 또 한가지 ARM C언어에서 구조체 선언을 할 때 어떻게 선언하는 것이 효율적인지를 알아 봅시다.</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td colspan="2" bgcolor="#E4F7BA">비 효율적인 구조체 데이터 선언</td>
</tr>
<tr>
<td>struct {<br />
char a;<br />
int b;<br />
short c;<br />
int d;<br />
} gVar;</td>
<td>메모리 배치<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK031.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13262" alt="17featureJK031" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK031.jpg" width="225" height="134" /></a></td>
</tr>
</tbody>
</table>
<p>위의 그림을 보면 총 5byte의 메모리 공간을 낭비하였습니다. 그렇다면 선언 순서를 short c, int b 의 순서를 바꾸면 어떻게 될까요?</p>
<table style="border-collapse: collapse;width: 600px" border="1" cellspacing="0" cellpadding="5">
<tbody>
<tr>
<td colspan="2" bgcolor="#E4F7BA">비 효율적인 구조체 데이터 선언</td>
</tr>
<tr>
<td>struct {<br />
char a;<br />
short c;<br />
int b;<br />
int d;<br />
}gVar;</td>
<td>메모리 배치<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK032.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13263" alt="17featureJK032" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK032.jpg" width="225" height="134" /></a></td>
</tr>
</tbody>
</table>
<p>단지 선언 순서만 바꾸어도 메모리 낭비가 5-byte에서 1-byte로 줄었습니다.</p>
<p><strong><span style="color: #99cc00">1.8.2 Un-Aligned Data Access</span> </strong></p>
<p>(1) ARM Architecture v6 부터 지원됨<br />
(2) ARM Architecture v4T, v5T(E) 등에서 Un-aligned data를 접근하려고 하면 Data Abort가 발생합니다.</p>
<p><em id="__mceDel"><br />
<a href="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK033.jpg" rel="lightbox[13132]"><img class="alignnone  wp-image-13264" alt="17featureJK033" src="http://www.ntrexgo.com/wp-content/uploads/2013/05/17featureJK033-620x170.jpg" width="496" height="136" /></a></em></p>
<p>&nbsp;</p>
<p style="text-align: right"><span style="color: #999999">JK전자와 함께하는 ARM 완전정복(3)-2 에서 계속 됩니다.</span><a href="http://wp.me/p3jmc8-3ti" target="_blank"><br />
</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ntrexgo.com/archives/13132/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
