<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>임베디드를 좋아하는 조금 특이한 개발자?</title>
    <link>https://littlebitodd-developer.tistory.com/</link>
    <description>안녕하세요.
저는 되도록이면 다른 개발지 및 사용자가 쉽게 제품에 접근 할 수 있는 방법에 대해서 관심이 많은 개발자입니다.
이 블로그는 임베디드 관련 또는 프로그래밍에 대한 전반적인 개발 방법을 공부하면서 정리하기 위한 블로그입니다.
하지만 가장 큰 목적은 제가 나중에 다시 확인하기 위한 블로그이므로 이해않되시는 부분이 있다면 댓글을 달아주세요.

email : bkgr4949p@icloud.com</description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 10:23:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Gordon_</managingEditor>
    <item>
      <title>[RaspberyPI4] JTAG(FT232H)로 Linux 커널 디버깅 - 1 (필요 환경 준비)</title>
      <link>https://littlebitodd-developer.tistory.com/105</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2&amp;nbsp; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Ubuntu 24.04 LTS&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;buildroot : 2024.02&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;target board : RaspberryPI 4&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;openocd&amp;nbsp; : &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;0.12.0&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;되도록이면 Ubuntu 24.04 를 사용&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;해야합니다. 22.04에서 openocd 설치시 0.11.0 버전으로 설치되며, 해당 버전은 라즈베리파이 이 보드 관련 config 파일이 없습니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;- 참고 문서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JTAG를 통해 RaspberryPI4 디버깅 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/@0xNoor/setup-openocd-with-jtag-uart-on-raspberry-pi-4-using-ft232h-da05ca01c693&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/@0xNoor/setup-openocd-with-jtag-uart-on-raspberry-pi-4-using-ft232h-da05ca01c693&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Debugging를 위한 Linux 빌드 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/74&quot;&gt;https://littlebitodd-developer.tistory.com/74&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Qemu로 실행한 리눅스 GDB로 디버깅 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/75&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/75&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;저는 이전에 Qemu 에뮬레이터에서 실행 중인 Linux를 GDB로 디버깅을 해본적이 있습니다. 이를 통해 Linux의 부팅 과정을 코드 라인 단위로 디버깅이 가능했었습니다. 이번에는 에뮬레이터가 아닌 실제 하드웨어서 JTAG로 디버깅을 하는 방법에 대해서 알아 보려고 합니다.&amp;nbsp;이 포스트를 통해 JTAG를 통해 디버깅하는 방법과 리눅스를 디버깅하는 방법까지 소개 할 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 내용이 방대하기 떄문에 2개의 포스트로 나누어 소개 할 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 하드웨어 구성&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2009&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JkmQi/dJMcabYYhpR/aBe3DkA94oMptxQtx6fhQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JkmQi/dJMcabYYhpR/aBe3DkA94oMptxQtx6fhQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JkmQi/dJMcabYYhpR/aBe3DkA94oMptxQtx6fhQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJkmQi%2FdJMcabYYhpR%2FaBe3DkA94oMptxQtx6fhQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2009&quot; height=&quot;679&quot; data-origin-width=&quot;2009&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2.1. Serial 통신&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 라즈베리파이는 Serial를 통해 Linux Terminal 및 Log를 정보를 송수신 합니다. 그러므로 Serial를 통해서 Uboot 명령어를 송신하거나 Linux의 printk 메세지 등을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 아래 제품을 사용하여 PC와 연결 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.coupang.com/vp/products/5722099371?itemId=25151963046&amp;amp;vendorItemId=92157059105&amp;amp;src=1042503&amp;amp;spec=10304991&amp;amp;addtag=400&amp;amp;ctag=5722099371&amp;amp;lptag=5722099371-25151963046&amp;amp;itime=20260619183307&amp;amp;pageType=PRODUCT&amp;amp;pageValue=5722099371&amp;amp;wPcid=17817676868665685149076&amp;amp;wRef=www.google.com&amp;amp;wTime=20260619183307&amp;amp;redirect=landing&amp;amp;gclid=CjwKCAjw0dPRBhAPEiwAE5vTThkV-6ngokz_Asr8PrVq21z9avelmuExB-PBh9CUtCVJnNK61eCI4hoCbSYQAvD_BwE&amp;amp;mcid=87ca6560c427491a944e0db360051b0e&amp;amp;campaignid=23294172465&amp;amp;adgroupid=&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.coupang.com/vp/products/5722099371?itemId=25151963046&amp;amp;vendorItemId=92157059105&amp;amp;src=1042503&amp;amp;spec=10304991&amp;amp;addtag=400&amp;amp;ctag=5722099371&amp;amp;lptag=5722099371-25151963046&amp;amp;itime=20260619183307&amp;amp;pageType=PRODUCT&amp;amp;pageValue=5722099371&amp;amp;wPcid=17817676868665685149076&amp;amp;wRef=www.google.com&amp;amp;wTime=20260619183307&amp;amp;redirect=landing&amp;amp;gclid=CjwKCAjw0dPRBhAPEiwAE5vTThkV-6ngokz_Asr8PrVq21z9avelmuExB-PBh9CUtCVJnNK61eCI4hoCbSYQAvD_BwE&amp;amp;mcid=87ca6560c427491a944e0db360051b0e&amp;amp;campaignid=23294172465&amp;amp;adgroupid=&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781861783862&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PL2303HX 컨버터 UART USB to RS232 TTL 변환 케이블 - 시리얼 통신 아두이노 라즈베리파이 MCU 개발용 - 케&quot; data-og-description=&quot;쿠팡에서 PL2303HX 컨버터 UART USB to RS232 TTL 변환 케이블 - 시리얼 통신 아두이노 라즈베리파이 MCU 개발용 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 케이블 제품도 바로 쿠팡에서 확&quot; data-og-host=&quot;www.coupang.com&quot; data-og-source-url=&quot;https://www.coupang.com/vp/products/5722099371?itemId=25151963046&amp;amp;vendorItemId=92157059105&amp;amp;src=1042503&amp;amp;spec=10304991&amp;amp;addtag=400&amp;amp;ctag=5722099371&amp;amp;lptag=5722099371-25151963046&amp;amp;itime=20260619183307&amp;amp;pageType=PRODUCT&amp;amp;pageValue=5722099371&amp;amp;wPcid=17817676868665685149076&amp;amp;wRef=www.google.com&amp;amp;wTime=20260619183307&amp;amp;redirect=landing&amp;amp;gclid=CjwKCAjw0dPRBhAPEiwAE5vTThkV-6ngokz_Asr8PrVq21z9avelmuExB-PBh9CUtCVJnNK61eCI4hoCbSYQAvD_BwE&amp;amp;mcid=87ca6560c427491a944e0db360051b0e&amp;amp;campaignid=23294172465&amp;amp;adgroupid=&quot; data-og-url=&quot;https://www.coupang.com/vp/products/5722099371?vendorItemId=92157059105&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1ORyj/dJMb9kUcbxA/yFe8CmXxVrsaGZg5drf5Xk/img.jpg?width=492&amp;amp;height=492&amp;amp;face=0_0_492_492,https://scrap.kakaocdn.net/dn/bNgDhy/dJMb9efnhzP/ctKBbC37D46FFjT3j2DGh1/img.jpg?width=492&amp;amp;height=492&amp;amp;face=0_0_492_492&quot;&gt;&lt;a href=&quot;https://www.coupang.com/vp/products/5722099371?itemId=25151963046&amp;amp;vendorItemId=92157059105&amp;amp;src=1042503&amp;amp;spec=10304991&amp;amp;addtag=400&amp;amp;ctag=5722099371&amp;amp;lptag=5722099371-25151963046&amp;amp;itime=20260619183307&amp;amp;pageType=PRODUCT&amp;amp;pageValue=5722099371&amp;amp;wPcid=17817676868665685149076&amp;amp;wRef=www.google.com&amp;amp;wTime=20260619183307&amp;amp;redirect=landing&amp;amp;gclid=CjwKCAjw0dPRBhAPEiwAE5vTThkV-6ngokz_Asr8PrVq21z9avelmuExB-PBh9CUtCVJnNK61eCI4hoCbSYQAvD_BwE&amp;amp;mcid=87ca6560c427491a944e0db360051b0e&amp;amp;campaignid=23294172465&amp;amp;adgroupid=&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.coupang.com/vp/products/5722099371?itemId=25151963046&amp;amp;vendorItemId=92157059105&amp;amp;src=1042503&amp;amp;spec=10304991&amp;amp;addtag=400&amp;amp;ctag=5722099371&amp;amp;lptag=5722099371-25151963046&amp;amp;itime=20260619183307&amp;amp;pageType=PRODUCT&amp;amp;pageValue=5722099371&amp;amp;wPcid=17817676868665685149076&amp;amp;wRef=www.google.com&amp;amp;wTime=20260619183307&amp;amp;redirect=landing&amp;amp;gclid=CjwKCAjw0dPRBhAPEiwAE5vTThkV-6ngokz_Asr8PrVq21z9avelmuExB-PBh9CUtCVJnNK61eCI4hoCbSYQAvD_BwE&amp;amp;mcid=87ca6560c427491a944e0db360051b0e&amp;amp;campaignid=23294172465&amp;amp;adgroupid=&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1ORyj/dJMb9kUcbxA/yFe8CmXxVrsaGZg5drf5Xk/img.jpg?width=492&amp;amp;height=492&amp;amp;face=0_0_492_492,https://scrap.kakaocdn.net/dn/bNgDhy/dJMb9efnhzP/ctKBbC37D46FFjT3j2DGh1/img.jpg?width=492&amp;amp;height=492&amp;amp;face=0_0_492_492');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PL2303HX 컨버터 UART USB to RS232 TTL 변환 케이블 - 시리얼 통신 아두이노 라즈베리파이 MCU 개발용 - 케&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;쿠팡에서 PL2303HX 컨버터 UART USB to RS232 TTL 변환 케이블 - 시리얼 통신 아두이노 라즈베리파이 MCU 개발용 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 케이블 제품도 바로 쿠팡에서 확&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.coupang.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;하지만 다른 USB to RS232 TTL 제품이 있다면 해당 제품을 사용해도 문제 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;주의점)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 반드시 Rx, Tx 연결을 확인하세요&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdXBWk/dJMb997RO34/axiBm7FuNKBoMcGyDamNQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdXBWk/dJMb997RO34/axiBm7FuNKBoMcGyDamNQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdXBWk/dJMb997RO34/axiBm7FuNKBoMcGyDamNQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdXBWk%2FdJMb997RO34%2FaxiBm7FuNKBoMcGyDamNQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;224&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 보이는 것처럼 하양색은 Rx, 초록색은 Tx입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 RaspberryPI Tx를 USB to RS232 TTL의 Rx에 연결해야 합니다. Rx는 그의 반대입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2395&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0LfL1/dJMcafG4f2x/fBMzKrdSK8A6OghKLHYKKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0LfL1/dJMcafG4f2x/fBMzKrdSK8A6OghKLHYKKK/img.png&quot; data-alt=&quot;Serial Pin 연결방법&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0LfL1/dJMcafG4f2x/fBMzKrdSK8A6OghKLHYKKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0LfL1%2FdJMcafG4f2x%2FfBMzKrdSK8A6OghKLHYKKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2395&quot; height=&quot;718&quot; data-origin-width=&quot;2395&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Serial Pin 연결방법&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2.2. JTAG 통신&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음으로 JTAG통신을 연결하는 방법에 대해서 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 FT232H 모듈을 구매해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005011539347602.html?spm=a2g0o.productlist.main.5.42f33e62vmYR1s&amp;amp;algo_pvid=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c&amp;amp;algo_exp_id=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c-4&amp;amp;pdp_ext_f=%7B%22order%22%3A%2292%22%2C%22eval%22%3A%221%22%2C%22fromPage%22%3A%22search%22%7D&amp;amp;pdp_npi=6%40dis%21KRW%2126020%219310%21%21%21111.40%2139.86%21%4021010d9017818650582133025eea34%2112000055864070811%21sea%21KR%216034166235%21X%211%210%21n_tag%3A-29919%3Bd%3A50224c32%3Bm03_new_user%3A-29895%3BpisId%3A5000000208162599&amp;amp;curPageLogUid=QqbQJQjeD8zR&amp;amp;utparam-url=scene%3Asearch%7Cquery_from%3A%7Cx_object_id%3A1005011539347602%7C_p_origin_prod%3A&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.aliexpress.com/item/1005011539347602.html?spm=a2g0o.productlist.main.5.42f33e62vmYR1s&amp;amp;algo_pvid=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c&amp;amp;algo_exp_id=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c-4&amp;amp;pdp_ext_f=%7B%22order%22%3A%2292%22%2C%22eval%22%3A%221%22%2C%22fromPage%22%3A%22search%22%7D&amp;amp;pdp_npi=6%40dis%21KRW%2126020%219310%21%21%21111.40%2139.86%21%4021010d9017818650582133025eea34%2112000055864070811%21sea%21KR%216034166235%21X%211%210%21n_tag%3A-29919%3Bd%3A50224c32%3Bm03_new_user%3A-29895%3BpisId%3A5000000208162599&amp;amp;curPageLogUid=QqbQJQjeD8zR&amp;amp;utparam-url=scene%3Asearch%7Cquery_from%3A%7Cx_object_id%3A1005011539347602%7C_p_origin_prod%3A&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781865092411&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;product&quot; data-og-title=&quot;FT232H 다기능 모듈 USB 2.0 고속 480Mb/s USB to JTAG UART FIFO SPI I2C 모듈 - AliExpress&quot; data-og-description=&quot;Smarter Shopping, Better Living! Aliexpress.com&quot; data-og-host=&quot;ko.aliexpress.com&quot; data-og-source-url=&quot;https://ko.aliexpress.com/item/1005011539347602.html?spm=a2g0o.productlist.main.5.42f33e62vmYR1s&amp;amp;algo_pvid=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c&amp;amp;algo_exp_id=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c-4&amp;amp;pdp_ext_f=%7B%22order%22%3A%2292%22%2C%22eval%22%3A%221%22%2C%22fromPage%22%3A%22search%22%7D&amp;amp;pdp_npi=6%40dis%21KRW%2126020%219310%21%21%21111.40%2139.86%21%4021010d9017818650582133025eea34%2112000055864070811%21sea%21KR%216034166235%21X%211%210%21n_tag%3A-29919%3Bd%3A50224c32%3Bm03_new_user%3A-29895%3BpisId%3A5000000208162599&amp;amp;curPageLogUid=QqbQJQjeD8zR&amp;amp;utparam-url=scene%3Asearch%7Cquery_from%3A%7Cx_object_id%3A1005011539347602%7C_p_origin_prod%3A&quot; data-og-url=&quot;https://ko.aliexpress.com/item/1005011539347602.html?src=ibdm_d03p0558e02r02&amp;amp;sk=&amp;amp;aff_platform=&amp;amp;aff_trace_key=&amp;amp;af=&amp;amp;cv=&amp;amp;cn=&amp;amp;dp=&amp;amp;aff_short_key=&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmm1UU/dJMb8YXU3tA/X9Mwqdbrx3Bz7F1TTxtsWK/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005011539347602.html?spm=a2g0o.productlist.main.5.42f33e62vmYR1s&amp;amp;algo_pvid=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c&amp;amp;algo_exp_id=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c-4&amp;amp;pdp_ext_f=%7B%22order%22%3A%2292%22%2C%22eval%22%3A%221%22%2C%22fromPage%22%3A%22search%22%7D&amp;amp;pdp_npi=6%40dis%21KRW%2126020%219310%21%21%21111.40%2139.86%21%4021010d9017818650582133025eea34%2112000055864070811%21sea%21KR%216034166235%21X%211%210%21n_tag%3A-29919%3Bd%3A50224c32%3Bm03_new_user%3A-29895%3BpisId%3A5000000208162599&amp;amp;curPageLogUid=QqbQJQjeD8zR&amp;amp;utparam-url=scene%3Asearch%7Cquery_from%3A%7Cx_object_id%3A1005011539347602%7C_p_origin_prod%3A&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.aliexpress.com/item/1005011539347602.html?spm=a2g0o.productlist.main.5.42f33e62vmYR1s&amp;amp;algo_pvid=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c&amp;amp;algo_exp_id=bf2ddc4e-6b41-4cb5-9910-5ff6d50a434c-4&amp;amp;pdp_ext_f=%7B%22order%22%3A%2292%22%2C%22eval%22%3A%221%22%2C%22fromPage%22%3A%22search%22%7D&amp;amp;pdp_npi=6%40dis%21KRW%2126020%219310%21%21%21111.40%2139.86%21%4021010d9017818650582133025eea34%2112000055864070811%21sea%21KR%216034166235%21X%211%210%21n_tag%3A-29919%3Bd%3A50224c32%3Bm03_new_user%3A-29895%3BpisId%3A5000000208162599&amp;amp;curPageLogUid=QqbQJQjeD8zR&amp;amp;utparam-url=scene%3Asearch%7Cquery_from%3A%7Cx_object_id%3A1005011539347602%7C_p_origin_prod%3A&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmm1UU/dJMb8YXU3tA/X9Mwqdbrx3Bz7F1TTxtsWK/img.jpg?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;FT232H 다기능 모듈 USB 2.0 고속 480Mb/s USB to JTAG UART FIFO SPI I2C 모듈 - AliExpress&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Smarter Shopping, Better Living! Aliexpress.com&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.aliexpress.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;FT232H는 JTAG 뿐만이 아니라 다양한 통신을 위한 모듈입니다. 하지만 다행이도 이렇게 저렴한 가격에 JTAG을 지원하는 모듈이고 취미로 임베디드를 하는 사람으로서 충분히 지불할만한 가격입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;JTAG는 기본적으로 4개의 핀을 사용하여 통신합니다.(SPI 통신이랑 비슷합니다) 핀 연결 방법은 아래 그림으로 설명하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2901&quot; data-origin-height=&quot;1029&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QEvBg/dJMcaf72SX6/ND6X4hAihYtGqY0qN2FsWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QEvBg/dJMcaf72SX6/ND6X4hAihYtGqY0qN2FsWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QEvBg/dJMcaf72SX6/ND6X4hAihYtGqY0qN2FsWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQEvBg%2FdJMcaf72SX6%2FND6X4hAihYtGqY0qN2FsWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2901&quot; height=&quot;1029&quot; data-origin-width=&quot;2901&quot; data-origin-height=&quot;1029&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;주의점)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;u&gt;&lt;b&gt;반드시 I2C Mode 스위치를 Off&lt;/b&gt; &lt;/u&gt;로 설정해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FT232H Datasheet)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ftdichip.com/wp-content/uploads/2024/09/DS_FT232H.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ftdichip.com/wp-content/uploads/2024/09/DS_FT232H.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FT232H의 JTAG Pin 관련한 내용은 Datasheet의 &lt;b&gt;&quot;3.5.5. FT232H Pins used in an MPSSE&quot;&lt;/b&gt;&amp;nbsp; 에 명시되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L1VVi/dJMcaaMt0Rh/p87tbkjGut0I1rIOSTIwk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L1VVi/dJMcaaMt0Rh/p87tbkjGut0I1rIOSTIwk0/img.png&quot; data-alt=&quot;JTAG 핀 번호 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L1VVi/dJMcaaMt0Rh/p87tbkjGut0I1rIOSTIwk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL1VVi%2FdJMcaaMt0Rh%2Fp87tbkjGut0I1rIOSTIwk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;643&quot; height=&quot;205&quot; data-origin-width=&quot;643&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JTAG 핀 번호 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;1125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9TBmB/dJMcag6Zbd9/baFOAdyzoTKkB1kNFf4kqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9TBmB/dJMcag6Zbd9/baFOAdyzoTKkB1kNFf4kqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9TBmB/dJMcag6Zbd9/baFOAdyzoTKkB1kNFf4kqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9TBmB%2FdJMcag6Zbd9%2FbaFOAdyzoTKkB1kNFf4kqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;530&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;1125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Host PC와 FT232와 정상적으로 연결되었다면 lsusb로 정상 연결되었는지 확인해볼 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781865843155&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lsusb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yklQv/dJMcajo1IOT/cz1M6iszU0dYHG9ERCM7n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yklQv/dJMcajo1IOT/cz1M6iszU0dYHG9ERCM7n1/img.png&quot; data-alt=&quot;FT232H 인식 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yklQv/dJMcajo1IOT/cz1M6iszU0dYHG9ERCM7n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyklQv%2FdJMcajo1IOT%2Fcz1M6iszU0dYHG9ERCM7n1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;807&quot; height=&quot;71&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FT232H 인식 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 디버깅을 위한 Linux 빌드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781865997899&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-description=&quot;Contribute to MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hsyl7/dJMb83kCj2h/qyK3kXb60F4M1NdyBVnn3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/myUbI/dJMb9fZEz6E/kKjz2NsQ3ZM5CUOtjjn420/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hsyl7/dJMb83kCj2h/qyK3kXb60F4M1NdyBVnn3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/myUbI/dJMb9fZEz6E/kKjz2NsQ3ZM5CUOtjjn420/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;저는 buildroot를 사용해 Linux를 빌드하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;또한, 하기 귀찮은 Buildroot 설정 및 Linux kernel 설정을 제가 다 해놨으므로 그냥 빌드한 하시면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781866217422&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# buildroot 필요 package 설치
sudo apt install sed make binutils build-essential diffutils bash patch gzip bzip2 perl tar cpio unzip rsync file bc findutils libncurses5-dev libncursesw5-dev bzr curl cvs git mercurial libssl-dev subversion

# Linux build 환경 clone
git clone https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT.git ./br2_rpi4_debug

# buildroot submodule update
cd br2_rpi4_debug
git submodule update --init --recursive

# 빌드 환경 구성
make raspberrypi4_64_defconfig

# 리눅스 빌드
make -C output/raspberrypi4_64&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WSL에서 빌드시 PATH 관련 에러가 발생하면 아래 포스트를 참고하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/20&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781866510928&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;buildroot 빌드시 PATH 애러 해결&quot; data-og-description=&quot;1. 문제 원인위 해당 에러의 경우 PATH 환경변수에 스페이스, 탭, 개행 문자가 포함되어 있을 경우 발생하는 에러 입니다.echo $PATH위 명령어를 실행하면 위 문자가 포함되어 있는 것을 확인 할 수 &quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/20&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/20&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ceKXkP/dJMb9b31iJZ/iGhjzPPGcPWX35kjlHB0K1/img.png?width=542&amp;amp;height=89&amp;amp;face=0_0_542_89,https://scrap.kakaocdn.net/dn/mRew6/dJMb8WeI8jU/TcfUgVNyPPFmYg4Aayl0z0/img.png?width=542&amp;amp;height=89&amp;amp;face=0_0_542_89,https://scrap.kakaocdn.net/dn/cPa6VA/dJMb8UHYBqy/ZEl6BWOFeRuBxYv0UhqiS0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/20&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ceKXkP/dJMb9b31iJZ/iGhjzPPGcPWX35kjlHB0K1/img.png?width=542&amp;amp;height=89&amp;amp;face=0_0_542_89,https://scrap.kakaocdn.net/dn/mRew6/dJMb8WeI8jU/TcfUgVNyPPFmYg4Aayl0z0/img.png?width=542&amp;amp;height=89&amp;amp;face=0_0_542_89,https://scrap.kakaocdn.net/dn/cPa6VA/dJMb8UHYBqy/ZEl6BWOFeRuBxYv0UhqiS0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;buildroot 빌드시 PATH 애러 해결&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 문제 원인위 해당 에러의 경우 PATH 환경변수에 스페이스, 탭, 개행 문자가 포함되어 있을 경우 발생하는 에러 입니다.echo $PATH위 명령어를 실행하면 위 문자가 포함되어 있는 것을 확인 할 수&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 디버깅을 위해 어떤 설정을 했는지는 너무 길어지므로 다른 포스트를 참고 부탁드립니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. U-boot 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/100&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/100&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781866709168&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Buildroot] 라즈베리파이4 U-boot 부트로더 설정&quot; data-og-description=&quot;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 24.04 LTS)buildroot(2024.02)- 소스 코드https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOTContribute to MainForm/rpi4_debug_l&quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/100&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/100&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZTsCf/dJMb88GemBZ/glLk2Vp3SQz5Mgy8T5OiFk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/4mPh2/dJMb8YXU3Cg/L9bgew7q6pEw2a0oPazvK0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bHgwlW/dJMb88e93yI/0cOWvFDxLApcrwJw479lKk/img.png?width=1171&amp;amp;height=307&amp;amp;face=0_0_1171_307&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/100&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/100&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZTsCf/dJMb88GemBZ/glLk2Vp3SQz5Mgy8T5OiFk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/4mPh2/dJMb8YXU3Cg/L9bgew7q6pEw2a0oPazvK0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bHgwlW/dJMb88e93yI/0cOWvFDxLApcrwJw479lKk/img.png?width=1171&amp;amp;height=307&amp;amp;face=0_0_1171_307');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Buildroot] 라즈베리파이4 U-boot 부트로더 설정&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 24.04 LTS)buildroot(2024.02)- 소스 코드https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOTContribute to MainForm/rpi4_debug_l&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;리눅스 디버깅 하기전 JTAG를 연결해야합니다. 하지만 U-boot bootloader를 사용하지 않는다면 부팅후 자동적으로 리눅스 커널을 부팅 해버리기 때문에 JTAG를 연결할 시간이 없습니다. 그로므로 U-boot bootloader를 사용하여 Linux 커널 부팅전 U-boot에서 대기 후 JTAG로 연결한 다음 Linux 을 부팅하기 위해 U-boot를 설정하야여 합니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2. 리눅스 디버깅 심볼 관련 커널 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/74&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781866815157&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Linux Debugging] Buildroot를 통해  디버깅할 리눅스 빌드&quot; data-og-description=&quot;- 개발 환경WSL2 (Ubuntu 24.04 LTS)buildroot(2024.02)1. 서론 리눅스 커널을 공부하면서 어떻게 하면 일반적인 어플리케이션을 디버깅 할 때 처럼 직관적이고 커널의 코드흐름을 확인 할 수 있는 방법을 고&quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/74&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/74&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bLoz68/dJMb8SpRm6Q/BPB4mSPSTysJodrd3rnQDK/img.png?width=800&amp;amp;height=435&amp;amp;face=0_0_800_435,https://scrap.kakaocdn.net/dn/zt1of/dJMb8VNE0tn/oewUskJYiD9BRthNPuvPc1/img.png?width=800&amp;amp;height=435&amp;amp;face=0_0_800_435,https://scrap.kakaocdn.net/dn/bo6VZy/dJMb8RR1gFj/JukSWbcNkKxNDPJpVXn5Ik/img.png?width=905&amp;amp;height=493&amp;amp;face=0_0_905_493&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/74&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/74&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bLoz68/dJMb8SpRm6Q/BPB4mSPSTysJodrd3rnQDK/img.png?width=800&amp;amp;height=435&amp;amp;face=0_0_800_435,https://scrap.kakaocdn.net/dn/zt1of/dJMb8VNE0tn/oewUskJYiD9BRthNPuvPc1/img.png?width=800&amp;amp;height=435&amp;amp;face=0_0_800_435,https://scrap.kakaocdn.net/dn/bo6VZy/dJMb8RR1gFj/JukSWbcNkKxNDPJpVXn5Ik/img.png?width=905&amp;amp;height=493&amp;amp;face=0_0_905_493');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Linux Debugging] Buildroot를 통해 디버깅할 리눅스 빌드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 개발 환경WSL2 (Ubuntu 24.04 LTS)buildroot(2024.02)1. 서론 리눅스 커널을 공부하면서 어떻게 하면 일반적인 어플리케이션을 디버깅 할 때 처럼 직관적이고 커널의 코드흐름을 확인 할 수 있는 방법을 고&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;기본적으로 리눅스 커널 이미지에는 디버깅 심볼이 포함되어 있지 않기에 디버깅할 수 없습니다. 그러므로 이미지에 디버깅 심볼을 추가하여 GDB로 디버깅 할 수 있는 설정을 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.3. 라즈베리파이 JTAG 활성화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이는 config.txt 파일을 통해 부팅 전 미리 기능을 활성화 할 수 있습니다. 그 중 JTAG도 마찬가지 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781886783224&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;&amp;lt;code&amp;gt;config.txt&amp;lt;/code&amp;gt; - Raspberry Pi Documentation&quot; data-og-description=&quot;The official documentation for Raspberry Pi computers and microcontrollers&quot; data-og-host=&quot;www.raspberrypi.com&quot; data-og-source-url=&quot;https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio&quot; data-og-url=&quot;https://www.raspberrypi.com/documentation/computers/config_txt.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xAJVe/dJMb88e95DS/ImpXkiChA1NuvMV9CFyna0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xAJVe/dJMb88e95DS/ImpXkiChA1NuvMV9CFyna0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;code&amp;gt;config.txt&amp;lt;/code&amp;gt; - Raspberry Pi Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The official documentation for Raspberry Pi computers and microcontrollers&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.raspberrypi.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- config.txt&lt;/h3&gt;
&lt;pre id=&quot;code_1781886807695&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Please note that this is only a sample, we recommend you to change it to fit
# your needs.
# You should override this file using BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE.
# See http://buildroot.org/manual.html#rootfs-custom
# and http://elinux.org/RPiconfig for a description of config.txt syntax

start_file=start4.elf
fixup_file=fixup4.dat

# kernel=Image
kernel=u-boot.bin

# To use an external initramfs file
#initramfs rootfs.cpio.gz

# Disable overscan assuming the display supports displaying the full resolution
# If the text shown on the screen disappears off the edge, comment this out
disable_overscan=1

# How much memory in MB to assign to the GPU on Pi models having
# 256, 512 or 1024 MB total memory
gpu_mem_256=100
gpu_mem_512=100
gpu_mem_1024=100

# fixes rpi (3B, 3B+, 3A+, 4B and Zero W) ttyAMA0 serial console
# dtoverlay=miniuart-bt
dtoverlay=disable-bt
enable_uart=1

# enable autoprobing of Bluetooth driver without need of hciattach/btattach
dtparam=krnbt=on

# enable 64bits support
arm_64bit=1

# Configure GPIOs for debugging via JTAG
# Disable pull-downs
gpio=22-27=np

# Enable JTAG pins (GPIO22-GPIO27)
enable_jtag_gpio=1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 enable_jtag_gpio를 1로 하여 미리 JTAG를 활성화 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. openOCD 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://openocd.org/pages/getting-openocd.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openocd.org/pages/getting-openocd.html&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1781886924879&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# openOCD 설치
sudo apt install openocd

# openOCD 버전 확인(반드시 0.12.0 이상일 것)
openocd -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Dxrk/dJMcaccsBtU/GCCAyk3xhrSDS3dRyeS920/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Dxrk/dJMcaccsBtU/GCCAyk3xhrSDS3dRyeS920/img.png&quot; data-alt=&quot;openOCD 버전 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Dxrk/dJMcaccsBtU/GCCAyk3xhrSDS3dRyeS920/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Dxrk%2FdJMcaccsBtU%2FGCCAyk3xhrSDS3dRyeS920%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;85&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;openOCD 버전 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의점)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 반드시 openOCD의 버전이 0.12.0 이상이여야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; openOCD(On Chip Debugger)는 JTAG와 GDB사이를 연결해주는 중간 서버입니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UoKZt/dJMcacjbHZV/vGLI0jUIouBMpec0apv5Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UoKZt/dJMcacjbHZV/vGLI0jUIouBMpec0apv5Kk/img.png&quot; data-alt=&quot;디버깅 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UoKZt/dJMcacjbHZV/vGLI0jUIouBMpec0apv5Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUoKZt%2FdJMcacjbHZV%2FvGLI0jUIouBMpec0apv5Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2183&quot; height=&quot;797&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디버깅 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;5. gdb-multiarch 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; GDB는 ASM, C, C++에서 가장 많이 쓰이는 디버거 입니다. 그래서 대부분의 toolchain을 설치하면 gdb도 같이 포함되어 있는 경우가 많습니다. 그리고 이전에는 CPU 아키텍쳐 마다 GDB를 맞추어 설치하여야 하지만 현재는 gdb-multiarch를 통해 gdb내 아키텍쳐만 설정하면 굳이 gdb를 따로 설치할 필요가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781888152355&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# gdb-multiarch 설치
sudo apt install gdb-multiarch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;6. 후기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 드디어 라즈베리파이를 JTAG로 디버깅할 환경이 준비되었습니다. 드디어 다음 포스트에서 JTAG를 통해 리눅스 커널 중 start_kernel을 디버깅 할 예정입니다. 이를 통해 Qemu라는 에뮬레이털 뿐만이 아니라 실제 하드웨어를 디버깅하면서&amp;nbsp; JTAG을 사용하는 방법을 학습할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Embedded/Raspberry PI</category>
      <category>Debug</category>
      <category>Kernel</category>
      <category>Linux</category>
      <category>openocd</category>
      <category>raspberypi</category>
      <category>디버깅</category>
      <category>커널</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/105</guid>
      <comments>https://littlebitodd-developer.tistory.com/105#entry105comment</comments>
      <pubDate>Sat, 20 Jun 2026 01:58:42 +0900</pubDate>
    </item>
    <item>
      <title>[WPF][MVVM] RelayCommand로 Button 동작을 ViewModel에 연결</title>
      <link>https://littlebitodd-developer.tistory.com/104</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Window 11 (버전 24H2)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Visual Studio Community 2026 (18.7.1)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;.NET framework 4.7.2&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 이전 포스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/81&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/81&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781715661976&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[WPF][MVVM] MVVM 패턴을 위한 ViewModel 추가&quot; data-og-description=&quot;- 개발 환경Window 11 (버전 24H2)Visual Studio Community 2026 (18.0.2).NET framework 4.7.2- 소스 코드https://github.com/MainForm/WPF_MVVM_Base/tree/03d346fe93499c50289eb4085917b4e2839389ad GitHub - MainForm/WPF_MVVM_BaseContribute to MainForm/WPF_&quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/81&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/81&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mTDbh/dJMb9kmlBEA/1qnJOkjrGUzjw7jBRBdlXk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cwWCC1/dJMb9g5j1P9/pX2vVr1Dd9oSNo10s1aZDK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/5rlLa/dJMb9jgGmia/N5oKwUGLzAsEYSttK9bnC0/img.png?width=1436&amp;amp;height=667&amp;amp;face=0_0_1436_667&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/81&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/81&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mTDbh/dJMb9kmlBEA/1qnJOkjrGUzjw7jBRBdlXk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cwWCC1/dJMb9g5j1P9/pX2vVr1Dd9oSNo10s1aZDK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/5rlLa/dJMb9jgGmia/N5oKwUGLzAsEYSttK9bnC0/img.png?width=1436&amp;amp;height=667&amp;amp;face=0_0_1436_667');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[WPF][MVVM] MVVM 패턴을 위한 ViewModel 추가&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 개발 환경Window 11 (버전 24H2)Visual Studio Community 2026 (18.0.2).NET framework 4.7.2- 소스 코드https://github.com/MainForm/WPF_MVVM_Base/tree/03d346fe93499c50289eb4085917b4e2839389ad GitHub - MainForm/WPF_MVVM_BaseContribute to MainForm/WPF_&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 소스 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781722003209&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/WPF_MVVM_Base at 41ddd10394546d452eec0f7123abe4139b40e9ac&quot; data-og-description=&quot;Contribute to MainForm/WPF_MVVM_Base development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&quot; data-og-url=&quot;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cFq1A9/dJMb8Rka92V/S81SQqTfWeerMUMEnhhx2K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bcOVYF/dJMb8U82KZP/1aVYCHIVeBf13H87aDnyI0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/WPF_MVVM_Base/tree/41ddd10394546d452eec0f7123abe4139b40e9ac&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cFq1A9/dJMb8Rka92V/S81SQqTfWeerMUMEnhhx2K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bcOVYF/dJMb8U82KZP/1aVYCHIVeBf13H87aDnyI0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/WPF_MVVM_Base at 41ddd10394546d452eec0f7123abe4139b40e9ac&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/WPF_MVVM_Base development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; MVVM 패턴에서 중요한 점은 되도록이면 View에 직접 C# 코드를 작성하지 않는 것입니다. View와 ViewModel은 Binding을 통해 데이터를 주고받으며, 이를 통해 서로 간의 의존성을 낮추는 것을 목표로 합니다.&amp;nbsp;그러나 실제 애플리케이션을 작성하다 보면 Button과 같은 Control에서 발생하는 Event를 처리해야 하는 경우가 있습니다. 이번 글에서는 이러한 Event를 ViewModel에서 처리할 수 있도록 연결하는 방법에 대해 다루어 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 다만 RelayCommand는 View에서 발생하는 모든 Event를 ViewModel로 전달하기 위한 도구는 아닙니다. RelayCommand의 목적은 Button 클릭과 같은 사용자 동작을 ViewModel의 기능과 연결하는 것입니다. 따라서 어떤 Event를 RelayCommand로 처리하기 전에, 그 동작이 ViewModel에서 담당해야 하는 기능인지 먼저 판단하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대표적으로 다음과 같은 Control은 &lt;/span&gt;&lt;span&gt;Command&lt;/span&gt;&lt;span&gt; 속성을 제공하므로 RelayCommand를 Binding하여 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;Button&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;MenuItem&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;CheckBox&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;RadioButton&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; data-alt=&quot;View와 ViewModel 간 RelayCommand 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCqGkS%2FdJMcaf1gntc%2FYZbVZpxklYtOqkEDTDjFp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1362&quot; height=&quot;652&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;View와 ViewModel 간 RelayCommand 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의점)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;RelayCommand는 &lt;u&gt;&lt;b&gt;모든 Control의 Event를 처리하지 않습니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 예를 들어, &lt;span&gt;TextBox의 입력값 변경이나 ListBox의 선택 항목 변경처럼 Control의 값이 바뀌는 경우에는 Event를 Command로 연결하기보다 Property Binding을 사용하는 것이 더 자연스럽습니다. TextBox는 &lt;/span&gt;&lt;span&gt;Text&lt;/span&gt;&lt;span&gt; 속성을 ViewModel의 Property에 Binding하고, ListBox는 &lt;/span&gt;&lt;span&gt;SelectedItem&lt;/span&gt;&lt;span&gt; 속성을 ViewModel의 Property에 Binding하여 변경된 값을 전달할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. RelayCommand 작성&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4uisi/dJMcajoZ1xc/5TUkXJQCkNkBsieLsOcPaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4uisi/dJMcajoZ1xc/5TUkXJQCkNkBsieLsOcPaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4uisi/dJMcajoZ1xc/5TUkXJQCkNkBsieLsOcPaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4uisi%2FdJMcajoZ1xc%2F5TUkXJQCkNkBsieLsOcPaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;146&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- RelayCommand.cs&lt;/h3&gt;
&lt;pre id=&quot;code_1781722102321&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Windows.Input;

namespace WPF_MVVM_Base.Commands
{
    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        private readonly Func&amp;lt;bool&amp;gt; _canExecute;

        public RelayCommand(Action execute)
            : this(execute, null)
        {
        }

        public RelayCommand(Action execute, Func&amp;lt;bool&amp;gt; canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException(&quot;execute&quot;);
            }

            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute == null)
            {
                return true;
            }

            return _canExecute();
        }

        public void Execute(object parameter)
        {
            _execute();
        }

        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;RelayCommand는 Control의 활성화 여부 및 이벤트 처리를 담당하는 Command 입니다. 더 자세한 이야기는 ICommnad에 대한 포스트를 따로 올리도록하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 각 중요 메소드 및 파라미터를 확인하겠습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;- void Execute(object parameter) 메소드&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 실질적으로 이벤트가 발생할 때, 호출 되는 메소드 입니다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;- bool CanExecute(object parameter) 메소드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Control의 활성화(Enable) 여부를 정하는 메소드입니다.&lt;br /&gt;&amp;nbsp; 반환값이 True이면 활성화, False이면 비활성화 됩니다.&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;- event EventHandler CanExecuteChagned&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; CanExecute를 호출(Callback)해서 해당 컨트롤의 활성화 여부를확인합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 RelayCommand는 이름 처럼 단순히 &lt;u&gt;&lt;b&gt;ICommand의 메소드를 호출 하는 것을 단순히 전달(Relay)하는 Command&lt;/b&gt;&lt;/u&gt; 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. Command Property 추가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MainViewModel.cs&lt;/p&gt;
&lt;pre id=&quot;code_1781777164702&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using WPF_MVVM_Base.Commands;

namespace WPF_MVVM_Base.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        // 버튼 클릭 횟수
        private int _count;
		
        // IncreaseCommand Property
        public ICommand IncreaseCommand { get; }

        public MainViewModel()
        {
            IncreaseCommand = new RelayCommand(Increase, canIncrease);
        }

        // 버튼 클릭 이벤트 콜백
        private void Increase()
        {
            _count++;

            MessageBox.Show($&quot;Count: {_count}&quot;);
        }

        // 버튼 클릭 가능 여부 체크 콜백
        private bool canIncrease()
        {
            // 버튼 클릭 횟수가 5 미만일 때만 버튼이 활성화되도록 설정
            return _count &amp;lt; 5;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 위 코드에서 IncreaseCommand 가 어떤 역할을 하는지 보는 것이 중요합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNjloG/dJMcacp1e7R/Sk5pj4g3vB9geAlKLL0vfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNjloG/dJMcacp1e7R/Sk5pj4g3vB9geAlKLL0vfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNjloG/dJMcacp1e7R/Sk5pj4g3vB9geAlKLL0vfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNjloG%2FdJMcacp1e7R%2FSk5pj4g3vB9geAlKLL0vfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1636&quot; height=&quot;289&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RelayCommand는 View로 부터오는 Execute 메소드 호출을 IncreaseCommand의 Increase로 전달하는 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이로 인해 버튼을 누르더라도 Increase메소드가 호출 되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; data-alt=&quot;View와 ViewModel 간 RelayCommand 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCqGkS/dJMcaf1gntc/YZbVZpxklYtOqkEDTDjFp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCqGkS%2FdJMcaf1gntc%2FYZbVZpxklYtOqkEDTDjFp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1362&quot; height=&quot;652&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;View와 ViewModel 간 RelayCommand 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 IncreaseCommand의 역할은 2개입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 버튼이 눌릴때 마다 Increase 메소드가 호출되어 버튼이 클릭된 회수를 세고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;canIncrase에서 버튼 눌린 횟수가 5 미만일 때만 버튼이 활성화 되는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. View에서 Command Binding&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- MainWindow.xaml&lt;/h4&gt;
&lt;pre id=&quot;code_1781779489475&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Window x:Class=&quot;WPF_MVVM_Base.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
        xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
        xmlns:local=&quot;clr-namespace:WPF_MVVM_Base&quot;
        xmlns:vm=&quot;clr-namespace:WPF_MVVM_Base.ViewModels&quot;
        mc:Ignorable=&quot;d&quot;
        
        d:DataContext=&quot;{d:DesignInstance Type=vm:MainViewModel}&quot;
        Title=&quot;MainWindow&quot; Height=&quot;450&quot; Width=&quot;800&quot;&amp;gt;
    &amp;lt;Grid&amp;gt;
        &amp;lt;Button Content=&quot;Click Me&quot; Command=&quot;{Binding IncreaseCommand}&quot; 
                HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;
                Height=&quot;50&quot; Width=&quot;100&quot;/&amp;gt;
    &amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1685&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg50Xf/dJMcajo0JFP/kekalejO9xHIx8a5ttEpvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg50Xf/dJMcajo0JFP/kekalejO9xHIx8a5ttEpvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg50Xf/dJMcajo0JFP/kekalejO9xHIx8a5ttEpvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg50Xf%2FdJMcajo0JFP%2FkekalejO9xHIx8a5ttEpvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1685&quot; height=&quot;293&quot; data-origin-width=&quot;1685&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;5. 동작 확인&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qw9e7/dJMcab5GleF/HxLjqRTAnjW10o8QCgmiK1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qw9e7/dJMcab5GleF/HxLjqRTAnjW10o8QCgmiK1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qw9e7/dJMcab5GleF/HxLjqRTAnjW10o8QCgmiK1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/Qw9e7/dJMcab5GleF/HxLjqRTAnjW10o8QCgmiK1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;442&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;정상적으로 버튼을 5번 누르고 난 후 버튼이 비활성화 되는 것을 확인 할 수 있습니다.&lt;/p&gt;</description>
      <category>C#/WPF</category>
      <category>c#</category>
      <category>command</category>
      <category>GUI</category>
      <category>MVVM</category>
      <category>Relay</category>
      <category>RelayCommand</category>
      <category>WPF</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/104</guid>
      <comments>https://littlebitodd-developer.tistory.com/104#entry104comment</comments>
      <pubDate>Thu, 18 Jun 2026 19:56:27 +0900</pubDate>
    </item>
    <item>
      <title>[Yocto Project] KAS를 통한 개발 환경 자동 구성</title>
      <link>https://littlebitodd-developer.tistory.com/103</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발 보드 : Raspberrypi 4&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 (Ubuntu 22.04 LTS)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Yocto Project : Scarthgap&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 소스 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/yocto_rpi4_with_kas_template&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/yocto_rpi4_with_kas_template&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781688182616&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/yocto_rpi4_with_kas_template&quot; data-og-description=&quot;Contribute to MainForm/yocto_rpi4_with_kas_template development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/yocto_rpi4_with_kas_template&quot; data-og-url=&quot;https://github.com/MainForm/yocto_rpi4_with_kas_template&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blXuy0/dJMb9cBQYBi/l2A0qaINt0nJLoF6uU4FTK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bopYjT/dJMb9iaZ5M7/cAT9maXfM3VqzKg6EudbZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/yocto_rpi4_with_kas_template&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/yocto_rpi4_with_kas_template&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blXuy0/dJMb9cBQYBi/l2A0qaINt0nJLoF6uU4FTK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bopYjT/dJMb9iaZ5M7/cAT9maXfM3VqzKg6EudbZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/yocto_rpi4_with_kas_template&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/yocto_rpi4_with_kas_template development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Yocto Project를 사용하다보면 명령어가 너무 많아 답답하고 개발 환경을 구축하는데 큰 어려움을 격는 분들이 많습니다. 레이어 구성하는 파일(bblayers.conf)과 설정 파일(local.conf)가 따로 있어 프로젝트의 전체 구성을 한번에 파악하는 것이 힘들고, git으로 submodule로 관리시 git 구성이 복잡해지는 문제가 발생 하는 것이 싫어하는 사람이 있습니다. 이런 개발자들을 위해 docker compose 처럼 간단한 파일 하나로 전체 프로젝트 구성을 나타내며 명령어 하나로 이미지 빌드까지 자동화 해주는 것이 kas 도구 입니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;- kas를 사용하는 이유&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발 환경을 docker compose 처럼 파일 하나로 구성 (manifest 형식)&lt;/li&gt;
&lt;li&gt;git으로 배포 및 형상 관리시 submodule 미사용&lt;/li&gt;
&lt;li&gt;귀찮은 yocto project 개발 환경 설정을 통일&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;- kas를 사용하기에 어려운 환경&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kas yml 파일에서 지원하지 않는 환경 (Petalinux Tools, AMD EDF 등)&lt;/li&gt;
&lt;li&gt;개발 환경이 자주 변경되는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kas를 사용지 않고 git submodule 로 형상 관리하는 방법에 대한 포스트는 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://littlebitodd-developer.tistory.com/102&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781679098060&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Yocto Project] Github 배포하기 위한 프로젝트 구성&quot; data-og-description=&quot;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)Yocto Project : Scarthgap - 소스 코드https://github.com/MainForm/yocto_rpi4_template GitHub - MainForm/yocto_rpi4_templateContribute to MainForm/yocto_rpi4_template development by creat&quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/102&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/102&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b5Dr5Z/dJMb8ZvKsY5/4bTR6k0R9RO6iMMc0uZRF1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eyUfdY/dJMb86n6DiU/orBsUWy07AVwmxvaZLDHO0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/iCocv/dJMb82MMayB/avJSkWzITbVviuIN0SPKGk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/102&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b5Dr5Z/dJMb8ZvKsY5/4bTR6k0R9RO6iMMc0uZRF1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/eyUfdY/dJMb86n6DiU/orBsUWy07AVwmxvaZLDHO0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/iCocv/dJMb82MMayB/avJSkWzITbVviuIN0SPKGk/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Yocto Project] Github 배포하기 위한 프로젝트 구성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)Yocto Project : Scarthgap - 소스 코드https://github.com/MainForm/yocto_rpi4_template GitHub - MainForm/yocto_rpi4_templateContribute to MainForm/yocto_rpi4_template development by creat&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;만약 Git을 사용하지 않으실 거라면 3번으로 넘어가도 상관 없습니다.&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. Git 초기화 (선택)&lt;/h2&gt;
&lt;pre id=&quot;code_1781683781313&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# git 초기화
git init

# git ignore 파일 생성
touch .gitignore&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- git ignore 파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781683833185&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### Visual studio code ###
.vscode
.codex
.agents

### Yocto ###
build*
sources&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 여기서 중요한 것은 layer나 config 파일들을 전부 git에서 제외 하는 것입니다. 왜냐하면, 우리는 kas yml로 개발 환경을 자동 구성 할 것이기에 kas yml로 생성된 파일을 git에 포함한 경우 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. kas 설치 및 yml 파일 작성&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. kas 설치&lt;/h3&gt;
&lt;pre id=&quot;code_1781684566851&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# pipx 설치
sudo apt update
sudo apt install pipx

# kas 설치
pipx install kas

# kas 버전 확인
kas --version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tgbrc/dJMcafG18r0/CqixOTSQeNZ2VdmVnnUyI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tgbrc/dJMcafG18r0/CqixOTSQeNZ2VdmVnnUyI1/img.png&quot; data-alt=&quot;설치된 kas 버전 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tgbrc/dJMcafG18r0/CqixOTSQeNZ2VdmVnnUyI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTgbrc%2FdJMcafG18r0%2FCqixOTSQeNZ2VdmVnnUyI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;43&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설치된 kas 버전 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 문서 : &lt;a href=&quot;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781684679918&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Getting Started &amp;mdash; kas 5.3 documentation&quot; data-og-description=&quot;&amp;copy; Copyright Siemens and contributors, 2017-2025.&quot; data-og-host=&quot;kas.readthedocs.io&quot; data-og-source-url=&quot;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&quot; data-og-url=&quot;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kas.readthedocs.io/en/latest/userguide/getting-started.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Getting Started &amp;mdash; kas 5.3 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;copy; Copyright Siemens and contributors, 2017-2025.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kas.readthedocs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2. yml 파일 작성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 문서 : &lt;a href=&quot;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781684759232&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Project Configuration &amp;mdash; kas 5.3 documentation&quot; data-og-description=&quot;Provides variables to define which buildtools version should be fetched and where it is (or will be) installed. Both version and sha256sum should be set. The environment variable KAS_BUILDTOOLS_DIR can be used to set the directory where buildtools will be &quot; data-og-host=&quot;kas.readthedocs.io&quot; data-og-source-url=&quot;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&quot; data-og-url=&quot;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kas.readthedocs.io/en/latest/userguide/project-configuration.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Project Configuration &amp;mdash; kas 5.3 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Provides variables to define which buildtools version should be fetched and where it is (or will be) installed. Both version and sha256sum should be set. The environment variable KAS_BUILDTOOLS_DIR can be used to set the directory where buildtools will be&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kas.readthedocs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1781684836108&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 라즈베리파이4를 위한 kas yml 파일 생성
touch kas-rpi4.yml&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- kas-rpi4.yml 파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781685444625&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;header:
  version: 11

repos:
  poky:
    url: https://git.yoctoproject.org/poky
    branch: scarthgap
    path: sources/poky
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

  meta-openembedded:
    url: https://github.com/openembedded/meta-openembedded.git
    branch: scarthgap
    path: sources/meta-openembedded
    layers:
      meta-oe:
      meta-python:
      meta-networking:
      meta-multimedia:

  meta-raspberrypi:
    url: https://git.yoctoproject.org/meta-raspberrypi
    branch: scarthgap
    path: sources/meta-raspberrypi
    layers:
      .:
      
machine: raspberrypi4-64
distro: poky

target:
  - core-image-base

local_conf_header:
  base: |
    CONF_VERSION = &quot;2&quot;

  rpi4: |
    ENABLE_UART = &quot;1&quot;
    GPU_MEM = &quot;64&quot;

  image: |
    IMAGE_FSTYPES += &quot;wic.bz2&quot;

  licenses: |
    LICENSE_FLAGS_ACCEPTED += &quot;synaptics-killswitch&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.1. header 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781685680800&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;header:
  version: 11&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;version은 yml 파일에 대한 최소 포멧 버전(Configuration&amp;nbsp;Format&amp;nbsp;Changes)을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kas.readthedocs.io/en/4.4/format-changelog.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kas.readthedocs.io/en/4.4/format-changelog.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781685757314&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Configuration Format Changes &amp;mdash; kas 4.4 documentation&quot; data-og-description=&quot;&amp;copy; Copyright Siemens AG, 2017-2024. Revision 37f84335.&quot; data-og-host=&quot;kas.readthedocs.io&quot; data-og-source-url=&quot;https://kas.readthedocs.io/en/4.4/format-changelog.html&quot; data-og-url=&quot;https://kas.readthedocs.io/en/4.4/format-changelog.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://kas.readthedocs.io/en/4.4/format-changelog.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kas.readthedocs.io/en/4.4/format-changelog.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Configuration Format Changes &amp;mdash; kas 4.4 documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;copy; Copyright Siemens AG, 2017-2024. Revision 37f84335.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kas.readthedocs.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.2. repos 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781685902255&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;repos:
  poky:
    url: https://git.yoctoproject.org/poky
    branch: scarthgap
    path: sources/poky
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

  meta-openembedded:
    url: https://github.com/openembedded/meta-openembedded.git
    branch: scarthgap
    path: sources/meta-openembedded
    layers:
      meta-oe:
      meta-python:
      meta-networking:
      meta-multimedia:

  meta-raspberrypi:
    url: https://git.yoctoproject.org/meta-raspberrypi
    branch: scarthgap
    path: sources/meta-raspberrypi
    layers:
      .:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; repos 는 bitbake에서 Layer를 어떻게 구성할지를 정하는 부분입니다. 여기에는 각 소스코드를 어떻게 다운 받을 것이며 해당 소스 코드 내에서 어떤 레이어를 추가할지를 명명하게 되어있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- url&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;url은 git 소스코드를 다운 받은 repository URL 주소를 의미합니다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- branch&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;branch는 git으로 clone한 repository를 어떤 branch로 checkout할지를 의미합니다.&amp;nbsp;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의점)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 말 그대로 해당 브렌치로 checkout하는 것이므로 해당 branch의 HEAD가 달라진 다면 다른 commit을 clone 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 그러므로 이러한 상황을 방지하고자 commit ID를 지정할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- path&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;path는 clone할 git repository를 어디에 다운 받을 지를 정합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- layers&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; layers는 clone한 repository에서 어떤 layer를 추가할지 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 단, 따로 명시되어 있지 않는다면 자기 자신을 layer로 추가합니다.&lt;br /&gt;&amp;nbsp; 그래서 명시적으로 자기 자신을 추가한 다고 명시하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 예) meta-raspberrypi 자기 자신을 layer로 추가함&lt;/p&gt;
&lt;pre id=&quot;code_1781686624710&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  meta-raspberrypi:
    url: https://git.yoctoproject.org/meta-raspberrypi
    branch: scarthgap
    path: sources/meta-raspberrypi
    layers:
      .:&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.3. machine 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781686703358&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;machine: raspberrypi4-64&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 타겟 개발 보드를 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 우리 개발 환경에서는 meta-rapberrypi에 &quot;raspberrypi4-64.conf&quot; 가 있으므로 명시 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.4. distro 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781686794971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;distro: poky&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드할 Linux의 distribution 명을 지정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.5. target 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781686871946&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;target:
  - core-image-base&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드할 Recipe를 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;core-image-base는 Poky에서 기본적으로 제공해주는 image recipe 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781687064868&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;poky/meta/recipes-core/images/core-image-base.bb at scarthgap &amp;middot; yoctoproject/poky&quot; data-og-description=&quot;Mirror of https://git.yoctoproject.org/poky/. Contribute to yoctoproject/poky development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&quot; data-og-url=&quot;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WhObv/dJMb8QMlceA/0Bfs8jWcFUVtuNckFKowo0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/lM2dN/dJMb84X7Mdc/sfAX8KbLvz2Bf7AOy0Jix1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/yoctoproject/poky/blob/scarthgap/meta/recipes-core/images/core-image-base.bb&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WhObv/dJMb8QMlceA/0Bfs8jWcFUVtuNckFKowo0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/lM2dN/dJMb84X7Mdc/sfAX8KbLvz2Bf7AOy0Jix1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;poky/meta/recipes-core/images/core-image-base.bb at scarthgap &amp;middot; yoctoproject/poky&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Mirror of https://git.yoctoproject.org/poky/. Contribute to yoctoproject/poky development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 자기 만의 image recipe이 있다면 변경 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2.6. local_conf_header 구성&lt;/h3&gt;
&lt;pre id=&quot;code_1781687127690&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;local_conf_header:
  base: |
    CONF_VERSION = &quot;2&quot;

  rpi4: |
    ENABLE_UART = &quot;1&quot;
    GPU_MEM = &quot;64&quot;

  image: |
    IMAGE_FSTYPES += &quot;wic.bz2&quot;

  licenses: |
    LICENSE_FLAGS_ACCEPTED += &quot;synaptics-killswitch&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;local_conf_header는 말 그대로 local.conf에 작성할 내용을 명시하는 구간입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 경우 예시로 4개의 구간으로 나누어 명시하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용을 바탕으로 생성된 local.conf 내용은 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781687267986&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# base
CONF_VERSION = &quot;2&quot;

# image
IMAGE_FSTYPES += &quot;wic.bz2&quot;

# licenses
LICENSE_FLAGS_ACCEPTED += &quot;synaptics-killswitch&quot;
# rpi4
ENABLE_UART = &quot;1&quot;
GPU_MEM = &quot;64&quot;

MACHINE ??= &quot;raspberrypi4-64&quot;
DISTRO ??= &quot;poky&quot;
BBMULTICONFIG ?= &quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. kas yml으로 이미지 빌드&lt;/h2&gt;
&lt;pre id=&quot;code_1781687569567&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kas build kas-rpi4.yml&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1239&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf1Mfc/dJMcafNPfoh/fwa8iBz5yUoO3VStFBw2p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf1Mfc/dJMcafNPfoh/fwa8iBz5yUoO3VStFBw2p1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf1Mfc/dJMcafNPfoh/fwa8iBz5yUoO3VStFBw2p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf1Mfc%2FdJMcafNPfoh%2Ffwa8iBz5yUoO3VStFBw2p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1239&quot; height=&quot;696&quot; data-origin-width=&quot;1239&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Embedded/Yocto Project</category>
      <category>build</category>
      <category>Kas</category>
      <category>Linux</category>
      <category>PROJECT</category>
      <category>yocto</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/103</guid>
      <comments>https://littlebitodd-developer.tistory.com/103#entry103comment</comments>
      <pubDate>Wed, 17 Jun 2026 18:32:22 +0900</pubDate>
    </item>
    <item>
      <title>[Yocto Project] Github 배포하기 위한 프로젝트 구성</title>
      <link>https://littlebitodd-developer.tistory.com/102</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발 보드 : Raspberrypi 4&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 (Ubuntu 22.04 LTS)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Yocto Project : Scarthgap&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 소스 코드&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/yocto_rpi4_template&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/yocto_rpi4_template&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781555712848&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/yocto_rpi4_template&quot; data-og-description=&quot;Contribute to MainForm/yocto_rpi4_template development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/yocto_rpi4_template&quot; data-og-url=&quot;https://github.com/MainForm/yocto_rpi4_template&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iuXuQ/dJMb9efmLzk/dy9nwu5KhUzVUTH13BKkR1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/qWyw8/dJMb8Z3AgDN/dVIPswjYr0KtanT4cuR4q1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/yocto_rpi4_template&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/yocto_rpi4_template&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iuXuQ/dJMb9efmLzk/dy9nwu5KhUzVUTH13BKkR1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/qWyw8/dJMb8Z3AgDN/dVIPswjYr0KtanT4cuR4q1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/yocto_rpi4_template&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/yocto_rpi4_template development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Yocto Project로 구성한 프로젝트를 git으로 형상관리를 하거나 github를 통해 배포를 하고 싶을 때가 있습니다. 하지만 Yocto project로 리눅스를 빌드하게 되면 많은 소스코드와 용량이 많은 산출물이 발생하게 됩니다. 그렇기 때문에 Yocto Project를 배포하기 위해서는 프로젝트를 어떻게 구성하는지가 매우 중요합니다. 이번 포스트에서는 Yocto Project로 개발한 프로젝트를 git으로 관리하기 위한 간단한 방법을 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. Git 초기화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 먼저 git을 초기화한 git ignore 폴더를 생성해 필요없는 파일들을 무시하도록 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781552607136&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# git 초기화
git init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- git ignore 파일&lt;/h4&gt;
&lt;pre id=&quot;code_1781553484564&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;### Visual studio code ###
.vscode
.codex
.agents

### Yocto ###
build*/*
!build*/conf/
!build*/conf/**&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 프로젝트 구성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음으로 기본적인 Layer를 submodule로 추가하고 build 폴더를 구성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- Layer 및 build 폴더 구성&lt;/h4&gt;
&lt;pre id=&quot;code_1781552446783&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// layer를 관리하기 위한 sources 폴더 생성
mkdir sources &amp;amp;&amp;amp; cd -P ./sources

// 필요한 레이어를 submodule로 추가
git clone git://git.yoctoproject.org/poky --branch scarthgap
git clone git://git.openembedded.org/meta-openembedded --branch scarthgap
git clone git://git.yoctoproject.org/meta-raspberrypi --branch scarthgap

cd ..

// build 폴더 구성
source ./sources/poky/oe-init-build-env ./build-rpi4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 그 다음 &quot;bblayers.conf&quot; 파일을 수정해야합니다. &quot;bblayers.conf&quot;은 Layer의 위치를 나타내는 파일입니다. 하지만, 기본적으로 Layer는 절대 경로로 나타내기 때문에 github로 배포시 다른 사람의 환경에서는 Layer를 찾지 못하는 에러가 발생합니다. 그러므로 Layer의 위치를 상태 경로로 변경해주어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9DfY0/dJMcab5DL1M/xcKInqqOz0A1ZjlkCSSkX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9DfY0/dJMcab5DL1M/xcKInqqOz0A1ZjlkCSSkX0/img.png&quot; data-alt=&quot;절대 경로로 설정된 레이어 위치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9DfY0/dJMcab5DL1M/xcKInqqOz0A1ZjlkCSSkX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9DfY0%2FdJMcab5DL1M%2FxcKInqqOz0A1ZjlkCSSkX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;121&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;절대 경로로 설정된 레이어 위치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- bblayers.conf 파일 내용&lt;/h4&gt;
&lt;pre id=&quot;code_1781553981698&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = &quot;2&quot;

BBPATH = &quot;${TOPDIR}&quot;
BBFILES ?= &quot;&quot;

BBLAYERS ?= &quot; \
  ${TOPDIR}/../sources/poky/meta \
  ${TOPDIR}/../sources/poky/meta-poky \
  ${TOPDIR}/../sources/poky/meta-yocto-bsp \
  ${TOPDIR}/../sources/meta-openembedded/meta-oe \
  ${TOPDIR}/../sources/meta-openembedded/meta-python \
  ${TOPDIR}/../sources/meta-raspberrypi \
  &quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qlQhd/dJMcafUxmH2/CkLcnlN8RSX7kDBIu9X7T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qlQhd/dJMcafUxmH2/CkLcnlN8RSX7kDBIu9X7T0/img.png&quot; data-alt=&quot;상대 경로로 설정된 레이어 위치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qlQhd/dJMcafUxmH2/CkLcnlN8RSX7kDBIu9X7T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqlQhd%2FdJMcafUxmH2%2FCkLcnlN8RSX7kDBIu9X7T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;172&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;상대 경로로 설정된 레이어 위치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 기본적인 local.conf 파일을 수정하여 machine을 변경합니다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;-&lt;span&gt; local&lt;/span&gt;.conf 파일 내용&lt;/h4&gt;
&lt;pre id=&quot;code_1781554232611&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;MACHINE ??= &quot;raspberrypi4-64&quot;

LICENSE_FLAGS_ACCEPTED = &quot;synaptics-killswitch&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 리눅스 빌드&lt;/h2&gt;
&lt;pre id=&quot;code_1781554526321&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bitbake core-image-base&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Embedded/Yocto Project</category>
      <category>git</category>
      <category>github</category>
      <category>yocto</category>
      <category>yocto project</category>
      <category>깃</category>
      <category>라즈베리파이</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/102</guid>
      <comments>https://littlebitodd-developer.tistory.com/102#entry102comment</comments>
      <pubDate>Tue, 16 Jun 2026 05:35:18 +0900</pubDate>
    </item>
    <item>
      <title>LIG D&amp;amp;A The SSEN 임베디드 SW스쿨 3기 후기</title>
      <link>https://littlebitodd-developer.tistory.com/101</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://edu.rapa.or.kr/recruitment/11921&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://edu.rapa.or.kr/recruitment/11921&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781527378596&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;RAPA DX캠퍼스 - LIG D&amp;amp;A The SSEN 임베디드SW 스쿨&quot; data-og-description=&quot;본 과정은 고용노동부가 주최하고 디지털선도기업인 LIG D&amp;amp;A 와 전문교육기관 한국전파진흥협회가 공동 운영하는 K-디지털 트레이닝의 디지털선도기업아카데미 사업으로 지원됩니다.&quot; data-og-host=&quot;edu.rapa.or.kr&quot; data-og-source-url=&quot;https://edu.rapa.or.kr/recruitment/11921&quot; data-og-url=&quot;https://edu.rapa.or.kr/recruitment/11921&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cCKvUg/dJMb9gxuaNw/qmNgDWNJhJ9pV2FeKKgi6K/img.png?width=1120&amp;amp;height=561&amp;amp;face=0_0_1120_561,https://scrap.kakaocdn.net/dn/cegvmO/dJMb89ymp49/3n9yjT3BnHayKKVEP99eN0/img.png?width=1120&amp;amp;height=561&amp;amp;face=0_0_1120_561,https://scrap.kakaocdn.net/dn/cPPIBL/dJMb9kUbEHd/1WUmK8reyH0RgxkYJklwQ0/img.png?width=588&amp;amp;height=588&amp;amp;face=0_0_588_588&quot;&gt;&lt;a href=&quot;https://edu.rapa.or.kr/recruitment/11921&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://edu.rapa.or.kr/recruitment/11921&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cCKvUg/dJMb9gxuaNw/qmNgDWNJhJ9pV2FeKKgi6K/img.png?width=1120&amp;amp;height=561&amp;amp;face=0_0_1120_561,https://scrap.kakaocdn.net/dn/cegvmO/dJMb89ymp49/3n9yjT3BnHayKKVEP99eN0/img.png?width=1120&amp;amp;height=561&amp;amp;face=0_0_1120_561,https://scrap.kakaocdn.net/dn/cPPIBL/dJMb9kUbEHd/1WUmK8reyH0RgxkYJklwQ0/img.png?width=588&amp;amp;height=588&amp;amp;face=0_0_588_588');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RAPA DX캠퍼스 - LIG D&amp;amp;A The SSEN 임베디드SW 스쿨&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;본 과정은 고용노동부가 주최하고 디지털선도기업인 LIG D&amp;amp;A 와 전문교육기관 한국전파진흥협회가 공동 운영하는 K-디지털 트레이닝의 디지털선도기업아카데미 사업으로 지원됩니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;edu.rapa.or.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 저는 LIG D&amp;amp;A The SSEN 임베디드SW 스쿨 3기(2025년 12월 1일 ~ 2026년 6월 9일)을 수강하였습니다. 해당 부트캠프는 RAPA 캠퍼스 주관하고 LIG D&amp;amp;A 에 취업하기 위한 맞춤 교육 프로그램입니다. 저의 경우 우연치 않게 지인의 추천으로 인해 해당 부트캠프를 수강하었으며, 운 좋게 합격하여 수강할 수 있었습니다. 해당 교육 프로그램을 수강하면서 느꼈던 점과 수강 후 후기를 나누어 보려고 합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;2. LIG D&amp;amp;A The SSEN 임베디드 SW스쿨에 대해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 수강 인원은 총 30명으로 기본적인 C/C++과 같은 프로그래밍 언어 부터 시작하여 방산 업계에서 사용하는 임베디드 시스템 개발 환경까지 공부 할 수 있는 부트 캠프입니다. 부트 캠프를 수강하면서 몇가지 큰 장점이 있어 소개드립니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- 부트 캠프 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;면점, 코딩 테스트를 패스 하고 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;b&gt;면접 한번으로 취업 할 수 있는 특채 기회&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;한국 방산 업계를 선도하고 있는 LIG D&amp;amp;A 에 근무하고 있는 &lt;u&gt;&lt;b&gt;연구원님들과 직접 소통할 수 있는 기회&lt;/b&gt;&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;프로젝트 발표회를 통해 &lt;u&gt;&lt;b&gt;LIG D&amp;amp;A 연구원님 및 임원님에게 자신의 개발 역량을 보여 줄 수 있는 기회&lt;/b&gt;&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;무기체계 개발 프로세스 및 LIG D&amp;amp;A에서 사용하고 있는 개발 환경으로 프로젝트 진행 기회&lt;/li&gt;
&lt;li&gt;LIG D&amp;amp;A에서 자신에게 맞는 연구소를 확인 할 수 있는 기회&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 특채라는 기회 하나만으로 이 부트캠프를 수강하는데 큰 이점이 있다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 부트캠프내 따로 시험이나 평가가 없기 때문에 큰 부담없이 수강 할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;3. 교육 커리큘럼&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cF7yPA/dJMcajvPRna/MwOhNUJZpIK8BoBzyywzq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cF7yPA/dJMcajvPRna/MwOhNUJZpIK8BoBzyywzq1/img.png&quot; data-alt=&quot;LIG The SSEN 임베디드 SW 스쿨 커리큘&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cF7yPA/dJMcajvPRna/MwOhNUJZpIK8BoBzyywzq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcF7yPA%2FdJMcajvPRna%2FMwOhNUJZpIK8BoBzyywzq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1274&quot; height=&quot;199&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LIG The SSEN 임베디드 SW 스쿨 커리큘&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 교육 커리큘럼은 크게 4개로 나누어져 있습니다. 각 커리큘럼을 자세히 소개 해드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. [0개월 ~ 1개월] 기본적인 개발 역량 강화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 1개월 동안은 기본적인 개발 역량을 강화하기 위해 C / C++, 자료구조 및 알고리즘, WPF GUI 어플리케이션 개발을 학습합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- 임베디드 시스템 개발 관련&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;C / C++&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- 코딩 테스트 역량&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;자료구조 및 알고리즘&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;- LIG D&amp;amp;A 에서 자주 사용하는 GUI 프레임 워크&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WPF Framework&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2. [1개월 ~ 2개월]&amp;nbsp; LIG D&amp;amp;A 각 연구소 소개&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이때 부터 이제 각 연구소에서 선임 연구원분들이 오셔서 각 연구소에 대한 소개 및 연구소에서 필요한 역량들을 알려주십니다. 이때 가장 중요한 것이 만약 방산 산업에 대한 이해가 없다면 내가 어떤 연구소에 가고 싶은지 선택할 수 있는 큰 기회가 됩니다. 또한 수업 후 각 연구원님께 질문을 통해 자신에 맞춤 연구소에 대한 역량을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.3. [2개월 ~ 4개월] 임베디드 관련 공부&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이때 부터 가장 중요한 임베디드 관련 공부를 진행합니다. 이때 전문 강사님께서 몇십년간 갈고 닦으신 임베디드 시스템에 대한 전문적인 내용으로 강의를 해주십니다. 이때 크게 2가지를 학습하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.1. STM32&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 보드 : STM32F427I-DISC1&lt;br /&gt;&lt;a href=&quot;https://www.st.com/en/evaluation-tools/32f429idiscovery.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.st.com/en/evaluation-tools/32f429idiscovery.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;STM32에 대한 기본적인 개발 방법에 대해서 학습하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;하지만, 단순히 개발 방법에 대해서 학습하는 것이 아닌 아키텍쳐(Cortex-M4) 부터 시작하여 각 기능별 레지스터 세팅 방법까지 굉장이 로우 한 부분까지 알려주시기 때문에 코드 레벨이 아닌 아키텍쳐 레벨에서 동작하는 방법을 알려주십니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;더 나아가 FreeRTOS의 포팅 부터 코드 분석을 통해 FreeRTOS의 스케쥴링을 디버깅하는 방법까지 알려주십니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이 교육을 통해 단순히 STM32랑 FreeRTOS를 학습하는 것이 아닌 내부에서 어떻게 동작하는 방법을 알려주시기 때문에 인터넷이나 책으로 배울 수 없는 부분을 학습 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.2. Zynq FGPA&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 보드 : ZYBO-Z7-10&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://digilent.com/reference/programmable-logic/zybo-z7/start?srsltid=AfmBOopRPY75esbX9pRSEtygCA6w1ilhtJzco2omS7lO91xHwYhlIEO6&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://digilent.com/reference/programmable-logic/zybo-z7/start?srsltid=AfmBOopRPY75esbX9pRSEtygCA6w1ilhtJzco2omS7lO91xHwYhlIEO6&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 다음으로 실제 LIG D&amp;amp;A에서 자주 사용하는 환경으로 Zynq FPGA에 대해서 학습합니다. 단, FGPA에 대해서 학습하는 것이 아닌 Zynq내 매우 저사양의 Cortex-A9가 내장되어 있어 임베디드 리눅스에 대해서 학습하게 됩니다. 특히 Zynq의 경우 AMD에서 Petalinux라고 하는 전용 리눅스를 제공해주고 있어 Petalinux를 빌드하고 SDK 툴을 통해 임베디드 환경에서 어플리케이션 및 디바이스 드라이버 개발을 하는 방법을 학습하게 됩니다. 하지만 1개월이라는 시간이 너무 짧고 방대한 교육 내용으로 인해 교육 내용을 따라가는 것이 꽤나 벅찰 수 있지만, 이 교육과정을 통해 실질적으로 FPGA를 왜 방산 산업에서 사용하는 이유에 대해서 학습 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.3. [4개월 ~ 6개월] 프로젝트 진행&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 부트캠프 내에서 가장 중요한 부분이 프로젝트 개발입니다. 약 2개월 정도 개발 시간을 통해 마지막 수료식에 프로젝트를 발표하고 수상식을 통해 수상하게 됩니다. 하지만 2개월 이라고 하더라도 2개월 동안 개발 할 수 있는 시간은 거의 없습니다. 총 개발 기간이 10주라고 한다면 2주 정도는 프로젝트 개발 방향 및 개발 환경 구성하고, 5주 정도 개발을 진행하고 2주 정도 프로젝트 발표 준비, 1주 특채 면접 준비 시간을 분배하므로 개발 할 수 있는 시간은 생각보다 없습니다. 또한, 프로젝트를 진행하면서 2026년 상반기 LIG D&amp;amp;A 채용을 진행하면서 자소서 및 코딩 테스트 면접 준비를 하게 된다면 더욱이 개발 시간이 부족하게 됩니다. 그러므로 팀원들과 확실하게 프로젝트에 집중할 것인지 각자 취업을 준비하면서 병행할지는 프로젝트 시작전 정하는 것이 좋아 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 그리고 프로젝트를 진행하면서 LIG D&amp;amp;A에서 연구원님을 &quot;멘토님&quot;으로서 붙여 주십니다. 그러므로 프로젝트에 대한 진행 방향 및 취업에 대한 조언을 해주시므로 이 또한 매우 큰 메리트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size26&quot;&gt;4. 후기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 만약 주변에 방산 산업 관련하여 취업할 예정이신 분은 무조건 추천 드립니다. 방산 산업 관련 부트캠프 중 당연 최고라고 생각하며 특히 수강자에게 큰 부담이 되지 않도록 수업이 구성되어 있으며, 또한 LIG D&amp;amp;A 관련 실무자를 초청하여 대화를 할 수 있는 기회를 많이 주는 부트캠프는 없다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 특히에 프로젝트 발표회에서 많은 임원분과 연구소장님 앞에서 발표를 하면서 분위기가 좋았으며, 이 LIG D&amp;amp;A에서 해당 교육 프로그램을 매우 긍정적으로 생각하는 느낌이 들었습니다. 만약 LIG D&amp;amp;A에 취업 기회가 필요하신 분들은 이 교육 프로그램에서 프로젝트 발표를 통해 자신의 역량을 어필하고, 특채를 통해 취업을 한다면 이보다 LIG D&amp;amp;A에 취업할 수있는 확율이 매우 높아진다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://v.daum.net/v/fkjbJbb0Ai?f=p&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://v.daum.net/v/fkjbJbb0Ai?f=p&lt;/a&gt;.&lt;/p&gt;
&lt;figure id=&quot;og_1781531569638&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;LIG D&amp;amp;A, 방산 SW 인재 양성 '임베디드SW 스쿨 3기' 수료&quot; data-og-description=&quot;LIG 디펜스&amp;amp;에어로스페이스(LIG D&amp;amp;A)와 한국전파진흥협회(RAPA)는 9일 방위산업 임베디드 소프트웨어 전문인력 양성을 위해 공동 운영한 'LIG D&amp;amp;A The SSEN 임베디드SW 스쿨 3기'의 수료식을 개최했다고 10&quot; data-og-host=&quot;v.daum.net&quot; data-og-source-url=&quot;https://v.daum.net/v/fkjbJbb0Ai?f=p&quot; data-og-url=&quot;https://v.daum.net/v/fkjbJbb0Ai&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UbB6s/dJMb9g5jKHM/SgxUeUH2gYjVo4uiFhRzMk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=155_275_1066_356,https://scrap.kakaocdn.net/dn/jNmZ1/dJMb9iaZQKb/IRz1lWHnKucXNyu6eg8Yy1/img.jpg?width=658&amp;amp;height=492&amp;amp;face=84_249_513_279&quot;&gt;&lt;a href=&quot;https://v.daum.net/v/fkjbJbb0Ai?f=p&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://v.daum.net/v/fkjbJbb0Ai?f=p&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UbB6s/dJMb9g5jKHM/SgxUeUH2gYjVo4uiFhRzMk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=155_275_1066_356,https://scrap.kakaocdn.net/dn/jNmZ1/dJMb9iaZQKb/IRz1lWHnKucXNyu6eg8Yy1/img.jpg?width=658&amp;amp;height=492&amp;amp;face=84_249_513_279');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;LIG D&amp;amp;A, 방산 SW 인재 양성 '임베디드SW 스쿨 3기' 수료&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;LIG 디펜스&amp;amp;에어로스페이스(LIG D&amp;amp;A)와 한국전파진흥협회(RAPA)는 9일 방위산업 임베디드 소프트웨어 전문인력 양성을 위해 공동 운영한 'LIG D&amp;amp;A The SSEN 임베디드SW 스쿨 3기'의 수료식을 개최했다고 10&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;v.daum.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>잡담</category>
      <category>LIG D&amp;amp;A</category>
      <category>The SSEN</category>
      <category>부트캠프</category>
      <category>후기</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/101</guid>
      <comments>https://littlebitodd-developer.tistory.com/101#entry101comment</comments>
      <pubDate>Mon, 15 Jun 2026 22:53:08 +0900</pubDate>
    </item>
    <item>
      <title>[Buildroot] 라즈베리파이4 U-boot 부트로더 설정</title>
      <link>https://littlebitodd-developer.tistory.com/100</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발 보드 : Raspberrypi 4&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;WSL2 (Ubuntu 24.04 LTS)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;buildroot(2024.02)&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 소스 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781269449242&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-description=&quot;Contribute to MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bFZZUU/dJMb8PGEESS/67p8dF53Pmr7z0bjWUKw0K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/sPYeM/dJMb83kBsLq/7CadOoKlBxd0JQtDdWC0vK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bFZZUU/dJMb8PGEESS/67p8dF53Pmr7z0bjWUKw0K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/sPYeM/dJMb83kBsLq/7CadOoKlBxd0JQtDdWC0vK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/rpi4_debug_linux_with_JTAG_with_UBOOT development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위 소스코드는 아래 포스트를 기준으로 구성되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/57&quot;&gt;https://littlebitodd-developer.tistory.com/57&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1781269465765&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Buildroot] Github로 관리하기 위한 개발 환경 구축&quot; data-og-description=&quot;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)buildroot(2024.02)1. 서론 Buildroot를 이용하여 개발하다 보면 Buildroot 내에 이미 개발보드나 패키지들이 많이 정의되어 있어 추가적인 개발보드나 패&quot; data-og-host=&quot;littlebitodd-developer.tistory.com&quot; data-og-source-url=&quot;https://littlebitodd-developer.tistory.com/57&quot; data-og-url=&quot;https://littlebitodd-developer.tistory.com/57&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/T76Dq/dJMb8XknWuq/c6LF6jskZanmt01U5BsxM0/img.png?width=249&amp;amp;height=72&amp;amp;face=0_0_249_72,https://scrap.kakaocdn.net/dn/UENxy/dJMb8ZvJUT2/KxAUnIPIjIBupmPc7ZL3Rk/img.png?width=249&amp;amp;height=72&amp;amp;face=0_0_249_72,https://scrap.kakaocdn.net/dn/chMwmo/dJMb8RR0oWc/N4j8SDjrUGNJakhYCLW4DK/img.png?width=601&amp;amp;height=571&amp;amp;face=0_0_601_571&quot;&gt;&lt;a href=&quot;https://littlebitodd-developer.tistory.com/57&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://littlebitodd-developer.tistory.com/57&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/T76Dq/dJMb8XknWuq/c6LF6jskZanmt01U5BsxM0/img.png?width=249&amp;amp;height=72&amp;amp;face=0_0_249_72,https://scrap.kakaocdn.net/dn/UENxy/dJMb8ZvJUT2/KxAUnIPIjIBupmPc7ZL3Rk/img.png?width=249&amp;amp;height=72&amp;amp;face=0_0_249_72,https://scrap.kakaocdn.net/dn/chMwmo/dJMb8RR0oWc/N4j8SDjrUGNJakhYCLW4DK/img.png?width=601&amp;amp;height=571&amp;amp;face=0_0_601_571');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Buildroot] Github로 관리하기 위한 개발 환경 구축&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;- 개발 환경개발 보드 : Raspberrypi 4WSL2 (Ubuntu 22.04 LTS)buildroot(2024.02)1. 서론 Buildroot를 이용하여 개발하다 보면 Buildroot 내에 이미 개발보드나 패키지들이 많이 정의되어 있어 추가적인 개발보드나 패&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;littlebitodd-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; U-boot는 임베디드 환경에서 가장 많이 쓰이는 부트로더라고 생각합니다. Buildroot의 기본 설정은 따로 부트로더가 없지만 U-boot을 추가할 수 있습니다. U-boot을 사용하면 많은 것들을 할 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리눅스 부팅 인자 설정&lt;/li&gt;
&lt;li&gt;다중 OS 부팅&lt;/li&gt;
&lt;li&gt;NFS rootfs 부팅&lt;/li&gt;
&lt;li&gt;OS 업데이트 기능 추가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 하지만 실제로 U-boot를 buildroot에 추가하는 방법은 쉽지 않습니다. 이번 포스트에서는 Buildroot에서 U-boot을 추가하는 방법을 알아보고 실제 Linux까지 부팅해보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. Board 폴더 내 파일 수정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Board 폴더는 개발 환경에 따라 디렉토리 위치가 다를 수 있습니다. 그러므로 반드시 정확한 Board 위치를 확인해야합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- 기본 Board 폴더 위치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;./board/raspberrypi4-64&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1. cmdline.txt 파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781271090164&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root=/dev/mmcblk0p2 rootwait console=tty1 console=serial0,115200&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ttyAMA0 -&amp;gt; serial0 로 변경해야 U-boot에서 serial0 으로 terminal을 사용할 수 있습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.2.&lt;span&gt; config_4_64bit.txt&lt;/span&gt;&amp;nbsp;파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781271194956&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Please note that this is only a sample, we recommend you to change it to fit
# your needs.
# You should override this file using BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE.
# See http://buildroot.org/manual.html#rootfs-custom
# and http://elinux.org/RPiconfig for a description of config.txt syntax

start_file=start4.elf
fixup_file=fixup4.dat

# kernel=Image
kernel=u-boot.bin

# To use an external initramfs file
#initramfs rootfs.cpio.gz

# Disable overscan assuming the display supports displaying the full resolution
# If the text shown on the screen disappears off the edge, comment this out
disable_overscan=1

# How much memory in MB to assign to the GPU on Pi models having
# 256, 512 or 1024 MB total memory
gpu_mem_256=100
gpu_mem_512=100
gpu_mem_1024=100

# fixes rpi (3B, 3B+, 3A+, 4B and Zero W) ttyAMA0 serial console
# dtoverlay=miniuart-bt
dtoverlay=disable-bt
enable_uart=1

# enable autoprobing of Bluetooth driver without need of hciattach/btattach
dtparam=krnbt=on

# enable 64bits support
arm_64bit=1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 크게 2가지를 변경하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1781271332199&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# kernel=Image
kernel=u-boot.bin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 kernel 파일을 u-boot.bin으로 변경하여 처음 보드가 부팅 할 파일을 Linux가 아닌 u-boot으로 설정하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781271378538&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# fixes rpi (3B, 3B+, 3A+, 4B and Zero W) ttyAMA0 serial console
# dtoverlay=miniuart-bt
dtoverlay=disable-bt
enable_uart=1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 enable_uart=1로 하여 serial를 enable 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.3.post-image.sh&amp;nbsp;파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781271458709&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

set -e

BOARD_DIR=&quot;$(dirname $0)&quot;
BOARD_NAME=&quot;$(basename ${BOARD_DIR})&quot;
GENIMAGE_CFG=&quot;${BOARD_DIR}/genimage-${BOARD_NAME}.cfg&quot;
GENIMAGE_TMP=&quot;${BUILD_DIR}/genimage.tmp&quot;

# generate genimage from template if a board specific variant doesn't exists
if [ ! -e &quot;${GENIMAGE_CFG}&quot; ]; then
	GENIMAGE_CFG=&quot;${BINARIES_DIR}/genimage.cfg&quot;
	FILES=()

	for i in &quot;${BINARIES_DIR}&quot;/*.dtb &quot;${BINARIES_DIR}&quot;/rpi-firmware/*; do
		FILES+=( &quot;${i#${BINARIES_DIR}/}&quot; )
	done

	KERNEL=$(sed -n 's/^kernel=//p' &quot;${BINARIES_DIR}/rpi-firmware/config.txt&quot;)
	FILES+=( &quot;${KERNEL}&quot; )
	
	FILES+=( &quot;Image&quot; )

	BOOT_FILES=$(printf '\\t\\t\\t&quot;%s&quot;,\\n' &quot;${FILES[@]}&quot;)
	sed &quot;s|#BOOT_FILES#|${BOOT_FILES}|&quot; &quot;${BOARD_DIR}/genimage.cfg.in&quot; \
		&amp;gt; &quot;${GENIMAGE_CFG}&quot;
fi

# Pass an empty rootpath. genimage makes a full copy of the given rootpath to
# ${GENIMAGE_TMP}/root so passing TARGET_DIR would be a waste of time and disk
# space. We don't rely on genimage to build the rootfs image, just to insert a
# pre-built one in the disk image.

trap 'rm -rf &quot;${ROOTPATH_TMP}&quot;' EXIT
ROOTPATH_TMP=&quot;$(mktemp -d)&quot;

rm -rf &quot;${GENIMAGE_TMP}&quot;

genimage \
	--rootpath &quot;${ROOTPATH_TMP}&quot;   \
	--tmppath &quot;${GENIMAGE_TMP}&quot;    \
	--inputpath &quot;${BINARIES_DIR}&quot;  \
	--outputpath &quot;${BINARIES_DIR}&quot; \
	--config &quot;${GENIMAGE_CFG}&quot;

exit $?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당파일은 image 파일내 구성을 만드는 파일입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 것은 &quot;config_4_64bit.txt&quot; 파일을 읽어 필요한 파일을 자동적으로 image에 추가해주는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 저희는 u-boot로 부팅하기 위해 config_4_64bit.txt에서 kernel=image를 주석 처리하여 리눅스가 image에 포함되지 않는 문제가 발생합니다. 그러므로 우리가 직접 설정하여 추가해주어야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1781272496013&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	KERNEL=$(sed -n 's/^kernel=//p' &quot;${BINARIES_DIR}/rpi-firmware/config.txt&quot;)
	FILES+=( &quot;${KERNEL}&quot; )
	# 직접 Image 파일을 추가
	FILES+=( &quot;Image&quot; )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.4.uboot.fragment 파일&lt;/h3&gt;
&lt;pre id=&quot;code_1781272561683&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CONFIG_BOOTCOMMAND=&quot;setenv bootargs root=/dev/mmcblk0p2 rootwait console=tty1 console=ttyAMA0,115200 earlycon=pl011,mmio32,0xfe201000 loglevel=8; fatload mmc 0:1 ${kernel_addr_r} Image; booti ${kernel_addr_r} - ${fdt_addr}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uboot에 자동적으로 입력되는 명령어입니다. 해당 명령어를 통해 우리가 굳이 u-boot 명령어를 입력하지 않아도 자동적으로 u-boot에서 Linux로 부팅이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. menuconfig 설정&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqs004/dJMcaiDFMfi/2viR8Vd4m67HJImSkIbTr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqs004/dJMcaiDFMfi/2viR8Vd4m67HJImSkIbTr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqs004/dJMcaiDFMfi/2viR8Vd4m67HJImSkIbTr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdqs004%2FdJMcaiDFMfi%2F2viR8Vd4m67HJImSkIbTr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;310&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qut8b/dJMcaicEyGS/LzIZK84ozVOrwVD3FI59G1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qut8b/dJMcaicEyGS/LzIZK84ozVOrwVD3FI59G1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qut8b/dJMcaicEyGS/LzIZK84ozVOrwVD3FI59G1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqut8b%2FdJMcaicEyGS%2FLzIZK84ozVOrwVD3FI59G1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;382&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 몇가지 중요한 설정만 확인하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.1. Board defconfig 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sOcUb/dJMcabxKnDV/tnHCLO01O2dvq9r0KBkgT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sOcUb/dJMcabxKnDV/tnHCLO01O2dvq9r0KBkgT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sOcUb/dJMcabxKnDV/tnHCLO01O2dvq9r0KBkgT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsOcUb%2FdJMcabxKnDV%2FtnHCLO01O2dvq9r0KBkgT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1171&quot; height=&quot;307&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Board defconfig는 u-boot 내 config 설정을 위한 파일을 설정하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 u-boot에 대한 파일 위치를 넣어도 괜찮지만, 만약 github에 이미 설정된 config를 사용할 경우 &quot;_defconfig&quot;를 제외한 나머지 이름을 넣으면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.1. Additional configuration fragment files 설정&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;21&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fvq0B/dJMcadWDYb9/pcLhrbGkq0G8M15xNrsXf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fvq0B/dJMcadWDYb9/pcLhrbGkq0G8M15xNrsXf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fvq0B/dJMcadWDYb9/pcLhrbGkq0G8M15xNrsXf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFvq0B%2FdJMcadWDYb9%2FpcLhrbGkq0G8M15xNrsXf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;888&quot; height=&quot;21&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;21&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;uboot.fragment 의 파일 위치를 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이 것으로 모든 u-boot 사용을 위한 buildroot 설정은 끝났습니다. 이제 image를 sd카드에 적용하여 부팅한다면 u-boot가 잘 나오는 것을 확인 할 수 있을 것입니다. 저는 단순히 u-boot을 사용하기 위해서가 아닌 라즈베리파이4를 디버깅하기 위해서 사용했지만,&amp;nbsp; Yocto에서 U-boot를 설정하는 것보다 너무 어렵고 정확하게 설정하는 글이 나오지 않아 꽤 애를 먹었습니다.&lt;/p&gt;</description>
      <category>Embedded/Buildroot</category>
      <category>bootloader</category>
      <category>buildroot</category>
      <category>raspberrypi</category>
      <category>u-boot</category>
      <category>라즈베리파이</category>
      <category>부트로더</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/100</guid>
      <comments>https://littlebitodd-developer.tistory.com/100#entry100comment</comments>
      <pubDate>Fri, 12 Jun 2026 23:10:02 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이 4B를 대체하기 위한 다른 SBC 추천</title>
      <link>https://littlebitodd-developer.tistory.com/99</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 요즘 SBC(Single Board Computer)의 가격이 심상치가 않습니다. 특히 메모리 가격이 그게 증가하면서 SBC의 크게 증가한 것은 사실입니다. 특히 라즈베리파이4의 가격이 크게 증가하여 더 이상 쉽게 구입하기가 힘들어졌습니다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이에 따라 다른 SBC 보드로 눈을 돌릴 수밖에 없습니다. 관련하여 어떤 SBC가 있는지 소개해 드리고자 합니다.&amp;nbsp;&lt;/span&gt; &lt;br /&gt;&lt;a href=&quot;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777978071803&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;1GB Raspberry Pi 5 now available at $45, and memory-driven price rises - Raspberry Pi&quot; data-og-description=&quot;A new 1GB Raspberry Pi 5 maintains access to low-cost computing amid memory-driven price rises on some other Raspberry Pi products.&quot; data-og-host=&quot;www.raspberrypi.com&quot; data-og-source-url=&quot;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&quot; data-og-url=&quot;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sfcj1/dJMb8957tFR/uPqdTJgw2o0hUEITwAZ9cK/img.jpg?width=945&amp;amp;height=709&amp;amp;face=0_0_945_709,https://scrap.kakaocdn.net/dn/3n2Vf/dJMb87N0pdt/4vhJUvPKyuWlfivKkuFds0/img.jpg?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533&quot;&gt;&lt;a href=&quot;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.raspberrypi.com/news/1gb-raspberry-pi-5-now-available-at-45-and-memory-driven-price-rises/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sfcj1/dJMb8957tFR/uPqdTJgw2o0hUEITwAZ9cK/img.jpg?width=945&amp;amp;height=709&amp;amp;face=0_0_945_709,https://scrap.kakaocdn.net/dn/3n2Vf/dJMb87N0pdt/4vhJUvPKyuWlfivKkuFds0/img.jpg?width=800&amp;amp;height=533&amp;amp;face=0_0_800_533');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;1GB Raspberry Pi 5 now available at $45, and memory-driven price rises - Raspberry Pi&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A new 1GB Raspberry Pi 5 maintains access to low-cost computing amid memory-driven price rises on some other Raspberry Pi products.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.raspberrypi.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 하지만 라즈베리파이 외의 다른 보드를 구매하는 것은 이런 리눅스 임베디드에 익숙한 사람들에게 추천드립니다. 그 이유는 문제가 발생했을 때 관련 자료를 찾기 힘들기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 선정한 SBC 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 선정한 SBC의 선정 기준은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 합리적인 가격&lt;br /&gt;&amp;nbsp; &amp;nbsp; 라즈베리파이처럼 성능에 비해 너무 비싼 SBC는 제외했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 재고 여부&lt;br /&gt;&amp;nbsp; &amp;nbsp; Orange Pi나 Rock Pi의 경우 더 성능이 높은 SBC가 있습니다. 하지만 재고가 없어 구매할 수 없으므로 추천하지 않았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3) 성능&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- SBC 비교표&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; text-align: center; height: 318px;&quot; border=&quot;1&quot; width=&quot;855&quot; cellspacing=&quot;0&quot; cellpadding=&quot;8&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead style=&quot;background-color: #f2f2f2;&quot;&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;Raspberry Pi 4B&lt;/th&gt;
&lt;th&gt;ODROID-C5&lt;/th&gt;
&lt;th&gt;Orange Pi 4 Pro&lt;/th&gt;
&lt;th&gt;Rock Pi 4B&lt;/th&gt;
&lt;th&gt;RDK X5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SoC&lt;/td&gt;
&lt;td&gt;BCM2711&lt;/td&gt;
&lt;td&gt;S905X5M&lt;/td&gt;
&lt;td&gt;Allwinner A733&lt;/td&gt;
&lt;td&gt;RK3399&lt;/td&gt;
&lt;td&gt;Horizon X5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;Cortex-A72 &amp;times;4&lt;/td&gt;
&lt;td&gt;Cortex-A55 &amp;times;4&lt;/td&gt;
&lt;td&gt;Cortex-A76x2 + A55 x6&lt;/td&gt;
&lt;td&gt;Cortex-A72&amp;times;2 + A53&amp;times;4&lt;/td&gt;
&lt;td&gt;Cortex-A55 &amp;times;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NPU&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;&lt;b&gt;3 TOPS&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;&lt;b&gt;10 TOPS&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM&lt;/td&gt;
&lt;td&gt;4GB&lt;/td&gt;
&lt;td&gt;4GB&lt;/td&gt;
&lt;td&gt;4GB&lt;/td&gt;
&lt;td&gt;4GB&lt;/td&gt;
&lt;td&gt;4GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;USB&lt;/td&gt;
&lt;td&gt;USB 3.0 &amp;times;2&lt;/td&gt;
&lt;td&gt;USB 2.0 only&lt;/td&gt;
&lt;td&gt;USB 3.0&lt;/td&gt;
&lt;td&gt;USB 3.0&lt;/td&gt;
&lt;td&gt;USB 3.0 &amp;times;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;네트워크&lt;/td&gt;
&lt;td&gt;GbE + WiFi&lt;/td&gt;
&lt;td&gt;GbE&lt;/td&gt;
&lt;td&gt;GbE + WiFi&lt;/td&gt;
&lt;td&gt;GbE&lt;/td&gt;
&lt;td&gt;2.5GbE + WiFi6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;가격 (단품)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;₩165,000&lt;/td&gt;
&lt;td&gt;₩71,100&lt;/td&gt;
&lt;td&gt;₩71,400&lt;/td&gt;
&lt;td&gt;₩85,843&lt;/td&gt;
&lt;td&gt;₩99,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- SBC 구매 링크&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ODROID-C5)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.hardkernel.com/ko/shop/odroid-c5/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.hardkernel.com/ko/shop/odroid-c5/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777978837974&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;ODROID-C5 &amp;ndash; ODROID&quot; data-og-description=&quot;ODROID-C5 For Bank transfer TIER DISCOUNT RATE 50 ~ 99 2% 100 ~ 299 3% 300 ~ 499 4% 500 ~ and more 5%&quot; data-og-host=&quot;www.hardkernel.com&quot; data-og-source-url=&quot;https://www.hardkernel.com/ko/shop/odroid-c5/&quot; data-og-url=&quot;https://www.hardkernel.com/ko/shop/odroid-c5/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/2k0SW/dJMb84X2A0i/LdfywHKzg3QYfDGAMMd5x1/img.jpg?width=510&amp;amp;height=389&amp;amp;face=0_0_510_389,https://scrap.kakaocdn.net/dn/Ny0VM/dJMb8Rj5P5i/NTKBTwM0jjAZFKKvJYJdIK/img.jpg?width=510&amp;amp;height=387&amp;amp;face=0_0_510_387&quot;&gt;&lt;a href=&quot;https://www.hardkernel.com/ko/shop/odroid-c5/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.hardkernel.com/ko/shop/odroid-c5/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/2k0SW/dJMb84X2A0i/LdfywHKzg3QYfDGAMMd5x1/img.jpg?width=510&amp;amp;height=389&amp;amp;face=0_0_510_389,https://scrap.kakaocdn.net/dn/Ny0VM/dJMb8Rj5P5i/NTKBTwM0jjAZFKKvJYJdIK/img.jpg?width=510&amp;amp;height=387&amp;amp;face=0_0_510_387');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;ODROID-C5 &amp;ndash; ODROID&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ODROID-C5 For Bank transfer TIER DISCOUNT RATE 50 ~ 99 2% 100 ~ 299 3% 300 ~ 499 4% 500 ~ and more 5%&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.hardkernel.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Orange Pi 4 Pro)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005010198029047.html?gatewayAdapt=glo2kor&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.aliexpress.com/item/1005010198029047.html?gatewayAdapt=glo2kor&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777978878421&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;product&quot; data-og-title=&quot;오렌지 파이 4 프로 4GB 램 올위너 A733 DDR5 싱글 보드 컴퓨터 WiFi6+블루투스 듀얼 MIPI-CSI M2 PCIE SSD 3 T&quot; data-og-description=&quot;Smarter Shopping, Better Living! Aliexpress.com&quot; data-og-host=&quot;ko.aliexpress.com&quot; data-og-source-url=&quot;https://ko.aliexpress.com/item/1005010198029047.html?gatewayAdapt=glo2kor&quot; data-og-url=&quot;https://ko.aliexpress.com/item/1005010198029047.html?src=ibdm_d03p0558e02r02&amp;amp;sk=&amp;amp;aff_platform=&amp;amp;aff_trace_key=&amp;amp;af=&amp;amp;cv=&amp;amp;cn=&amp;amp;dp=&amp;amp;aff_short_key=&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dTmv31/dJMb8RRVJvo/s9Ty2JLP7olklL4o0VIb5k/img.jpg?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005010198029047.html?gatewayAdapt=glo2kor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.aliexpress.com/item/1005010198029047.html?gatewayAdapt=glo2kor&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dTmv31/dJMb8RRVJvo/s9Ty2JLP7olklL4o0VIb5k/img.jpg?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;오렌지 파이 4 프로 4GB 램 올위너 A733 DDR5 싱글 보드 컴퓨터 WiFi6+블루투스 듀얼 MIPI-CSI M2 PCIE SSD 3 T&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Smarter Shopping, Better Living! Aliexpress.com&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.aliexpress.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rock Pi 4B)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005006851328890.html?gatewayAdapt=glo2kor&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.aliexpress.com/item/1005006851328890.html?gatewayAdapt=glo2kor&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777978902972&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;product&quot; data-og-title=&quot;Radxa ROCK 4B RK3399, 6코어 CPU SBC, 4K 출력 지원 HDMI, WiFi 5, 기가비트 이더넷 및 PCIe 2.1, 싱글 보드 컴퓨&quot; data-og-description=&quot;Smarter Shopping, Better Living! Aliexpress.com&quot; data-og-host=&quot;ko.aliexpress.com&quot; data-og-source-url=&quot;https://ko.aliexpress.com/item/1005006851328890.html?gatewayAdapt=glo2kor&quot; data-og-url=&quot;https://ko.aliexpress.com/item/1005006851328890.html?src=ibdm_d03p0558e02r02&amp;amp;sk=&amp;amp;aff_platform=&amp;amp;aff_trace_key=&amp;amp;af=&amp;amp;cv=&amp;amp;cn=&amp;amp;dp=&amp;amp;aff_short_key=&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cInhoV/dJMb8PGz0bh/kVDh6nupBqwrzyVpHXdjT0/img.jpg?width=1125&amp;amp;height=1125&amp;amp;face=0_0_1125_1125&quot;&gt;&lt;a href=&quot;https://ko.aliexpress.com/item/1005006851328890.html?gatewayAdapt=glo2kor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.aliexpress.com/item/1005006851328890.html?gatewayAdapt=glo2kor&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cInhoV/dJMb8PGz0bh/kVDh6nupBqwrzyVpHXdjT0/img.jpg?width=1125&amp;amp;height=1125&amp;amp;face=0_0_1125_1125');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Radxa ROCK 4B RK3399, 6코어 CPU SBC, 4K 출력 지원 HDMI, WiFi 5, 기가비트 이더넷 및 PCIe 2.1, 싱글 보드 컴퓨&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Smarter Shopping, Better Living! Aliexpress.com&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ko.aliexpress.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDK X5)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.devicemart.co.kr/goods/view?no=15741665&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.devicemart.co.kr/goods/view?no=15741665&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777978935780&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;RDK X5 - 10TOPS 인공지능 엣지보드 / ROS2, Transformer 지원 (4GB)&quot; data-og-description=&quot;Sunrise 5 A55 8코어 64비트 CPU 기반 / 10TOPS 성능의 AI 추론용 BPU 내장 / ROS2, Transformer 지원 / Wi-Fi 6 및 블루투스 5.2 / microSD, USB 3.0, HDMI 포트 / AI, 로봇, 엣지 컴퓨팅 특화 / Debian 기반 OS 제공 / 라즈베리파&quot; data-og-host=&quot;www.devicemart.co.kr&quot; data-og-source-url=&quot;https://www.devicemart.co.kr/goods/view?no=15741665&quot; data-og-url=&quot;https://www.devicemart.co.kr/goods/view?no=15741665&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/caA22K/dJMb8UHS1Z0/U2dN6MPqPSn28jkK7ZWYcK/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/bxmqf0/dJMb8Z3vb9Q/Wqj8ikJo0GzCjDf5xULyd0/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/beFWpo/dJMb8YpZe7M/YQrWAroHVb95ZuqPKMPnE0/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600&quot;&gt;&lt;a href=&quot;https://www.devicemart.co.kr/goods/view?no=15741665&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.devicemart.co.kr/goods/view?no=15741665&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/caA22K/dJMb8UHS1Z0/U2dN6MPqPSn28jkK7ZWYcK/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/bxmqf0/dJMb8Z3vb9Q/Wqj8ikJo0GzCjDf5xULyd0/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/beFWpo/dJMb8YpZe7M/YQrWAroHVb95ZuqPKMPnE0/img.jpg?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;RDK X5 - 10TOPS 인공지능 엣지보드 / ROS2, Transformer 지원 (4GB)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Sunrise 5 A55 8코어 64비트 CPU 기반 / 10TOPS 성능의 AI 추론용 BPU 내장 / ROS2, Transformer 지원 / Wi-Fi 6 및 블루투스 5.2 / microSD, USB 3.0, HDMI 포트 / AI, 로봇, 엣지 컴퓨팅 특화 / Debian 기반 OS 제공 / 라즈베리파&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.devicemart.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Embedded</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/99</guid>
      <comments>https://littlebitodd-developer.tistory.com/99#entry99comment</comments>
      <pubDate>Tue, 5 May 2026 20:12:10 +0900</pubDate>
    </item>
    <item>
      <title>[Linux Kernel Module] Character Device의 장치 노드 자동 생성</title>
      <link>https://littlebitodd-developer.tistory.com/98</link>
      <description>&lt;h2 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발 보드 : Raspberrypi 5&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OS : Linux raspberrypi 6.12.62&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;a href=&quot;https://littlebitodd-developer.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;지난 포스트&lt;/a&gt;에서는 간단한 문자 장치를 만들고 나서 직접 수동으로 노드를 문자 장치에 연결해 주었습니다. 하지만 우리가 실생활에서 사용하는 디바이스 드라이버는 사용자가 직접 노드를 연결하는 경우는 거의 없습니다. 그리고 앞으로 실습을 할 때마다 노드를 연결하는 것은 매우 귀찮기에 자동적으로 노드를 연결하는 코드를 추가할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 관련 함수 확인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1. class_create 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1774534868609&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct class * __must_check class_create(const char *name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/class.c#L254&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/class.c#L254&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; class_create 함수는 디바이스 클래스를 생성하는 함수입니다. 디바이스 클래스는 디바이스를 기능 또는 용도에 따라 구분하기 위한 그룹입니다. 그래서 해당 함수를 통해 /sys/class 내 name에 해당하는 디바이스 클래스가 생성됩니다. 그리고 그 후 생성하는 디바이스는 어떤 디바이스 클래스의 속에 있는지에 따라 어떤 기능인지를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;- 매개 변수&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;const char * name&lt;br /&gt;/sys/class 내 생성될 폴더의 이름을 지정하는 변수입니다.&lt;br /&gt;/sys/class는 디바이스 드라이버를 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;기능별로&lt;/span&gt; 그룹으로 묶어 관리하기 위한 폴더입니다.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- 리턴 값&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;struct class * __must_check&lt;br /&gt;정상적으로 디바이스 클래스가 생성된다면 해당 디바이스 클래스의 주소를 반환합니다.&lt;br /&gt;하지만, 에러가 발생하면 IS_ERR를 통해 에러를 확인하여 PTR_ERR로 에러에 대한 코드를 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__must_check 는 해당 함수에서 반환값을 사용하지 않는다면 warning을 발생하는 속성입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class_create의 반환값은 에러를 확인하기 위해서, 그리고 정상적으로 생성되었다면 해제하기 위해서 반드시 한 번 이상은 사용하게 됩니다. 그러므로 __must_check를 통해 반환값을 사용해야 한다고 경고를 주는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774535537403&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Common Attributes (Using the GNU Compiler Collection (GCC))&quot; data-og-description=&quot;Internal visibility is like hidden visibility, but with additional processor specific semantics. Unless otherwise specified by the psABI, GCC defines internal visibility to mean that a function is never called from another module. Compare this with hidden &quot; data-og-host=&quot;gcc.gnu.org&quot; data-og-source-url=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&quot; data-og-url=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-warn_005funused_005fresult&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Common Attributes (Using the GNU Compiler Collection (GCC))&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Internal visibility is like hidden visibility, but with additional processor specific semantics. Unless otherwise specified by the psABI, GCC defines internal visibility to mean that a function is never called from another module. Compare this with hidden&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gcc.gnu.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.2. class_destroy 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1774535708956&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void class_destroy(const struct class *cls)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/class.c#L292&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/class.c#L292&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class_create로 생성한 디바이스 클래스(struct class *)를 해제하기 위한 함수입니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- 매개 변수&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;const struct class * cls&lt;br /&gt;해제하기 위한 디바이스 클래스의 주소를 전달합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.3. device_create 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1774536575428&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;__printf(5, 6) struct device *
device_create(const struct class *cls, struct device *parent, dev_t devt,
	      void *drvdata, const char *fmt, ...);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/core.c#L4430&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/core.c#L4430&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디바이스를 생성하기 위한 함수입니다. 해당 함수를 통해 /dev 폴더에 fmt로 전달한 이름이 생성됩니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- 매개 변수&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;const struct class *cls&lt;br /&gt;디바이스가 어떠한 디바이스 클래스로 분류가 될지 결정되는 매개 변수입니다. &lt;br /&gt;위에서 미리 생성한 디바이스 클래스를 전달합니다.&amp;nbsp;&lt;br /&gt;또한 device_destroy 함수에서도 사용되므로 주의하여야합니다.&lt;/li&gt;
&lt;li&gt;struct device *parent&lt;br /&gt;부모가 되는 상위 디바이스를 전달하는 매개변수입니다.&lt;br /&gt;하지만 우리가 생성한 디바이스는 부모가 되는 디바이스가 없기 떄문에 NULL를 전달합니다.&lt;/li&gt;
&lt;li&gt;dev_t devt&lt;br /&gt;디바이스의 major와 minor를 전달하는 매개변수입니다.&lt;/li&gt;
&lt;li&gt;void *drvdata&lt;br /&gt;디바이스에 대한 상태나 정보를 저장하는 매개변수입니다.&lt;br /&gt;kalloc으로 저장할 데이터의 메모리를 할당받아 주소를 전달하고,&lt;br /&gt;다른 디바이스 드라이버에서 해당 메모리를 참조하여 디바이스에 대한 정보를 확인합니다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의)&lt;/span&gt;&lt;br /&gt;kallloc으로 메모리를 할당했다면,&lt;br /&gt;반드시 exit 함수에서 kfree로 반환해야합니다.&lt;/li&gt;
&lt;li&gt;const char *fmt, ....&lt;br /&gt;이 이후에 매개 변수들은 디바이스의 이름을 정하는 매개변수입니다.&lt;br /&gt;printf의 포멧을 가지고 있으며 &quot;%d&quot;, &quot;%s&quot;와 같은 포멧을 지원합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- 리턴 값&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;struct&amp;nbsp;device&amp;nbsp;*&lt;br /&gt;디바이스에 대한 정보를 저장하고 있는 객체를 반환합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__printf() 속성은 해당 함수가 printf와 같은 형식의 인자를 입력받는다는 것을 컴파일러에게 알리는 속성입니다.&amp;nbsp; 지금 예시로 나온 device_create의 경우는 __printf(5,6) 의 속성을 가지고 있습니다. 그 의미는 device_create는 printf처럼 인자를 받는다는 것이며 5번째 인자인 fmt가 문자열 형태의 포맷(&quot;%d %s&quot; 와 같은 형식)을 입력받는 인자이며 6번째 인자부터 포맷에 해당하는 변수 값을 전달한다는 의미입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-format&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-format&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.4. device_destroy 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1774536590044&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void device_destroy(const struct class *cls, dev_t devt);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/core.c#L4506&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://elixir.bootlin.com/linux/v6.12.34/source/drivers/base/core.c#L4506&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;device_create로 생성한 디바이스를 해제하기 위한 함수입니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;- 매개 변수&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;const struct class* cls&lt;br /&gt;디바이스를 생성할때 전달하였던 디바이스 클래스를 전달합니다.&lt;/li&gt;
&lt;li&gt;dev_t devt()|&lt;br /&gt;디바이스를 생성할 때 전달했던 major와 minor를 전달합니다.&lt;br /&gt;예) MKDEV(major,minor)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;매개변수로 특이하게 struct device*가 아닌 struct class와 dev_t가 들어갑니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 소스 코드&lt;/h2&gt;
&lt;pre id=&quot;code_1774535941756&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;linux/module.h&amp;gt;
#include &amp;lt;linux/init.h&amp;gt;
#include &amp;lt;linux/fs.h&amp;gt;

#include &amp;lt;linux/device.h&amp;gt;
#include &amp;lt;linux/err.h&amp;gt;
 
// 문자 장치의 이름
#define CHAR_DEV_NAME               (&quot;testDevice&quot;)
 
// 생성한 문자 장치의 Major 번호
static int major;
// 생성한 문자 장치을 제어하기 위한 함수를 관리하는 구조체
static struct file_operations fops ={
    .owner = THIS_MODULE,
};

static struct class * test_class;
static struct device * test_device;
 
static int __init initModule(void){
    int ret = 0;

    // 문자 장치 생성
    major = register_chrdev(0, CHAR_DEV_NAME, &amp;amp;fops);
    // 문자 장치 생성시 에러가 발생한 경우
    if(major &amp;lt; 0){
        printk(&quot;[testDevice] Error : register_chrdev()\n&quot;);

        ret = major;
        goto err_chrdev;
    }

    // 정상적으로 문자 장치 생성됨을 알림 및 major 번호 확인
    printk(&quot;[testDevice] Success to init char device module\n&quot;);
    printk(&quot;[testDevice] Major : %d\n&quot;,major);
    
    // /sys/class에 test_class 폴더 생성
    test_class = class_create(&quot;test_class&quot;);
    if(IS_ERR(test_class)){
        printk(&quot;[testDevice] Error : class_create()\n&quot;);

        ret = PTR_ERR(test_class);
        goto err_class;
    }

    // 정상적으로 /sys/class/test_class 폴더 생성
    printk(&quot;[testDevice] test_class folder is created in /sys/class\n&quot;);
    
    test_device = device_create(test_class,NULL,MKDEV(major,0),NULL,CHAR_DEV_NAME);
    if(IS_ERR(test_device)){
        printk(&quot;[testDevice] Error : device_create()\n&quot;);

        ret = PTR_ERR(test_device);
        goto err_device;
    }

    // 정상적으로 /dev/testDevice 생성
    printk(&quot;[testDevice] %s is created in /dev\n&quot;, CHAR_DEV_NAME);

    return 0;

err_device:
    //test class 해제
    class_destroy(test_class);
err_class:
    // 생성된 문자 장치를 해제
    unregister_chrdev(major, CHAR_DEV_NAME);
err_chrdev:
    return ret;
}
 
static void __exit exitModule(void){
    //test device 해제
    device_destroy(test_class,MKDEV(major,0));
    //test class 해제
    class_destroy(test_class);
    // 생성된 문자 장치를 해제
    unregister_chrdev(major, CHAR_DEV_NAME);
 
    printk(&quot;[testDevice] exit module\n&quot;);
}
 
module_init(initModule);
module_exit(exitModule);
 
MODULE_LICENSE(&quot;GPL&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 대부분의 사람들은 goto를 사용한 것에 대해 매우 불편해할 것임을 알고 있습니다. 물론 goto를 사용하지 않아도 충분히 가능합니다. 하지만 자원을 회수해야하는 순서가 FILO 관계이므로 goto로 처리하는 것이 더욱 편합니다. 그리고 실제로 커널 내부 코드에서도 goto를 사용하는 코드를 볼 수 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예시)&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1774632382989&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct class *class_create(const char *name)
{
	struct class *cls;
	int retval;

	cls = kzalloc(sizeof(*cls), GFP_KERNEL);
	if (!cls) {
		retval = -ENOMEM;
		goto error;
	}

	cls-&amp;gt;name = name;
	cls-&amp;gt;class_release = class_create_release;

	retval = class_register(cls);
	if (retval)
		goto error;

	return cls;

error:
	kfree(cls);
	return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(class_create);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 goto가 매우 위험한 코드임은 분명합니다. 그러므로 몇 가지 주의점을 반드시 지켜야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;goto 외의 방법으로 접근이 불가능해야 한다.&lt;/span&gt;&lt;br /&gt;위 코드를 보더라도 goto위에 return 문이 있어 goto문를 사용하지 않은 이상 해당 코드에 진입할 수 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;label은 goto보다 아래에 있어야 합니다.&lt;/span&gt;&lt;br /&gt;이는 코드 흐름을 흐트리지 않고 다음으로 실행해야 하는 코드를 쉽게 예상할 수 있게 하기 위함입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 결과&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mRgRw/dJMcacoZuEt/akpmk6BqKNLIYN16onzkSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mRgRw/dJMcacoZuEt/akpmk6BqKNLIYN16onzkSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mRgRw/dJMcacoZuEt/akpmk6BqKNLIYN16onzkSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmRgRw%2FdJMcacoZuEt%2Fakpmk6BqKNLIYN16onzkSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1006&quot; height=&quot;322&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Embedded/Linux</category>
      <category>charactor</category>
      <category>driver</category>
      <category>Linux</category>
      <category>Module</category>
      <category>디바이스 드라이버</category>
      <category>모듈</category>
      <category>문자 장치</category>
      <category>커널 모듈</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/98</guid>
      <comments>https://littlebitodd-developer.tistory.com/98#entry98comment</comments>
      <pubDate>Sat, 28 Mar 2026 02:31:55 +0900</pubDate>
    </item>
    <item>
      <title>[MediaFoundation] C++로 연결된 카메라 나열</title>
      <link>https://littlebitodd-developer.tistory.com/97</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;- 개발 환경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Visual Studio 2026 (18.3.1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;- 참고자료&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Media Foundation 프로그래밍 가이드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/win32/medfound/media-foundation-programming-guide&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/windows/win32/medfound/media-foundation-programming-guide&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Media Foundation 헤더 및 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/win32/medfound/media-foundation-headers-and-libraries&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/windows/win32/medfound/media-foundation-headers-and-libraries&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크로소프트 Media Foundation 공식 예제 코드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/win32/medfound/audio-video-capture-in-media-foundation&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/windows/win32/medfound/audio-video-capture-in-media-foundation&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;- 예제 코드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774337660328&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot; data-og-description=&quot;Contribute to MainForm/MediaFoundation_CPP_ShowCameraDeviceName development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot; data-og-url=&quot;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cWaEyK/dJMb9gxkU2Q/sa9CaJekIiHhRHPqrkCQr1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iJS5f/dJMb9c9xmlN/LF4EpJuOBAsvi9t7oPJeQ0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/MainForm/MediaFoundation_CPP_ShowCameraDeviceName&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cWaEyK/dJMb9gxkU2Q/sa9CaJekIiHhRHPqrkCQr1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/iJS5f/dJMb9c9xmlN/LF4EpJuOBAsvi9t7oPJeQ0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - MainForm/MediaFoundation_CPP_ShowCameraDeviceName&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to MainForm/MediaFoundation_CPP_ShowCameraDeviceName development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 서론&lt;/h2&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 영상처리 관련 개발자들은 대부분이 OpenCV를 사용할 것으로 예상합니다. 영상 처리를 위한 대부분의 기능들이 포함되어 있으며 더구나 VideoCapture를 통해 아주 손쉽게 카메라에 접근할 수 있어 특히 많이 사용하는 것 같습니다. 단, 딱 하나 문제가되는 부분이 있습니다. 카메라에 대한 자세한 정보를 제공해 주지 않는 다는 것과 세세한 설정을 할 수 없다는 것입니다. 내가 사용하려는 카메라의 모델 정보나 사양들을 확인하기 힘들기에 카메라 제조 회사에서 제공해주는 API를 사용합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 윈도우에서는 카메라나 오디오를 개발 하기위한 MediaFoundation 라이브러리를 제공해주고 있습니다. 해당 라이브러리는 윈도우에서 동영상 플레이어를 개발하기 위해 많이 사용되며 이에 따라 비디오에 인코딩, 디코딩에 대한 기능도 지원합니다. 이러한 라이브러리르 통해 컴퓨터에 연결된 카메라를 열거하는 프로그램을 개발해보도록 하겠습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 라이브러리 연결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 먼저 MediaFoundation을 사용하기 위해 아래와 같은 Lib파일을 프로젝트에 연결해야합니다. 기능에 따라서는 추가적인 Lib파일이 필요하지만 단순히 카메라 장치를 나열하기 위해서는 아래 Lib 파일로도 충분합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mfplat.lib &lt;br /&gt;mfuuid.lib &lt;br /&gt;mf.lib &lt;br /&gt;mfreadwrite.lib&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq2701/dJMcacP079t/qsqxHR7yO81UuIKcPBCyo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq2701/dJMcacP079t/qsqxHR7yO81UuIKcPBCyo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq2701/dJMcacP079t/qsqxHR7yO81UuIKcPBCyo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq2701%2FdJMcacP079t%2FqsqxHR7yO81UuIKcPBCyo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;443&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QmHAF/dJMcag5XwVY/ovIOh0OijpAUuetBB9x8B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QmHAF/dJMcag5XwVY/ovIOh0OijpAUuetBB9x8B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QmHAF/dJMcag5XwVY/ovIOh0OijpAUuetBB9x8B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQmHAF%2FdJMcag5XwVY%2FovIOh0OijpAUuetBB9x8B0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1675&quot; height=&quot;549&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;549&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;949&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PY5Nt/dJMcaadBT1F/fj0upaCpkrnx1RITE37FMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PY5Nt/dJMcaadBT1F/fj0upaCpkrnx1RITE37FMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PY5Nt/dJMcaadBT1F/fj0upaCpkrnx1RITE37FMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPY5Nt%2FdJMcaadBT1F%2Ffj0upaCpkrnx1RITE37FMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;547&quot; height=&quot;416&quot; data-origin-width=&quot;1247&quot; data-origin-height=&quot;949&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 프로그램 개발&lt;/h2&gt;
&lt;pre id=&quot;code_1774337102781&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

// MediaFoundtion 헤더파일
#include &amp;lt;mfapi.h&amp;gt;
#include &amp;lt;mfobjects.h&amp;gt;
#include &amp;lt;mfidl.h&amp;gt;
#include &amp;lt;mfreadwrite.h&amp;gt;
#include &amp;lt;mferror.h&amp;gt;

using namespace std;

// https://learn.microsoft.com/ko-kr/windows/win32/medfound/audio-video-capture-in-media-foundation
void showDeviceNames(IMFActivate** ppDevices, UINT count)
{
    for (DWORD i = 0; i &amp;lt; count; i++)
    {
        HRESULT hr = S_OK;
        WCHAR* szFriendlyName = NULL;

        // 카메라 이름 정보 도출
        UINT32 cchName;
        hr = ppDevices[i]-&amp;gt;GetAllocatedString(
            MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
            &amp;amp;szFriendlyName, &amp;amp;cchName);

        if (SUCCEEDED(hr))
        {
            wprintf(L&quot;%d : %s\n&quot;, i, szFriendlyName);
        }
        CoTaskMemFree(szFriendlyName);
    }
}

int main(void) {

	// COM 라이브러리 초기화
	CoInitializeEx(nullptr, COINIT_MULTITHREADED);
	// MediaFoundation 라이브러리 초기화
	MFStartup(MF_VERSION, MFSTARTUP_FULL);

    IMFAttributes* pConfig = NULL;
    IMFActivate** ppDevices = NULL;
    UINT count = 0;

    // 카메라 검색 속성을 저장하기 위한 객체 생성
    HRESULT hr = MFCreateAttributes(&amp;amp;pConfig, 1);

    // 카메라 검색 속성 지정
    // 카메라 디바이스를 검색(SOURCE_TYPE_VIDCAP)
    if (SUCCEEDED(hr))
    {
        hr = pConfig-&amp;gt;SetGUID(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
        );
    }

    // 카메라 디바이스 도출
    if (SUCCEEDED(hr))
    {
        hr = MFEnumDeviceSources(pConfig, &amp;amp;ppDevices, &amp;amp;count);
    }

    // 카메라 정보 출력
    showDeviceNames(ppDevices, count);


    // 카메라 정보 객체 해제
    for (UINT i = 0; i &amp;lt; count; i++) {
        ppDevices[i]-&amp;gt;Release();
    }
    CoTaskMemFree(ppDevices);

    // 카메라 검색 속성 객체 해제
    pConfig-&amp;gt;Release();

	// MediaFoundation 라이브러리 해제
	MFShutdown();
	// COM 라이브러리 해제
	CoUninitialize();

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bckltN/dJMcaibEnWX/6O1YnDk5eusmTCdNzxnAZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bckltN/dJMcaibEnWX/6O1YnDk5eusmTCdNzxnAZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bckltN/dJMcaibEnWX/6O1YnDk5eusmTCdNzxnAZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbckltN%2FdJMcaibEnWX%2F6O1YnDk5eusmTCdNzxnAZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;405&quot; height=&quot;112&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의 사항)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;MediaFoundation의 카메라 순서와 OpenCV의 CaptureVideo의 카메라 순서가 같다고 보장하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드가 가독성이 떨어지므로 life time을 그림으로 그렸습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;1101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tDU1m/dJMcahKELca/Uju9BfxjjBoP7pukkZwcUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tDU1m/dJMcahKELca/Uju9BfxjjBoP7pukkZwcUK/img.png&quot; data-alt=&quot;MediaFoundation Life time&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tDU1m/dJMcahKELca/Uju9BfxjjBoP7pukkZwcUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtDU1m%2FdJMcahKELca%2FUju9BfxjjBoP7pukkZwcUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;391&quot; height=&quot;569&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;1101&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MediaFoundation Life time&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 카메라의 이름이 잘 나열 된 것을 확인하였습니다 .이제 해당 카메라의 스트림에 접근하여 카메라에서 프레임을 획득하는 코드를 작성할 필요가 있습니다. 해당 코드에 대해서는 다음 포스트에서 작성하도록 하겠습니다.&lt;/p&gt;</description>
      <category>Vision</category>
      <category>C++</category>
      <category>cpp</category>
      <category>MeidaFoundation</category>
      <category>MF</category>
      <category>Vision</category>
      <category>영상처리</category>
      <category>이름</category>
      <category>정보</category>
      <category>카메라</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/97</guid>
      <comments>https://littlebitodd-developer.tistory.com/97#entry97comment</comments>
      <pubDate>Tue, 24 Mar 2026 16:31:43 +0900</pubDate>
    </item>
    <item>
      <title>[C++] std::bind 함수를 원하는 호출 형태로 가공</title>
      <link>https://littlebitodd-developer.tistory.com/96</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;- 참고 문서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://en.cppreference.com/w/cpp/utility/functional/bind.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1774314099654&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;std::bind - cppreference.com&quot; data-og-description=&quot;template&amp;lt; class F, class... Args &amp;gt; /* unspecified */ bind( F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args ); (1) (since C++11) (constexpr since C++20) template&amp;lt; class R, class F, class... Args &amp;gt; /* unspecified */ bind( F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args ); (2) (since C++11) (constexpr since C+&quot; data-og-host=&quot;en.cppreference.com&quot; data-og-source-url=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind.html&quot; data-og-url=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://en.cppreference.com/w/cpp/utility/functional/bind.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;std::bind - cppreference.com&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;template&amp;lt; class F, class... Args &amp;gt; /* unspecified */ bind( F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args ); (1) (since C++11) (constexpr since C++20) template&amp;lt; class R, class F, class... Args &amp;gt; /* unspecified */ bind( F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args ); (2) (since C++11) (constexpr since C+&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;en.cppreference.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 서론&lt;/h3&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 프로젝트를 진행하다보면 꼭 한번 씩은 함수 포인터를 경험하게 됩니다. GUI 프로그래밍에서는 이벤트 핸들러 함수를 등록하거나 아니면 기능을 유연하게 추가하기 위해서도 함수 포인터를 사용합니다. 이럴때 마다 이전에 작성한 함수를 재사용하기 위해 wrapper 함수를 작성했어야 했습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 또는 맴버함수의 경우 함수이지만 다른 함수와 다르게 호출하는 방법이 다릅니다. 그렇기에 맴버 함수를 일반 함수처럼 호출 하는 형태로 가공해야합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1774317624340&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

uint32_t calc(function&amp;lt;uint32_t(uint32_t,uint32_t)&amp;gt; handler, uint32_t n1, uint32_t n2) {
	return handler(n1, n2);
}

// 함수
uint32_t add(uint32_t x, uint32_t y) {
	return x + y;
}

class calculator {
public:
	// 맴버 함수
	uint32_t add(uint32_t x, uint32_t y) {
		return x + y;
	}
};

int main(void) {

	// 문제 없음
	int rs1 = calc(&amp;amp;add, 1, 2);

	// 에러 발생 (맴버 함수가 속해 있는 인스턴스가 없음)
	int rs2 = calc(&amp;amp;calculator::add, 1, 2);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;485&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zQw6M/dJMcadBiYQo/WJVGWxTjFvBh2TfSzydXD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zQw6M/dJMcadBiYQo/WJVGWxTjFvBh2TfSzydXD0/img.png&quot; data-alt=&quot;맴버 함수를 calc에 전달 불가능&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zQw6M/dJMcadBiYQo/WJVGWxTjFvBh2TfSzydXD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzQw6M%2FdJMcadBiYQo%2FWJVGWxTjFvBh2TfSzydXD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;295&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;485&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;맴버 함수를 calc에 전달 불가능&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 문제점을 해결하기 위해 C++에서는 std::bind를 제공하여 자연스럽게 함수를 원하는 형태로 가공하는 것이 가능합니다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1774318041858&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int main(void) {
	using namespace std::placeholders;

	// 문제 없음
	int rs1 = calc(&amp;amp;add, 1, 2);
	
    // bind로 맴버 함수를 전달
	calculator cal1;
	int rs2 = calc(bind(&amp;amp;calculator::add, &amp;amp;cal1, _1, _2), 1, 2);

	cout &amp;lt;&amp;lt; &quot;rs1 : &quot; &amp;lt;&amp;lt; rs1 &amp;lt;&amp;lt; endl;
	cout &amp;lt;&amp;lt; &quot;rs2 : &quot; &amp;lt;&amp;lt; rs2 &amp;lt;&amp;lt; endl;

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mVqA0/dJMcaaEGhz7/bZ2iJIhTsC57OgKPfhKZMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mVqA0/dJMcaaEGhz7/bZ2iJIhTsC57OgKPfhKZMK/img.png&quot; data-alt=&quot;bind로 문제 해결&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mVqA0/dJMcaaEGhz7/bZ2iJIhTsC57OgKPfhKZMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmVqA0%2FdJMcaaEGhz7%2FbZ2iJIhTsC57OgKPfhKZMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;283&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;bind로 문제 해결&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2. bind 사용 방법&lt;/h3&gt;
&lt;pre id=&quot;code_1774318568987&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

uint32_t add(uint32_t x, uint32_t y) {
	return x + y;
}

int main(void) {
	using namespace std::placeholders;

	// bind의 첫번째 인자는 호출가능한 함수(callable)
	function&amp;lt;uint32_t(uint32_t, uint32_t)&amp;gt; f1 = bind(add, _1, _2);

	// _1이 10으로 _2가 20으로 대체되어 호출
	uint32_t result = f1(10, 20);

	cout &amp;lt;&amp;lt; result &amp;lt;&amp;lt; endl;

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMQs78/dJMb99Z48mt/8vQ5CozzzV2GHSRF2ejM50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMQs78/dJMb99Z48mt/8vQ5CozzzV2GHSRF2ejM50/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMQs78/dJMb99Z48mt/8vQ5CozzzV2GHSRF2ejM50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMQs78%2FdJMb99Z48mt%2F8vQ5CozzzV2GHSRF2ejM50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;781&quot; height=&quot;217&quot; data-origin-width=&quot;1378&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; bind에서 첫번째 인자는 호출가능한 함수(함수, 맴버 함수, 람다 함수)이여야 합니다. 그리고 그 뒤에 f1으로 호출할 때 필요한 맴버 변수를 지정하게 됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용 방법은 매우 간단하지만 밑 응용 방법을 보게 된다면 매우 강력한 기능임을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3. bind 응용&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.1. 매개 변수 생략&lt;/h4&gt;
&lt;pre id=&quot;code_1774319501655&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

uint32_t mul(uint32_t x, uint32_t y) {
	return x * y;
}

int main(void) {
	
	// 1과 _1의 차이를 명확히 보여주기 위해 using를 사용하지 않았습니다.
	// uint32_t(uint32_t, uint32_t)를 uint32_t(uint32_t)로 변경.
	// 즉 매개변수 x의 값을 2로 고정함
	function&amp;lt;uint32_t(uint32_t)&amp;gt; mul2 = bind(&amp;amp;mul, 2 , std::placeholders::_1);

	for (uint32_t i = 2; i &amp;lt; 10; i++) {
		cout &amp;lt;&amp;lt; &quot;2 x &quot; &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &quot; = &quot; &amp;lt;&amp;lt; mul2(i) &amp;lt;&amp;lt; endl;
	}

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BIJRE/dJMcaaYWRPi/edfozkk7vxCEIb0TcWfKHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BIJRE/dJMcaaYWRPi/edfozkk7vxCEIb0TcWfKHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BIJRE/dJMcaaYWRPi/edfozkk7vxCEIb0TcWfKHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBIJRE%2FdJMcaaYWRPi%2Fedfozkk7vxCEIb0TcWfKHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;177&quot; height=&quot;252&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 위 예제를 통해서 mul의 x 매개 변수를 2로 고정하여서 mul2의 함수 형태가 변경된 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.2. 매개 변수 순서 변경&lt;/h4&gt;
&lt;pre id=&quot;code_1774319850048&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

void test(uint32_t n1, uint32_t n2) {
	cout &amp;lt;&amp;lt; &quot;n1 : &quot; &amp;lt;&amp;lt; n1 &amp;lt;&amp;lt; &quot;, n2 : &quot; &amp;lt;&amp;lt; n2 &amp;lt;&amp;lt; endl;
}

int main(void) {
	using namespace std::placeholders;
	
	// _1의 위치와 _2의 위치를 바꾸었습니다.
	function&amp;lt;void(uint32_t,uint32_t)&amp;gt; func = bind(&amp;amp;test, _2, _1);

	// n1 값에 20이, n2값에 10으로 대입된다.
	func(10, 20);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dq6CLV/dJMcaaq8gE7/IXUIuMeDiGtEEjb4bi67kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dq6CLV/dJMcaaq8gE7/IXUIuMeDiGtEEjb4bi67kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dq6CLV/dJMcaaq8gE7/IXUIuMeDiGtEEjb4bi67kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdq6CLV%2FdJMcaaq8gE7%2FIXUIuMeDiGtEEjb4bi67kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;390&quot; height=&quot;85&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.3. ref, cref를 통해 변수의 값을 반영&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;- 주의 사항 -&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;참조하는 변수에 따라 Dangling이 발생할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1774320351021&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

void test(uint32_t n1, uint32_t n2) {
	cout &amp;lt;&amp;lt; &quot;n1 : &quot; &amp;lt;&amp;lt; n1 &amp;lt;&amp;lt; &quot;, n2 : &quot; &amp;lt;&amp;lt; n2 &amp;lt;&amp;lt; endl;
}

int main(void) {
	using namespace std::placeholders;

	uint32_t value1 = 10;
	
	// n1에 value1의 값인 10이 들어간다.
	function&amp;lt;void(uint32_t)&amp;gt; func1 = bind(&amp;amp;test, value1, _1);
	// n1은 value1을 참조하게 된다.
	function&amp;lt;void(uint32_t)&amp;gt; func2 = bind(&amp;amp;test, cref(value1), _1);

	value1 = 100;

	// n1에 10이 들어갔으므로 n1이 10으로 출력
	func1(20);
	// n1이 valu1를 참조하므로 n1이 100으로 출력
	func2(30);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKvOLF/dJMcaduyjOL/FQsKshXj6XJNkmjspkgXm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKvOLF/dJMcaduyjOL/FQsKshXj6XJNkmjspkgXm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKvOLF/dJMcaduyjOL/FQsKshXj6XJNkmjspkgXm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKvOLF%2FdJMcaduyjOL%2FFQsKshXj6XJNkmjspkgXm1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;151&quot; data-origin-width=&quot;285&quot; data-origin-height=&quot;118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.4. bind의 중첩 호출&lt;/h4&gt;
&lt;pre id=&quot;code_1774320933520&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;

using namespace std;

uint32_t test(uint32_t num) {
	cout &amp;lt;&amp;lt; &quot;num : &quot; &amp;lt;&amp;lt; num &amp;lt;&amp;lt; endl;

	return num;
}

int main(void) {
	using namespace std::placeholders;

	auto func1 = bind(&amp;amp;test, _1);
	// func1를 중접
	function&amp;lt;uint32_t(uint32_t)&amp;gt; func2 = bind(&amp;amp;test, func1);

	// func2는 fun1을 중첩하여 bind하였기 때문에 test가 2번 호출
	// func1의 _1는 10으로 대입
	// 중첩된 bind는 placehodler를 공유하여 사용한다.
	func2(10);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vlrGO/dJMcaivTcZp/GKYa4B3UTWR70tp5g93OYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vlrGO/dJMcaivTcZp/GKYa4B3UTWR70tp5g93OYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vlrGO/dJMcaivTcZp/GKYa4B3UTWR70tp5g93OYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvlrGO%2FdJMcaivTcZp%2FGKYa4B3UTWR70tp5g93OYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;399&quot; height=&quot;112&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.5. 다양한 형태의 함수의 호출 일원화&lt;/h4&gt;
&lt;pre id=&quot;code_1774322000986&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;functional&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

void func(uint32_t num) {
	cout &amp;lt;&amp;lt; &quot;[funciton] num : &quot; &amp;lt;&amp;lt; num &amp;lt;&amp;lt; endl;
}

class test {
public:
	void mem_func(uint32_t num) {
		cout &amp;lt;&amp;lt; &quot;[member function] num : &quot; &amp;lt;&amp;lt; num &amp;lt;&amp;lt; endl;
	}
};

int main(void){
	using namespace std::placeholders;

	// Callable 배열
	vector&amp;lt;function&amp;lt;void(uint32_t)&amp;gt;&amp;gt; functions;

	// 일반 함수 bind
	functions.emplace_back(bind(&amp;amp;func, _1));

	// 맴버 함수 함수 bind
	test t1;
	functions.emplace_back(bind(&amp;amp;test::mem_func, &amp;amp;t1, _1));

	// 람다 함수 함수 bind
	functions.emplace_back(
		bind(
			[](uint32_t num) {
				cout &amp;lt;&amp;lt; &quot;[lambda function] num : &quot; &amp;lt;&amp;lt; num &amp;lt;&amp;lt; endl;
			},
			_1
		)
	);

	for (int i = 0; i &amp;lt; functions.size(); i++) {
		functions[i](i);
	}
	
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;138&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cujgIH/dJMcajuNY4L/WiLGBuzCUWysQTKv0epqtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cujgIH/dJMcajuNY4L/WiLGBuzCUWysQTKv0epqtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cujgIH/dJMcajuNY4L/WiLGBuzCUWysQTKv0epqtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcujgIH%2FdJMcajuNY4L%2FWiLGBuzCUWysQTKv0epqtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;187&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;138&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4. 결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; bind는 매우 편리한 기능임에는 분명하지만 C++언어가 그러하듯 잘못사용하였다가는 큰 문제가 발생할 요지가 있습니다. 잘못된 변수를 참조하여 Dangling 문제나 너무 많은 중첩 bind를 통해 성능 저하가 발생할 수 있다는 점이 있지만 이러한 점을 확실이 인지하고 사용한다면 개발에 큰 편의성을 제공해줄 수 있습니다.&lt;/p&gt;</description>
      <category>C++</category>
      <category>bind</category>
      <category>C</category>
      <category>C++</category>
      <category>cpp</category>
      <category>function</category>
      <category>STD</category>
      <category>함수</category>
      <author>Gordon_</author>
      <guid isPermaLink="true">https://littlebitodd-developer.tistory.com/96</guid>
      <comments>https://littlebitodd-developer.tistory.com/96#entry96comment</comments>
      <pubDate>Tue, 24 Mar 2026 12:17:18 +0900</pubDate>
    </item>
  </channel>
</rss>