Tag: yocto beginner guide

  • Integrating DHT11 Sensor Driver into Yocto Image for BeagleBone | Master Step-by-Step LDD Guide

    DHT11 Sensor Driver into Yocto : When I first got my BeagleBone board, I was super excited. I wanted to connect real-world sensors and see live data flowing into my board. One of the simplest yet powerful sensors I picked was the DHT11, a low-cost digital temperature and humidity sensor.

    At first glance, I thought: “It should be as easy as connecting a wire and running a Python script, right?” But then came the challenge — I wanted to integrate it properly at the kernel driver level and make it part of my Yocto-built image, so that every time I flashed my SD card, my BeagleBone would already have the driver and I could directly fetch temperature readings.

    If you’ve ever felt this curiosity, this guide is for you. Let’s go step by step.

    Manual Way: Adding DHT11 Sensor Driver into Yocto for BeagleBone

    Why DHT11 Sensor Driver into Yocto ?

    • Consistency: Every image build includes your driver — no need to manually insert modules each time.
    • Customization: You can control how the driver behaves and integrate it with other services.
    • Scalability: If tomorrow you move to another sensor or a production board, your Yocto setup scales with you.

    Step 1: Set Up Yocto Project Environment

    1. Download Poky and layers git clone git://git.yoctoproject.org/poky.git cd poky git checkout <yocto-version> # e.g., dunfell, honister
    2. Add necessary layers for BeagleBone git clone git://git.yoctoproject.org/meta-ti.git git clone git://git.yoctoproject.org/meta-openembedded.git
    3. Create a build directory source oe-init-build-env build
    4. Set your machine in conf/local.conf MACHINE ?= "beaglebone"

    Step 2: Understand Your DHT11 Sensor

    • DHT11 uses 1-wire digital communication.
    • Pins:
      • VCC: 3.3V or 5V
      • GND: Ground
      • DATA: Connected to a GPIO pin on BeagleBone
    • The driver needs to read the digital pulses and convert them to temperature and humidity.

    Step 3: Create a Custom Layer

    1. Create a new layer for your driver: bitbake-layers create-layer meta-dht11
    2. Add this layer to your build: bitbake-layers add-layer ../meta-dht11

    Step 4: Write the Kernel Driver

    4.1: Create Driver Skeleton

    • Go to your layer: meta-dht11/recipes-kernel/dht11/
    • Create dht11.c:
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/gpio.h>
    #include <linux/delay.h>
    #include <linux/fs.h>
    #include <linux/uaccess.h>
    
    #define DHT11_PIN 60  // Example: GPIO1_28 on BeagleBone
    
    static int major;
    static char temp_str[16];
    
    static int dht11_open(struct inode *inode, struct file *file) {
        return 0;
    }
    
    static int dht11_release(struct inode *inode, struct file *file) {
        return 0;
    }
    
    static ssize_t dht11_read(struct file *file, char __user *buf, size_t len, loff_t *offset) {
        int temperature = 25; // Mock value (we’ll implement real reading later)
        snprintf(temp_str, sizeof(temp_str), "%d\n", temperature);
        if (copy_to_user(buf, temp_str, strlen(temp_str))) {
            return -EFAULT;
        }
        return strlen(temp_str);
    }
    
    static struct file_operations fops = {
        .owner = THIS_MODULE,
        .open = dht11_open,
        .release = dht11_release,
        .read = dht11_read,
    };
    
    static int __init dht11_init(void) {
        major = register_chrdev(0, "dht11", &fops);
        printk(KERN_INFO "DHT11 driver loaded. Major=%d\n", major);
        return 0;
    }
    
    static void __exit dht11_exit(void) {
        unregister_chrdev(major, "dht11");
        printk(KERN_INFO "DHT11 driver unloaded\n");
    }
    
    module_init(dht11_init);
    module_exit(dht11_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Nish");
    MODULE_DESCRIPTION("DHT11 temperature driver for BeagleBone");
    

    4.2: Create the Recipe (.bb file)

    • File: meta-dht11/recipes-kernel/dht11/dht11.bb
    DESCRIPTION = "DHT11 temperature driver"
    LICENSE = "GPLv2"
    SRC_URI = "file://dht11.c"
    
    S = "${WORKDIR}"
    
    do_compile() {
        ${CC} -Wall -O2 -c ${WORKDIR}/dht11.c -o ${WORKDIR}/dht11.o
        ${CC} -Wall -O2 -shared -o ${WORKDIR}/dht11.ko ${WORKDIR}/dht11.o
    }
    
    do_install() {
        install -d ${D}${sysconfdir}/modules
        install -m 0644 ${WORKDIR}/dht11.ko ${D}${sysconfdir}/modules/
    }
    

    Step 5: Build and Add Driver to Image

    1. Build the driver: bitbake dht11
    2. Include it in your image (local.conf): IMAGE_INSTALL_append = " dht11"
    3. Rebuild your image: bitbake core-image-minimal

    Step 6: Boot BeagleBone and Test

    1. Flash .wic image to SD card.
    2. Boot BeagleBone.
    3. Load driver: insmod /etc/modules/dht11.ko
    4. Check temperature: cat /dev/dht11

    Step 7: Implement Actual DHT11 Reading

    • Replace mock temperature with real GPIO reading.
    • Use bit-banging with gpio_get_value() and precise timing with udelay().

    Tips

    • Make sure GPIO pin numbers match your BeagleBone header.
    • For production, consider interrupt-based reading for better accuracy.
    • Use dmesg to debug kernel messages.

    Auto Temperature Reading Without Manual Module Loading

    Step 1: Setup Yocto Kirkstone Environment

    1. Clone Poky (Kirkstone branch):
    git clone -b kirkstone git://git.yoctoproject.org/poky.git
    cd poky
    
    1. Clone meta layers:
    git clone -b kirkstone git://git.yoctoproject.org/meta-openembedded.git
    git clone -b kirkstone git://git.yoctoproject.org/meta-ti.git
    
    1. Initialize the build environment:
    source oe-init-build-env
    
    1. Set your target machine in conf/local.conf:
    MACHINE ?= "beaglebone"
    

    Step 2: Create a Custom Layer for DHT11

    1. Create layer:
    bitbake-layers create-layer meta-dht11
    
    1. Add it to your build:
    bitbake-layers add-layer ../meta-dht11
    

    Step 3: Write the DHT11 Driver

    1. Go to your layer folder:
      meta-dht11/recipes-kernel/dht11/
    2. Create dht11.c:
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/gpio.h>
    #include <linux/delay.h>
    #include <linux/fs.h>
    #include <linux/uaccess.h>
    
    #define DHT11_PIN 60  // Adjust according to BeagleBone header
    
    static int major;
    static char buf[32];
    
    static int dht11_open(struct inode *inode, struct file *file) { return 0; }
    static int dht11_release(struct inode *inode, struct file *file) { return 0; }
    
    static int read_dht11(int *temperature, int *humidity) {
        int bits[40] = {0}, i, j=0, data[5] = {0};
    
        // Send start signal
        gpio_direction_output(DHT11_PIN, 0);
        mdelay(20);
        gpio_direction_input(DHT11_PIN);
        udelay(30);
    
        // Wait for response
        while(gpio_get_value(DHT11_PIN) == 1);
        while(gpio_get_value(DHT11_PIN) == 0);
        while(gpio_get_value(DHT11_PIN) == 1);
    
        // Read 40 bits
        for(i=0;i<40;i++){
            while(gpio_get_value(DHT11_PIN) == 0);
            j=0;
            while(gpio_get_value(DHT11_PIN) == 1){ udelay(1); j++; }
            bits[i] = (j > 40) ? 1 : 0;
        }
    
        // Convert bits to bytes
        for(i=0;i<5;i++){
            data[i]=0;
            for(j=0;j<8;j++){
                data[i]<<=1;
                data[i] |= bits[i*8+j];
            }
        }
    
        if(data[4] != ((data[0]+data[1]+data[2]+data[3]) & 0xFF)) return -1;
    
        *humidity = data[0];
        *temperature = data[2];
        return 0;
    }
    
    static ssize_t dht11_read(struct file *file, char __user *user_buf, size_t len, loff_t *offset){
        int temp=0, hum=0;
        if(read_dht11(&temp,&hum)!=0) return -EIO;
        snprintf(buf,sizeof(buf),"Temp:%dC Hum:%d%%\n",temp,hum);
        if(copy_to_user(user_buf,buf,strlen(buf))) return -EFAULT;
        return strlen(buf);
    }
    
    static struct file_operations fops = {
        .owner=THIS_MODULE,
        .open=dht11_open,
        .release=dht11_release,
        .read=dht11_read,
    };
    
    static int __init dht11_init(void){
        major = register_chrdev(0,"dht11",&fops);
        printk(KERN_INFO "DHT11 driver loaded. Major=%d\n",major);
        return 0;
    }
    
    static void __exit dht11_exit(void){
        unregister_chrdev(major,"dht11");
        printk(KERN_INFO "DHT11 driver unloaded\n");
    }
    
    module_init(dht11_init);
    module_exit(dht11_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Nish");
    MODULE_DESCRIPTION("DHT11 driver for BeagleBone with real readings");
    

    Step 4: Create the BitBake Recipe

    Create dht11.bb in the same folder:

    DESCRIPTION = "DHT11 Temperature & Humidity Kernel Driver"
    LICENSE = "GPLv2"
    SRC_URI = "file://dht11.c"
    
    S = "${WORKDIR}"
    
    do_compile() {
        ${CC} -Wall -O2 -c ${WORKDIR}/dht11.c -o ${WORKDIR}/dht11.o
        ${CC} -Wall -O2 -shared -o ${WORKDIR}/dht11.ko ${WORKDIR}/dht11.o
    }
    
    do_install() {
        install -d ${D}${nonarch_libdir}/modules
        install -m 0644 ${WORKDIR}/dht11.ko ${D}${nonarch_libdir}/modules/
        # Auto-load at boot
        install -d ${D}/etc/modules-load.d
        echo "dht11" > ${D}/etc/modules-load.d/dht11.conf
    }
    

    Step 5: Include Driver in Yocto Image

    Edit conf/local.conf and add:

    IMAGE_INSTALL_append = " dht11"
    

    Step 6: Build the Image

    bitbake core-image-minimal
    

    After completion, your image already includes the DHT11 driver and will auto-load at boot.

    Step 7: Flash SD Card and Test

    1. Flash .wic image to SD card.
    2. Boot BeagleBone.
    3. Check temperature and humidity:
    cat /dev/dht11
    # Example output: Temp:27C Hum:55%
    

    ✅ You don’t need to insmod anymore. The driver is now part of the image.

    Integrating DHT11 Sensor Driver into Yocto Image for BeagleBone
    Integrating DHT11 Sensor Driver into Yocto Image for BeagleBone Master Step-by-Step Guide (2025)
  • How to Write Your First Hello World Driver with Yocto | Master Linux Driver Interview Question (2026)

    How to Write Your First Hello World Driver : Learn step-by-step how to write your first “Hello World” driver with Yocto. This beginner-friendly guide explains kernel module basics, creating a Yocto recipe, building with BitBake, and testing on your embedded Linux board.

    If you’re learning hello world yocto driver and want to understand how device drivers fit into an embedded Linux system, writing a simple Hello World driver is the best starting point. This article will guide you step by step on how to write, compile, and test a kernel module using Yocto.

    How to Write Your First Hello World Driver Step by Step

    Prerequisites for Writing a Hello World Driver with Yocto

    1. Basic Knowledge
      • Understanding of Linux basics (commands, file structure).
      • Some exposure to C programming (especially pointers and functions).
      • Awareness of what a kernel module is.
    2. Yocto Setup
      • A working Yocto build environment (Poky or a vendor BSP like meta-yocto, meta-ti, etc.).
      • You should be able to build at least a core-image-minimal successfully.
    3. Development Machine
      • Ubuntu (20.04 or 22.04 LTS) or Debian recommended.
      • Packages installed: sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc \ build-essential chrpath socat cpio python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping
    4. Target Hardware or Emulator
      • A real embedded board (e.g., BeagleBone Black, Raspberry Pi, STM32MP1, Qualcomm, etc.)
      • OR QEMU (Yocto supports running images in QEMU for testing).
    5. Cross-Compilation Knowledge
      • Basic idea of cross-compilation since Yocto builds software for a different architecture than your PC (e.g., ARM target vs x86 build machine).
    6. Kernel Source & Headers
      • Ensure your Yocto build has the kernel source available for building external modules (linux-yocto recipe).
    7. Bitbake & Layers
      • Familiarity with bitbake commands.
      • Knowledge of adding a custom layer using: bitbake-layers add-layer ../meta-myproject

    Git Clone Methods in Yocto Setup

    When working with Yocto, you usually clone the Poky repository (the reference distribution of Yocto). Depending on your internet and use case, you can use either HTTPS or SSH method.

    1. HTTPS Method (Recommended for Beginners)

    This is the easiest and most common. No special keys required.

    git clone git://git.yoctoproject.org/poky
    

    or sometimes:

    git clone https://git.yoctoproject.org/git/poky
    

    👉 Use this if you’re just learning and don’t want to deal with SSH keys.

    2. SSH Method (For Contributors/Advanced Users)

    If you plan to contribute to Yocto or push code, you need an SSH key.

    git clone git@yoctoproject.org:poky
    

    👉 Use this if you have a developer account with Yocto Project and want to push patches.

    3. Cloning a Specific Yocto Release

    Yocto has releases like dunfell, kirkstone, mickledore, etc. After cloning, you can check out a stable branch:

    cd poky
    git checkout kirkstone
    

    👉 Always use an LTS (Long-Term Support) branch if you’re learning (e.g., kirkstone is an LTS release).

    4. Shallow Clone (Faster, Less Disk Space)

    The Yocto repo is big. If you just want the latest branch, use:

    git clone --branch kirkstone --depth=1 git://git.yoctoproject.org/poky
    

    👉 This avoids downloading the full history.

    For Your Hello World Driver Project

    I recommend:

    git clone https://git.yoctoproject.org/git/poky
    cd poky
    git checkout kirkstone   # or the LTS release your board supports
    

    Then add BSP layers for your board (e.g., meta-raspberrypi, meta-ti).

    Step 1: What is Yocto?

    The Yocto Project is a build system for creating custom Linux distributions for embedded devices. It allows you to create minimal Linux images and include your own applications, libraries, and drivers.

    When working with Yocto, you usually create recipes (.bb files) that tell Yocto how to build and install your software.

    Step 2: Write a Simple “Hello World” Linux Driver

    Let’s create a very basic Linux kernel module (driver).

    👉 Create a file named hello.c

    #include <linux/init.h>      // For module init/exit macros
    #include <linux/module.h>    // For all kernel modules
    #include <linux/kernel.h>    // For printk()
    
    static int __init hello_init(void)
    {
        printk(KERN_INFO "Hello, World from Yocto Driver!\n");
        return 0;
    }
    
    static void __exit hello_exit(void)
    {
        printk(KERN_INFO "Goodbye, World from Yocto Driver!\n");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Beginner");
    MODULE_DESCRIPTION("A Simple Hello World Driver for Yocto");
    
    How to Write Your First Hello World Driver with Yocto Write a Simple "Hello World" Linux Driver

    This driver simply prints a message when it is loaded and unloaded.

    Step 3: Create a Makefile

    Create a file named Makefile in the same directory:

    obj-m += hello.o
    
    all:
    	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    
    clean:
    	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
    How to Write Your First Hello World Driver with Yocto  Makefile

    This allows you to build the kernel module outside the Yocto environment first (just to test).

    Run:

    make
    

    This will generate a file hello.ko (the kernel object module).

    👉 You can load it manually using:

    sudo insmod hello.ko
    dmesg | tail
    

    And remove it using:

    sudo rmmod hello
    dmesg | tail
    

    Step 4: Create a Yocto Recipe for Your Driver

    Now let’s integrate this driver into Yocto.

    Inside your Yocto layer (for example meta-myproject/), create a folder for your driver:

    How to Write Your First Hello World Driver with Yocto | RTOS Interview Question (2025)

    hello.bb (Recipe File)

    DESCRIPTION = "Simple Hello World Kernel Module"
    LICENSE = "GPLv2"
    LIC_FILES_CHKSUM = "file://hello.c;beginline=12;endline=22;md5=3c3e73c4e3f1c0b1c2b0ed8cfae1a777"
    
    SRC_URI = "file://hello.c \
               file://Makefile"
    
    S = "${WORKDIR}"
    
    inherit module
    
    

    Here:

    • inherit module tells Yocto it’s a kernel module.
    • SRC_URI tells Yocto where to find your driver files.

    Step 5: Build with Yocto

    1. Add your layer to Yocto:
    bitbake-layers add-layer ../meta-myproject
    1. Build your driver:
    bitbake hello
    

    After build, the module hello.ko will be available in the Yocto output.

    Step 6: Test the Driver on Target

    Copy the generated .ko file to your embedded board:

    scp tmp/deploy/ipk/*/hello_*.ipk user@board:/home/root/
    

    On the board, install and test:

    opkg install hello_*.ipk
    insmod hello.ko
    dmesg | tail
    

    You should see:

    Hello, World from Yocto Driver!
    

    When removing:

    Goodbye, World from Yocto Driver!
    

    Application Code

    #include <stdio.h>
    int main() {
        printf("Hello, Yocto Krikstone!\n");
        return 0;
    }
    

    Flashing of SD Card using Card Reader USB to SD Card Reader

    How to Write Your First Hello World Driver with Yocto  a)  SD Card Reader
    How to Write Your First Hello World Driver with Yocto  b) balena Tool to flash SD Card

    Target Preparation

    How to Write Your First Hello World Driver with Yocto  c) HW Connection
    How to Write Your First Hello World Driver with Yocto  d) output from serial console

    Conclusion

    Congratulations! 🎉 You just wrote your first Hello World driver with Yocto.

    • You learned how to write a basic Linux kernel module.
    • You created a Yocto recipe for your driver.
    • You built and tested it on your target board.

    This is the foundation. From here, you can extend your driver to work with real hardware like GPIO, I2C, or sensors.

    FAQ Writing Hello World Driver with Yocto

    1. What is Yocto used for?

    Ans: Yocto is a build system that helps developers create custom Linux distributions for embedded devices. It allows you to add drivers, applications, and libraries into your Linux image.

    2. What is a Hello World driver in Linux?

    Ans: A Hello World driver is the simplest Linux kernel module that just prints a message when loaded and unloaded. It helps beginners understand how kernel modules work.

    3. Do I need Yocto to write a Hello World driver?

    Ans : No, you can first write and test it on any Linux system using insmod and rmmod. Yocto is used when you want to integrate the driver into your embedded Linux distribution.

    4. What is the difference between a driver and a kernel module?

    Ans: A driver is a program that lets the kernel communicate with hardware. A kernel module is a piece of code that can be loaded into the Linux kernel at runtime—many drivers are kernel modules.

    5. How do I compile a Hello World driver in Linux?

    Ans: You write the driver code in C, create a Makefile, and run make to build a .ko (kernel object) file. Then use insmod to insert it and dmesg to check messages.

    6. How do I add a driver to Yocto?

    Ans: You create a recipe (.bb file) in a Yocto layer. The recipe tells Yocto how to compile and package your driver. Then you run bitbake to build it.

    7. What is a Yocto recipe?

    Ans: A recipe (.bb file) is a set of instructions used by Yocto to fetch, build, and package software like drivers or applications.

    8. Where can I find the Hello World driver after building with Yocto?

    Ans: Yocto puts the compiled driver (.ko file or .ipk package) in the tmp/deploy/ folder inside your build directory.

    9. How do I test my Yocto driver on the target board?

    Ans: Copy the .ko or .ipk file to your embedded board, use insmod to load the driver, and check logs with dmesg.

    10. Can I extend the Hello World driver to control real hardware?

    Ans: Yes ✅. Once you learn the basics, you can modify the driver to handle GPIO, I2C, SPI, or sensors. This is the next step after the Hello World driver.
    How to Write Your First Hello World Driver with Yocto
    How to Write Your First Hello World Driver with Yocto RTOS Interview Question (2025)