<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Devontae Reid </title>
    <description>The latest articles on Forem by Devontae Reid  (@devdoesit17).</description>
    <link>https://forem.com/devdoesit17</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1294001%2F44ec470d-31fc-41aa-a3ec-1dfdafe81a1b.png</url>
      <title>Forem: Devontae Reid </title>
      <link>https://forem.com/devdoesit17</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devdoesit17"/>
    <language>en</language>
    <item>
      <title>Creating a Character Device Driver for Raspberry Pi Using Buildroot</title>
      <dc:creator>Devontae Reid </dc:creator>
      <pubDate>Sat, 15 Jun 2024 04:16:15 +0000</pubDate>
      <link>https://forem.com/devdoesit17/creating-a-character-device-driver-for-raspberry-pi-using-buildroot-2i9a</link>
      <guid>https://forem.com/devdoesit17/creating-a-character-device-driver-for-raspberry-pi-using-buildroot-2i9a</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;Welcome to those who have read my previous posts, and a warm welcome to all who are new to my blog. As an embedded developer, I continue to navigate the complexities of learning embedded engineering. Imposter syndrome often makes me wonder if I truly grasp the concepts as well as my peers. I am committed to gaining more knowledge in order to overcome numerous challenges that may arise in the embedded world. In this article, I will introduce you to the world of character device drivers, understand their core concepts, and walk you through the steps of creating and building one for a Raspberry Pi using Buildroot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Character Device Drivers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a Character Device Driver?
&lt;/h3&gt;

&lt;p&gt;Character device drivers are a type of device driver that manage devices performing I/O operations sequentially. Character devices, on the other hand, deal with data streams, making them compatible with a variety of peripherals, like serial ports, keyboards, and custom hardware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Concepts
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Device Files&lt;/strong&gt;: In Linux, character devices are represented by device files located in the &lt;code&gt;/dev&lt;/code&gt; directory. These files provide an interface for user-space applications to interact with the hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Major and Minor Numbers&lt;/strong&gt;: Each device file contains both a &lt;a href="https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch03s02.html" rel="noopener noreferrer"&gt;Major and Minor Number&lt;/a&gt;. The major number identifies the driver associated with the device, while the minor number identifies the specific device handled by the driver.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Operations&lt;/strong&gt;: Character device drivers define a set of file operations, such as &lt;code&gt;open&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt;, &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, and &lt;code&gt;ioctl&lt;/code&gt;, to handle interactions between the user-space and the hardware.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a Character Device Driver
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before you embark on your development adventure, make sure you have the basic setup below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Linux development environment (preferably Ubuntu or similar).&lt;/li&gt;
&lt;li&gt;Basic knowledge of C programming and Linux kernel modules.&lt;/li&gt;
&lt;li&gt;Root access to the system for module loading and device file creation.&lt;/li&gt;
&lt;li&gt;A Raspberry Pi board.&lt;/li&gt;
&lt;li&gt;Buildroot configured for the Raspberry Pi.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up Buildroot for Raspberry Pi
&lt;/h3&gt;

&lt;p&gt;First, download and configure Buildroot for your Raspberry Pi as described in the &lt;a href="https://dev.to/devdoesit17/build-a-simple-linux-kernel-using-buildroot-4d29"&gt;previous article&lt;/a&gt; excluding the building step for the moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Writing the Driver Code
&lt;/h3&gt;

&lt;p&gt;Create a directory within your Buildroot package directory for your driver code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; buildroot/package/simple_char_driver
&lt;span class="nb"&gt;cd &lt;/span&gt;buildroot/package/simple_char_driver
&lt;span class="nb"&gt;touch &lt;/span&gt;char_driver.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;char_driver.c&lt;/code&gt; in your preferred text editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/module.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/kernel.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/fs.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/uaccess.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define DEVICE_NAME "char_device"
#define BUFFER_SIZE 1024
&lt;/span&gt;
&lt;span class="cp"&gt;#define CHAR_DEBUG_PRINT(fmt, ...) printk(KERN_INFO "CHAR_DRIVER_INFO: " fmt, ##__VA_ARGS__)
&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;major_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;device_buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BUFFER_SIZE&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;open_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;device_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;inode&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;inode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;open_count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;CHAR_DEBUG_PRINT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Device opened %d times&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;device_release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;inode&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;inode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;CHAR_DEBUG_PRINT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Device closed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="nf"&gt;device_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loff_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BUFFER_SIZE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copy_to_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EFAULT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bytes_read&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;ssize_t&lt;/span&gt; &lt;span class="nf"&gt;device_write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;__user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loff_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bytes_to_write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;BUFFER_SIZE&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BUFFER_SIZE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copy_from_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_to_write&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EFAULT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bytes_to_write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;file_operations&lt;/span&gt; &lt;span class="n"&gt;fops&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;device_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;device_release&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;device_read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;device_write&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;__init&lt;/span&gt; &lt;span class="nf"&gt;char_device_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;major_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;register_chrdev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DEVICE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fops&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;major_number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CHAR_DEBUG_PRINT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to register a major number&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;major_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;CHAR_DEBUG_PRINT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Registered with major number %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;major_number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;__exit&lt;/span&gt; &lt;span class="nf"&gt;char_device_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;unregister_chrdev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;major_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DEVICE_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;CHAR_DEBUG_PRINT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unregistered device&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;MODULE_LICENSE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GPL"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;MODULE_AUTHOR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dev Reid"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;MODULE_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A simple character device driver"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;MODULE_VERSION&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0.1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;module_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char_device_init&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;module_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char_device_exit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Integrating the Driver with Buildroot
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;Config.in&lt;/code&gt; file in the &lt;code&gt;simple_char_driver&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Config.in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;Config.in&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;config BR2_PACKAGE_SIMPLE_CHAR_DRIVER
    bool &lt;span class="s2"&gt;"Simple Character Device Driver"&lt;/span&gt;
    &lt;span class="nb"&gt;help
      &lt;/span&gt;This is a simple character device driver example &lt;span class="k"&gt;for &lt;/span&gt;my raspberry pi 4.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;simple_char_driver.mk&lt;/code&gt; file in the same directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;simple_char_driver.mk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;simple_char_driver.mk&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;################################################################################
# Simple Character Device Driver Buildroot Package Makefile
################################################################################
&lt;/span&gt;
&lt;span class="c"&gt;# Define package variables
&lt;/span&gt;&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_VERSION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 0.1
&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_SITE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;TOPDIR&lt;span class="p"&gt;)&lt;/span&gt;/package/simple_char_driver
&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_SITE_METHOD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;local&lt;/span&gt;
&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_LICENSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; GPL-2.0+
&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_LICENSE_FILES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; char_driver.c

&lt;span class="c"&gt;# Path to the Buildroot cross-compiler
&lt;/span&gt;&lt;span class="nv"&gt;CROSS_COMPILE&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;TOPDIR&lt;span class="p"&gt;)&lt;/span&gt;/output/host/usr/bin/arm-buildroot-linux-gnueabihf-

&lt;span class="c"&gt;# Define build commands
&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_BUILD_CMDS&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;$(LINUX_DIR)&lt;/span&gt; &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_BUILD_DIR&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm &lt;span class="nv"&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;CROSS_COMPILE&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;endef&lt;/span&gt;

&lt;span class="c"&gt;# Define install commands
&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_INSTALL_TARGET_CMDS&lt;/span&gt;
 &lt;span class="err"&gt;$(INSTALL)&lt;/span&gt; &lt;span class="err"&gt;-D&lt;/span&gt; &lt;span class="err"&gt;-m&lt;/span&gt; &lt;span class="err"&gt;0755&lt;/span&gt; &lt;span class="err"&gt;$(SIMPLE_CHAR_DRIVER_BUILD_DIR)/char_driver.ko&lt;/span&gt; &lt;span class="err"&gt;$(TARGET_DIR)/lib/modules/char_driver.ko&lt;/span&gt;
&lt;span class="k"&gt;endef&lt;/span&gt;

&lt;span class="c"&gt;# Define clean commands
&lt;/span&gt;&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_CLEAN_CMDS&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;$(LINUX_DIR)&lt;/span&gt; &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_BUILD_DIR&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm &lt;span class="nv"&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;CROSS_COMPILE&lt;span class="p"&gt;)&lt;/span&gt; clean
&lt;span class="k"&gt;endef&lt;/span&gt;

&lt;span class="c"&gt;# Set directory variables
&lt;/span&gt;&lt;span class="nv"&gt;SIMPLE_CHAR_DRIVER_BUILD_DIR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;BUILD_DIR&lt;span class="p"&gt;)&lt;/span&gt;/simple_char_driver-&lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_VERSION&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Evaluate kernel module and generic package rules
&lt;/span&gt;&lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;kernel-module&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;generic-package&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;Makefile&lt;/code&gt; file in the same directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Makefile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;Makefile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;obj-m&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; char_driver.o

&lt;span class="c"&gt;# Path to the kernel source
&lt;/span&gt;&lt;span class="nv"&gt;KERNELDIR&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_SITE&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Compilation flags
&lt;/span&gt;&lt;span class="nv"&gt;ccflags-y&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nt"&gt;-DDEBUG&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gnu99 &lt;span class="nt"&gt;-Wno-declaration-after-statement&lt;/span&gt;

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all clean&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;MAKE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_SITE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;PWD&lt;span class="p"&gt;)&lt;/span&gt; modules

&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;MAKE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SIMPLE_CHAR_DRIVER_SITE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;PWD&lt;span class="p"&gt;)&lt;/span&gt; clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the package to Buildroot's &lt;code&gt;package/Config.in&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"source &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;package/char_device_driver/Config.in&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; Config.in
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Building the Driver with Buildroot
&lt;/h3&gt;

&lt;p&gt;Reconfigure Buildroot to include your driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
make menuconfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Simple Device Driver&lt;/code&gt; and enable it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqm1cxxyn5gpc2uerazm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqm1cxxyn5gpc2uerazm.png" alt="Main Menu" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build the Buildroot system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After two hours later...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2sy29ldczvoqkzm9etw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2sy29ldczvoqkzm9etw.jpg" alt="Two Hours Later Meme" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Verify that the kernel module file (&lt;code&gt;char_driver.ko&lt;/code&gt;) was added to the rootfs. There are two methods to verify this, and they should have the same output:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;This can be done by check the current folder &lt;code&gt;output/target/lib/modules&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Or you can mount the &lt;code&gt;rootfs.ext4&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-o&lt;/span&gt; loop output/images/rootfs.ext4 /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the &lt;code&gt;lib/modules&lt;/code&gt; folder&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6sz0qqeinhrn3u1efp1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6sz0qqeinhrn3u1efp1l.png" alt="Modules Folder" width="625" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Running the Driver on Raspberry Pi
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flash the Buildroot image&lt;/strong&gt; to your SD card and boot your Raspberry Pi with it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Load the driver module&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;insmod /lib/modules/&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/char_driver.ko
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create the device file&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mknod&lt;/span&gt; /dev/char_device c &amp;lt;major_number&amp;gt; 0
&lt;span class="nb"&gt;chmod &lt;/span&gt;666 /dev/char_device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;major_number&amp;gt;&lt;/code&gt; with the major number from the kernel log. To read the logs from the module, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dmesg | &lt;span class="nb"&gt;grep &lt;/span&gt;char_device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test the driver&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, Device!"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/char_device
&lt;span class="nb"&gt;cat&lt;/span&gt; /dev/char_device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8uujmlj1ub37zrcz539.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8uujmlj1ub37zrcz539.png" alt="Raspberry Pi Console" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Unloading the Driver
&lt;/h3&gt;

&lt;p&gt;When you're done, unload the driver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rmmod char_driver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove the device file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; /dev/char_device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Understanding the core concepts of device files, major and minor numbers, and file operations is important for creating a character device driver for Raspberry Pi using Buildroot. You can build and test a character device driver on your Raspberry Pi by following the instructions in this article. This fundamental understanding paves the way for more intricate driver development and deeper interactions with hardware components in embedded systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  SOLI DEO GLORIA
&lt;/h3&gt;

&lt;p&gt;Helpful Articles:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.billvanleeuwen.ca/writing-and-inserting-a-hello-world-kernel-module-for-the-beaglebone-black-buildroot" rel="noopener noreferrer"&gt;Writing and Inserting a 'Hello World' Kernel Module for the Beaglebone Black (Buildroot)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>linux</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Exploring SoC and MPSoC: Understanding Integrated Circuit Architectures</title>
      <dc:creator>Devontae Reid </dc:creator>
      <pubDate>Sat, 30 Mar 2024 16:16:55 +0000</pubDate>
      <link>https://forem.com/devdoesit17/exploring-soc-and-mpsoc-understanding-integrated-circuit-architectures-2d3c</link>
      <guid>https://forem.com/devdoesit17/exploring-soc-and-mpsoc-understanding-integrated-circuit-architectures-2d3c</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome back to those who have read my previous posts, and a warm welcome to those who are new! As I continue to work as an embedded developer, navigating through the intricacies of SoC and MPSoC architectures, I often find myself grappling with imposter syndrome, wondering if I truly grasp the concepts as well as my peers. My aspiration is to enhance my comprehension and overcome numerous challenges that may arise.&lt;/p&gt;

&lt;p&gt;In the world of integrated circuits(ICs), the terms 'system-on-chip(SoC)' and'multi-processor system-on-chip(MPSoC)' are common. We'll explore the fundamentals of SoC and MPSoC, explore their key features, and highlight the differences between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding System-on-Chip (SoC)
&lt;/h2&gt;

&lt;p&gt;A system-on-chip (SoC) is an integrated circuit (IC) that unites all the parts of a computer or electronic device onto a single chip. The SoC usually has a central processing unit (CPU), memory, input/output (I/O) interfaces, and peripherals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felwab13ws2anu6l4f7vg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felwab13ws2anu6l4f7vg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This makes them suitable for a wide range of applications, including smartphones, tablets, IoT devices, and other embedded systems.&lt;/p&gt;

&lt;p&gt;The best feature of SoCs is their consolidation of multiple hardware components onto a single chip, which allows for reducing system complexity, size, and power consumption vs. traditional multi-chip solutions.&lt;/p&gt;

&lt;p&gt;Some of the leading vendors in the SoC market include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qualcomm&lt;/li&gt;
&lt;li&gt;MediaTek&lt;/li&gt;
&lt;li&gt;Samsung Electronics&lt;/li&gt;
&lt;li&gt;Broadcom&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exploring Multi-Processor System-on-Chip (MPSoC)
&lt;/h2&gt;

&lt;p&gt;The multiprocessor system of computers (MPSoCs) is designed to integrate multiple processing units (CPUs or cores) into a single chip, along with other components such as memory, I/O interfaces, and accelerators.&lt;/p&gt;

&lt;p&gt;MPSoCs achieve better performance and efficiency, as well as superior scalability compared to traditional SoCs. Multiple tasks, enhanced throughput, and adeptly handle intricate workloads are some of the applications where MPSoCs are used. MPSoCs are deployed in applications such as data centers, networking equipment, automotive systems, industrial automation, and consumer electronics.&lt;/p&gt;

&lt;p&gt;Some of the leading vendors in the MPSoC market include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Xilinx&lt;/li&gt;
&lt;li&gt;Intel&lt;/li&gt;
&lt;li&gt;NVIDIA&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Distinguishing Between SoC and MPSoC
&lt;/h2&gt;

&lt;p&gt;Though SoC and MPSoC share resemblances in consolidating multiple components onto a single chip, their primary disparities lie in the number of processing units and their emphasis on parallel processing capabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38uzcmps9crewi69lr51.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38uzcmps9crewi69lr51.jpeg" alt="scratching-head-meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wait what? I thought SoC has only one processing unit with many peripherals. How come there can be a CPU and a graphics processing unit (GPU) on the same chip?&lt;/p&gt;

&lt;p&gt;That is true, while SoCs often integrate a CPU and GPU along with other components onto a single chip, the distinction lies in the emphasis on parallel processing capabilities and the integration of multiple types of processing units specifically for that purpose.&lt;/p&gt;

&lt;p&gt;Another disparity lies in the versatility and customization options presented by MPSoCs, enabling developers to tailor the hardware architecture to meet precise application requisites, whereas SoCs are often optimized for specific applications or use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The difference between SoC and MPSoC is important for choosing the appropriate architecture for diverse applications and fully using the potential of ICs. SoC furnishes complete computing functionality within a singular chip, while MPSoC extends this concept by combining multiple processing units for enhanced performance.  Discerning the disparities between SoC and MPSoC is imperative for electing the appropriate architecture for diverse applications and fully harnessing the potential of IC technologies in the swiftly evolving computing landscape.&lt;/p&gt;

&lt;p&gt;Let's embark on an enlightening journey together, feel free to reach out on &lt;a href="https://www.linkedin.com/in/devontaereid" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or send a DM on &lt;a href="https://twitter.com/_yodev_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.ansys.com/blog/what-is-system-on-a-chip" rel="noopener noreferrer"&gt;What is System-on-Chip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://microcontrollerslab.com/system-on-chip-soc-introduction/" rel="noopener noreferrer"&gt;System-on-Chip Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cl.cam.ac.uk/teaching/1011/SysOnChip/socdam-notes1011.pdf" rel="noopener noreferrer"&gt;Notes from SoC course in UK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.telink-semi.com/system-on-chip/" rel="noopener noreferrer"&gt;The Power of Using a System on Chip (SoC) Approach for IoT Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cover Photo from &lt;a href="https://www.androidauthority.com/qualcomm-snapdragon-soc-guide-908280/" rel="noopener noreferrer"&gt;Android Authority&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Soli Deo Gloria!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>integratedcircuits</category>
      <category>embeddedsystems</category>
    </item>
    <item>
      <title>Build a Simple Linux Kernel Using Buildroot</title>
      <dc:creator>Devontae Reid </dc:creator>
      <pubDate>Tue, 27 Feb 2024 00:28:27 +0000</pubDate>
      <link>https://forem.com/devdoesit17/build-a-simple-linux-kernel-using-buildroot-4d29</link>
      <guid>https://forem.com/devdoesit17/build-a-simple-linux-kernel-using-buildroot-4d29</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to this guide on how to build a Linux kernel using &lt;a href="https://buildroot.org/" rel="noopener noreferrer"&gt;Buildroot&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;This guide will give you a basic introduction to Linux kernel development. By the end of this guide you will know how to set up a Buildroot project, config the project, and flash the image to an SD card and have it running on a Raspberry Pi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you embark on your Buildroot adventure, make sure your PC isn't begging for more space because of all the memes and apps you don't use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.kym-cdn.com%2Fphotos%2Fimages%2Foriginal%2F001%2F512%2F106%2F411.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.kym-cdn.com%2Fphotos%2Fimages%2Foriginal%2F001%2F512%2F106%2F411.jpg" alt="no space here"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aim for at least ~35GB of free space.&lt;/p&gt;

&lt;p&gt;Ensure that you have the necessary packages on your Linux machine found in the &lt;a href="https://buildroot.org/downloads/manual/manual.html#requirement" rel="noopener noreferrer"&gt;requirements section within Buildroot Doc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some minimal familiarity with Embedded Systems and Linux Ubuntu OS, as this will be the main OS we will be using.&lt;/p&gt;

&lt;p&gt;Before we start, we need to understand what Buildroot is, and I'll make sure for it to be short and sweet!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Buildroot?
&lt;/h2&gt;

&lt;p&gt;To use their own definition, "Buildroot is a simple, efficient and easy-to-use tool to generate embedded Linux systems through cross-compilation.". Cross-compilation is basically building software (SW) on one platform to be used on another platform.&lt;/p&gt;

&lt;p&gt;Now, let’s get this started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Linux Kernel
&lt;/h2&gt;

&lt;p&gt;Clone the &lt;a href="https://gitlab.com/buildroot.org/buildroot/" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; to download Buildroot using the following command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://gitlab.com/buildroot.org/buildroot.git


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once downloaded, open the newly created buildroot directory.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;buildroot


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Grab the configuration file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;make rasberrypi4_defconfig


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;This will create a config.in file into your local buildroot directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Time to config the kernel configuration. Run &lt;code&gt;make menuconfig&lt;/code&gt; to access Buildroot's configuration menu. Here, specify the target architecture, select desired packages and features, and configure any custom settings according to your project requirements.&lt;/p&gt;

&lt;p&gt;For my case, I will just be updating the startup boot manager. This is found in &lt;code&gt;System Configuration -&amp;gt; System banner&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;make menuconfig


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wk377gcgoy0teszm045.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wk377gcgoy0teszm045.png" alt="Menuconfig image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to &lt;code&gt;System Configuration&lt;/code&gt; and update &lt;code&gt;System banner&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiir8abz8ormrj2da9d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiir8abz8ormrj2da9d8.png" alt="System Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01dqy1juzkdinibjhp3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F01dqy1juzkdinibjhp3u.png" alt="System banner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exit and save your kernel config&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eqmhj1u34zvx7hx3x6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eqmhj1u34zvx7hx3x6l.png" alt="Menu Save Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build your kernel&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;make


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After two hours later...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2sy29ldczvoqkzm9etw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2sy29ldczvoqkzm9etw.jpg" alt="Two Hours Later Meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should have your bootable image inside the &lt;code&gt;output/images&lt;/code&gt; directory that you can add to your SD card&lt;/p&gt;

&lt;p&gt;Insert the SD card into the Raspberry Pi 4 and power it on to boot into the custom Linux system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bz7dg8a0cbkhxyjutvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bz7dg8a0cbkhxyjutvx.png" alt="Final Result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following these steps and along with installing the prerequisites, you will have everything you need to build a simple Linux kernel using Buildroot.&lt;/p&gt;

&lt;p&gt;I can’t wait to see what you’ll build; if you follow these steps and get stuck or have any questions, feel free to reach out on &lt;a href="https://www.linkedin.com/in/devontaereid" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or send a DM on &lt;a href="https://twitter.com/_yodev_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cover Photo by &lt;a href="https://unsplash.com/@stefanbc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Stefan Cosma&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/green-and-black-computer-motherboard-f3Yk7gW6chM?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>linux</category>
      <category>kernel</category>
      <category>cpp</category>
    </item>
  </channel>
</rss>
