Emulating Embedded Linux Systems with QEMU

Emulating Embedded Linux Systems with QEMU


1. Introduction

Embedded software development relies on embedded hardware devices, such as development boards, external module devices, etc., but if the debugging work has nothing to do with peripherals, only the kernel debugging can be simulated using QEMU without purchasing hardware.

It’s available for Linux and Windows hosts and emulated PowerPC, ARM, MIPS, and SPARC targets. QEMU takes the approach of providing a minimal translation layer between the host and target processor. The host processor is the one running the emulator, and the target processor is what’s being emulated.

The following is a detailed introduction to the process of setting up QEMU development environment.


2. Environment

2.1 Used environment

* Ubuntu-18.04.1


* PC:Windows10

* Virtual Machine:VirtualBox-5.18

* Virtual OS:Ubuntu-18.04.1

* Simulated development board: vexpres

2.2 Tools used when setting up the environment

* qemu-4.2.0

* linux-4.14.172 (Linux Kernel)

* u-boot-2017.05

* busybox-1.31.1

* arm-linux-gnueabi-gcc

Put all related files in  /home/joe/qemu

3. Install cross-compilation tools

# sudo apt install gcc-arm-linux-gnueabi


Check if the installation is successful

$ arm-linux-gnueabi-gcc -v

Using built-inspecs.



Target: arm-linux-gnueabi

Configured with: ../src/configure -v –with-pkgversion=’Ubuntu/Linaro 7.5.0-3ubuntu1~18.04′–with-bugurl=file:///usr

Thread model: posix

gcc version 7.5.0(Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)


4. Configure and Compile the Linux kernel

4.1 Download Linux Kernel

Download the required kernel version from www.kernel.org.

Here I download the relatively latest long-term supported kernel version linux-4.4.157

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.157.tar.xz  to /qemu directory

4.2 Unzip the Linux kernel

# tar xvJf linux-4.4.157.tar.xz

4.3 Compile Linux Kernel

// Enter the kernel source file directory

# cd linux-4.4.157

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm vexpress_defconfig

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm menuconfig

If running menuconfig shows that the ncurses package is missing, just run the following command to install it)

$ sudo apt-get install libncurses5-dev

Enter the menu configuration and make the following settings

Compile with cross toolchain

After successful compilation, Generate a kernel image file under the directory

arch/arm/boot, zImage and dtb can be copied into a separate folder for convenient use


5. Install QEMU Tools

5.1 Install QEMU

* wget https://download.qemu.org/qemu-4.2.0.tar.xz

* tar xvJf qemu-4.2.0.tar.xz

* cd qemu-4.2.0

5.2 Install dependent packages before configuring QEMU

# apt install zlib1g-dev
# apt install libglib2.0-0 libglib2.0-dev
# apt install libsdl1.2-dev
# apt install libpixman-1-dev libfdt-dev

In order to prevent the files from being messy after compilation, create the builder directory as the intermediate target path for compilation.

Configure, compile and install QEMU.

5.3 Configure QEMU to support all boards under the arm architecture

# ../configure –target-list=arm-softmmu –audio-drv-list=

If pixman is missing when the following prompt appears,

use sudo apt-get install libpixman-1-dev to install it.

5.4 View QEMU version

5.5 View development boards supported by QEMU

5.6 Run QEMU

# qemu-system-arm -M vexpress-a9 -m 512M -kernel ./zImage -dtb ./vexpress-v2p-ca9.dtb -nographic -append “console=ttyAMA0”




# qemu-system-arm -M vexpress-a9 -m 512M -kernel linux-.4.157/arch/arm/boot/zImage -dtb linux-4.4.157/arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic -append “console=ttyAMA0”

In order to better testing and start qemu, you can create the startup script start.sh, and give the script permission to run chmod +x start.sh




qemu-system-arm \

-M vexpress-a9 \

-m 512M \

-kernel /home/joe/jemu/linux-4.4.157/arch/arm/boot/zImage \

-dtb /home/joe/jemu/linux-4.4.157/arch/arm/boot/dts/vexpress-v2p-ca9.dtb \

-nographic \

-append “console=ttyAMA0”


6. Make a root file system

Use busybox to make a simple root file system.

6.1 Download busybox tool

Download busybox from https://busybox.net/downloads/

# wget https://busybox.net/downloads/busybox-1.31.1.tar.bz2

# tar xjvf busybox-1.31.1.tar.bz2

# cd busybox-1.31.1

# make defconfig

# make CROSS_COMPILE=arm-linux-gnueabi-

# make install CROSS_COMPILE=arm-linux-gnueabi-

The following information is prompted, indicating that the installation is successful.

After the installation is complete, the generated target file defaults to the ./_install directory.


6.2 Generate root file system

6.2.1 compile and install busybox

# mkdir rootfs

# sudo cp -r _install/* rootfs/

6.2.2 Add glibc library, add loader and dynamic library in the root file system

# sudo cp -r _install/* rootfs/

# sudo cp -p /usr/arm-linux-gnueabi/lib/* rootfs/lib/

6.2.3 Create 4 tty terminal devices (c stands for character device, 4 is the major device number, and 1~4 are the minor device numbers respectively)


6.3 Make SD card file system image

6.3.1 Generate an empty SD card image

# dd if=/dev/zero of=rootfs.ext3 bs=1M count=32

6.3.2 Format SD card as exts file system

# mkfs.ext3 rootfs.ext3

6.3.3 Burn rootfs to SD card

# sudo mount -t ext3 rootfs.ext3 /mnt -o loop

# sudo cp -rf rootfs/* /mnt/

# sudo umount /mnt


7. Verify

7.1 Start Qemu

Run the following command to test, check if the compiled kernel can run successfully

# sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel ~/qemu/zImage –dtb ~/qemu/vexpress-v2p-ca9.dtb -nographic -append “console=ttyAMA0”

Or using Script:


In the above test, the kernel will report panic, suggesting that we lack the root file system.

The above problem is due to the busybox tool generated inn the x86 environment.

We used make install when install busybox, so you should use

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install


The compilation tool generates the busybox tool used by the arm platform

# file rootfs/bin/busybox

rootfs/bin/busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=cbcd33b8d6c946cb19408a5e8e714de554c87f52, stripped


7.2 Verify again

Now, Qemu has started the Linux kernel and mounted the file system successfully, and can interact with the system with simple functions through the serial terminal. The problem of not being able to run /etc/init.d/rcS in the printing process, you only need to add the /etc/init.d/rcS file. The content of the file can be a prompt statement.


7.3 Exit QEMU

Two ways to exit qemu

* In another terminal input: kill all qemu-system-arm

* In Qemu input:  Ctrl+ A; X

QEMU: Terminated


8. Start the Linux kernel through u-boot

Embedded system usually include: u-boot, kernel, rootfs, and appfs. The positional relationship of these parts on the ARM development board shown in the figure below


BootLoader BootParameters Kernel Rootfs Appfs


Rootfs can run in board or PC


8.1 Prepare U-boot

8.1.1 Download u-boot

http://ftp.denx.de/pub/u-boot/,   we use: u-boot-2021.01.tar.bz2

# tar -jxvf u-boot-2018.09.tar.bz2

8.1.2 Compile u-boot

# vim Makefile

CROSS_COMPILE = arm-linux-gnueabi-

# vim config.mk

ARCH = arm

# make vexpress_ca9x4_defconfig, error

Need :  sudo apt install bison

sudo apt install flex

then:     # make -j4    error

Need :   export CROSS_COMPILE=arm-linux-gnueabi-

export ARCH=arm

again:  # make vexpress_ca9x4_defconfig

# make -j4


 8.1.3 Test, start u-boot

$ sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot-2021.01/u-boot –nographic


8.2 Kernel configuration compilation

Use u-boot to boot the kernel image:

Need to compile the kernel into uImage format,

Need to specify the load address of uImage in memory

Specify when compiling the kernel: make LOADADDR=? uImage -j4


# cd /home/joe/qemu/linux-4.4.157

# make LOADADDR=0x60003000 uImage -j4


After u-boot compilation is finished, a mkimage file will be generated under the tool folder, copy this file to the bin folder under the cross compiler directory.

$ cd qemu/linux-4.4.157


$ sudo apt install u-boot-tools

Get uImage

9. QEMU network function settings

When the Qemu virtual machine starts on u-boot, uImage needs to be loaded into the memory, and uImage can be downloaded to the specified address in the memory through the TFTP server.

9.1 Check whether the host kernel supports the tun/tap module

// Install the two tools that the bridged network depends on

# sudo apt install uml-utilities bridge-utils

Create tun device file: /dev/net/tun (usually created automatically)

Modify the /etc/network/interfaces (configure the network, restart to take effect)

# sudo vim /etc/network/interfaces

auto loiface lo inet loopbackauto enp0s3          // name of virtual network cardauto br0iface br0 inet dhcpbridge_ports enp0s3


9.2 Reboot

# reboot

Then check Qemu’s network environment

The virtual network port br0 is the network port for the communication between the Qemu virtual machine and the Linux host.


10. Install TFTP server

Create a TFTP server to download uImage to the memory when launching uImage for the Qemu simulation development board


10.1 Install tftp tool


$ apt-get install tftp-hpa tftpd-hpa xinetd


10.2 Modify the configuration file and set the TFTP server directory

# sudo vim /etc/default/tftpd-hpa




10.3 Create a tftp directory on the Linux host

# mkdir /home/joe/tftpboot

# chmod 777 /home/joe/tftpboot


10.4 Restart the tftp service

# sudo /etc/init.d/tftpd-hpa restart


10.5 Set kernel startup parameters in u-boot

copy uImage and cexpress-v2p-ca9.dtb to tftpboot

Start Qemu to verify


$ sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot-2021.01/u-boot –nographic -net nic,vlan=0 -net tap,vlan=0,ifname=tap0 -sd rootfs.ext3


Now, the rootfs directory is a simple root file system, which can be made into a mirror file, and the mirror file can be burned to the development board, or the Linux kernel can be started by u-boot in Qemu and mounted on the mirror file. It can also be set to boot via NFS network file system.


11. Mount NFS file system

11.1 Install and configure NFS service

11.1.1 Install

$ sudo apt install nfs-kernel-server


11.1.2  Configutation

$ sudo mkdir /home/joe/qemu/rootfs

$ sudo chown nobody:nogroup /home/joe/qemu/rootfs

$ sudo chmod 777 /home/joe/qemu/rootfs

$ sudo nano /etc/exports

Add:  /home/joe/qemu/rootfs *(rw,sync,no_root_squash)


Restart nfs server:

$ sudo /etc/init.d/nfs-kernel-server  restart

Or: $systemctl restart nfs-kernel-server


Check whether the NFS shared directory is created

$ sudo showmount –e

When using the NFS network file system, the Linux host needs to close the system firewall, otherwise, abnormalities will occur when the system is running.



Hopefully, with the help of this blog, you know more about QEMU. All the techniques demonstrated above were used in various submissions to our program. There’s not a single, fixed way to emulate with QEMU. Explore different techniques and see what works for you. Familiarize yourself with the knowledge and you will be surprised at how it can help you in unexpected ways.

Introduction of Lichee Pi

Introduction of Lichee Pi

The LicheePi is a delicate, single-board computer, running on the low-cost Allwinner V3S platform which is popularity in recent years. It can be used for beginners to learn Linux or for product development. it offers a wealth of peripherals (LCD, ETH, UART, SPI, I2C, PWM, SDIO…) and powerful performance.



        Lichee Zero                                  Lichee Nano





                                 Lichee Pi Zero                                                                          Lichee Pi Nano 






SoC Allwinner V3S Allwinner F1C100S
CPU ARM Cortex-A7 ARM9
Operating Freq. 1.2GHz 408MHz
Storage SPI Flash/Micro-SD SPI Flash/Micro-SD



* Universal 40P RGB LCD FPC:

* Supported resolutions: 272×480, 480×800,1024×600

* Onboard RTP chip, supports a touch screen

* Universal 40P RGB LCD FPC:

* Supported resolutions: 272×480, 480×800,1024×600

* Onboard RTP chip, supports a touch screen



* SDIO x2
* SPI x1
* I2C x2
* UARTx3
* 100M Ether x1(include EPHY)
* OTG USB x1
* PWM x2
* LRADC x1
* Speakerx2 + Mic x1
* SDIO x1
* SPI x2
* TWIX x3
* UART x3
* OTG USB x1
* TV out* PWM x2
* LRADC x1
* Speakerx2 + Mic x1

Electrical Information


Micro USB 5V, 2.54mm pins 3.3V~5V power supply; 1.27mm stamp hole power supply.

1GHz linux IDLE run 90~100mA; cpu-burn run ~180mA

Storage Temperature -40~125

Operating Temperature -20~70

Micro USB 5V, 2.54mm pins 3.3V~5V power supply; 1.27mm stamp hole power supply.

408MHz linux IDLE run 90~54mA; with screen operating current ~250mA

Storage Temperature -40~125

Operating Temperature -20~70


The temperature when running the Linux stress test is only slightly higher than the body temperature.


Lichee Pi support many OS such as: Linux, RT-Tread, Xboot or no OS.

Like most MCU, the Lichee Pi can connect to several low-speed interfaces, such as GPIO, UART, PWM, ADC, I2C, SPI, and more. Moreover, it can run other high-speed peripherals such as RGB LCD, EPHY, MIPI CSI, OTG USB, and more. The Lichee Pi has an integrated codec that allows direct connection to a headphone or microphone.


Display Connector:

The universal 40P LCD comes with a led back light and four-wire lines, electrical resistance touch, which is very suitable for display and interaction. A13 also supports four-wire resistance touch function, can carry out two-point touch detection.


This interface is compatible with the interface of ORIENT DISPLAY products.










Lichee Pi Link:

Telegram group: https://t.me/sipeed

Introduction to Orient Display Embedded Project

Introduction to Orient Display Embedded Project

Orient Display is one of the world’s leading display LCD display manufacturers which was founded in 1996 by executives more than 25 years of R&D and production experience. Besides display, Orient Display also focused on embedded technologies which are including ARM architecture and has accumulated rich experience in embedded products.

Now Orient Display Technical Services include hardware, software and consulting.


Our Hardware team make prototypes in the shortest time according to your design ideas and requirements. We specialize in the design of cost-effective or a complex high-performance board to meet your requirement for high reliability in a short development cycle.

– Schematic Design

– PCB Layout

– Industry Product Customization


Our Software team specializes in Linux-based ARM® designsPowerPC and x86 processor, to name a few. As a complete solution provider for Linux, Android and WinCE in embedded systems, we can solve the end-to-end system-related problems of your products.

– System migration, optimization and tailoring

– Drive development

– Kernel Tailoring

– Porting LINUX KERNEL to ARM, PPC or x86 Board

– APP development (application, Linux QT, Linux C/++)


Our FAE team also provide you with a full range of technologies for your products or semi-finished products.

– We provide consultation on software & hardware resources of our products;

– We solve problems encountered during the use of software & hardware manuals of our products;

– OEM and ODM after-sales technical support;

– Data maintenance and update;

– Orient Display products are backed by our Lowest Price Guarantee.


Development Sequence


1. System Requirements Analysis

* Design tasks, goals, specifications

–  This provided by our customers

* Functional and non-functional requirement

–  Include system performance, cost, power consumption, volume, weight and other factors


2. Architecture Design

A good architecture is the key to the success of the design. In this step, it is often necessary to do following things:

  • Select the main chip:

— ARM Cortex A, R or M,  or PowerPc or ColdFire

  • Determine the RTOS:

— Linux, uClinux, Vxworks, freeRTOS, WinCE

  • Select Display:

TFT Panel, Sunlight Readable TFT, LCD Glass Panels, Graphic LCD,  OLED Display, Touch Panels, Embedded LCD display or Custom made display by Orient Display

  • Programming language:

— c/c++, python, Java

  • Development tools:

u-boot, busybox, QT, Ubuntu, stm32CubeIde, visual studio, android studio, keil uVision, RT-Tread studio


3. Hardware and Software Co-design

In order to shorten the product development cycle:

Hardware:  We usually begin project from evaluation board such as orient display AIY-A002M, AIY-A003M and AIY-A005M. later will Customized board to fit project, discard parts which don’t need.

Software Development Sequence:

  • We usually choose u-boot as Bootloader, it 1)init cpu to known state 2)init memory 3)init interrupt 4)init clock 5)load kernel to running address
  • Configure Kernel:

1) configure kernel system: *memory management, *file systems, *device driver, *network stack, *I/O Systems

2) write I/O device driver *char device driver, *block device driver, *net device driver

  • Select Applications:

*Select a user library *Build user application *Configure Initialization process *Build root FS


4. System Integration

Integrate the system’s software, hardware and execution devices together, debug, find and improve the errors in the unit design process.


5. System Test

Test the designed system to see if it meets the functional requirements given in the specification. The biggest feature of the embedded system development model is the comprehensive development of software and hardware.


In Conclusion

Orient Display has an amazing team of talented experts with the experience and capabilities to create an embedded display module from concept through to production.

If you have any questions, please contact our engineers at: tech@orientdisplay.com.

How to select ARM Processors

How to select ARM Processors


The widest range of microprocessor cores for almost all application markets. Explore ARM. Performance, power & cost requirements for almost all application markets, processors are crucial. The system performance depends heavily on its hardware; this article will guide you through a study of the ARM Processor and be of great assistance in your decision-making.


A Brief Introduction to ARM

Figure 1. ARM Processors Roadmap


Before 2003, there are classic ARM Processors which are including ARM7(ARMv4 Architecture), ARM9(ARMv5 Architecture), ARM11(ARMv6 Architecture).  ARM7 has no MMU (memory management unit), cannot run multi-user multi-process system such as Linux and WinCE. Only can run system such as ucOS and ucLinux which do not need MMU.  ARM9 and ARM11 are embedded CPUs with MMU, which can run Linux.

After 2003, When it came to the ARMv7 architecture, it was named after Cortex and divided into three series: Cortex-A, Cortex-R, and Cortex-M.

  • Cortex-A — application processor cores for a performance-intensive systems
  • Cortex-R – high-performance cores for real-time applications
  • Cortex-M – microcontroller cores for a wide range of embedded applications

Simply put, Cortex-A series are suitable for applications that have high computing requirements, run rich operating systems, and provide interactive media and graphics experience. Cortex-R are suitable for that require reliability, high availability, fault tolerance, maintainability and real-time response. Cortex-M series are aimed at cost and power-sensitive MCUs and end applications.


Cortex-A VS Cortex-R VS Cortex-M


The Cortex-A category of processors is dedicated to Linux and Android devices. Any devices – starting from smartwatches and tablets and continuing with networking equipment – can be supported by Cortex-A processors.

  • Cortex-A processors (A5, A7, A8, A9, A12, A15 and A17) is based on the ARMv7-A architecture
  • The set of common features for A-processors includes a media processing engine (NEON), a tool for security purposes (Trustzone), and various supported instruction sets (ARM, Thumb, DSP etc.)
  • The main features of Cortex-A processors are top performance and brilliant power efficiency closely bundled to provide users with the best service possible

The main characteristics of Cortex-A processor:

Cortex-A5:  The Cortex A5 is the smallest and lowest power member of the Cortex A series, but it can still demonstrate multicore performance, it is compatible with A9 and A15 processors.

Cortex-A7:  The power consumption of A7 is nearly the same as A5, But the performance provided by the A7 is 20% higher than A5 as well as full architectural compatibility with Cortex-A15 and Cortex-A17. The Cortex-A7 is an ideal choice for cost -sensitive smartphone and tablet implementations.

Contrex-A15: The Cortex-A15 is the highest performance member of this series, providing twice the performance than A9.  A15 finds its application in high-end devices, low-power servers, and wireless infrastructure. This is the first processor support for data management and virtual environment solutions.

Contrex-A17: The Cortex-A17 demonstrates 60% higher performance than that of the A9. The main aim is satisfying the needs of premium-class devices.

Contrex-A50: Contrex-A50, latest series, are built on the ARMv8 architecture and bring with them support for Arch64-bit an energy-efficient system. An obvious reason for the move to 64-bit is the support of more than 4GB of physical memory, which is already achieved on Cortex-A15 and Cortex-A7.



Cortex-R processors target high-performance real-time applications such as hard disk controllers, networking equipment media players, and other similar devices, Furthermore, it also great support for the automotive industry such as airbags, braking systems and engine management.

Cortex-R4:  Cortex-R4 is well suited for automotive applications. It can be clocked up to 600 MHz, has an 8-stage pipeline with dual-issue, pre-fetch and a low latency interrupt system making it ideal for safety critical systems.

Cortex-R5: Cortex-R5 extends features offered by R4 and adding increased efficiency, reliability and enhance error management. The dual-core implementation makes it possible to build very powerful, flexible systems with real-time responses.

Cortex-R7: The Cortex-R7 significantly extends the performance. They feature an 11-stage pipeline and enable both out-of-order execution and high-level branch prediction. Tools can be implemented for lock-step, symmetric, and asymmetric multiprocessing. The generic interrupt controller is another significant feature that should be mentioned.



Cortex-M designed specifically to target MCU market. The Cortex-M series is built on the ARMv7-M architecture (used for Cortex-M3 and Cortex-M4), and the smaller Cortex-M0+ is built on the ARMv6-M architecture. It is safe to say that the Cortex-M has become for the 32-bit world what the 8051 is for the 8-bit – an industry-standard core supplied by many vendors. The Cortex-M series can be implemented as a soft core in an FPGA, for example, but it is much more common to find them implemented as MCU with integrated memories, clocks and peripherals. Some are optimized for energy efficiency, some for high performance and some are tailored to a specific market segment such as smart metering

For applications that are particularly cost sensitive or are migrating from 8-bit to 32-bit, the smallest member of the Cortex-M series might be the best choice.

Cortex-M0: The Cortex-M0+ uses the Thumb-2 instruction set and has a 2-stage pipeline. Significant features are the bus for single-cycle GPIO and the micro trace buffer.

Cortex-M3&M4:  The Cortex-M3 and Cortex-M4 are very similar cores. Each offers a 3-stage pipeline, multiple 32-bit busses, clock speeds up to 200 MHz and very efficient debug options. The significant difference is the Cortex-M4 core’s capability for DSP. The Cortex-M3 and Cortex-M4 share the same architecture and instruction set (Thumb-2). If your application requires floating point math, you will get this done considerably faster on a Cortex-M4 than you will on a Cortex-M3. That said, for an application that is not using the DSP or FPU capabilities of the Cortex-M4, you will see the same level of performance and power consumption on a Cortex-M3. In other words, if you need DSP functionality, go with a Cortex-M4. Otherwise, the Cortex-M3 will do the job.



Figure 2. Cortex overview


ARM processors offer a variety of capabilities for different purposes. With a little bit of thought and investigation, you will be able to find the right processor that suits your application needs. whether it’s for a high-end tablet or an ultra-low-cost wireless sensor node.

It is a challenge to make the right choice of Cortex core and turn the idea into reality. But a team of experienced professionals can take care of all the issues and implement concepts of any complexity.

Orient Display has focused on ARM processor-related technologies for many years, and has accumulated rich experience in the development and implementation of ARM architecture products. While continuously launching development platforms and core board that meet the general needs of the market, it also addresses the individual project needs of customers. Provide customized services.

Our hardware team can produce prototypes in the shortest time according to your design ideas and needs. Our software team can help you customize all the functions of the cutting driver layer.

Contact us and we will help to make your plans from initial idea to final product.

How to use Graphic LCD Displays with Raspberry Pi?

How to connect Graphic LCD to Raspberry PI?

The article shows how to hook up a 128×64 graphics LCD display to a Raspberry Pi.

LCD used is a 128×64 with LCD controller of ST7565. It can be powered directly from the Raspberry Pi 3.3V rail. It requires 5 GPIO pins for data.

The schematic is, CS (Chip Select), RST(Reset) and A0 (Register Select) can be connected to any 3 GPIO pins. In this example, 8,24 and 25 are default values. Different values can be specified as parameters when instantiating the ST7565 Python class. SCLK (Serial Clock) on the GLCD goes to GPIO 11 which is the Pi’s serial clock. SID (Serial Input Data) on the GLCD goes to GPIO 10 on the Pi which is MOSI. GPIO 10 and 11 must be used for SID and SCLK. Vdd is connected to a 3.3V pin on the PI and the grounds are also connected.

The LCD has a RGB backlight. The LED pins can go to GPIO’s 16,20 and 21. To control the color from the Pi, specifying RGB pins when instantiate the ST7565 class. The resistors must be placed in series to limit the current to prevent LED breakdown. The LED brightness can be changed by using different values of resistors. It will be best to adjust the current to be around 20mA, of course, different values will result in a different mix of colors. It is very difficult to mix a pure white color. Please calculate the resistor value carefully, at 40mA, the LED brightness will decrease sharply with time, with the current of close to 60mA, the LED might be breakdown and be permanently damaged.

How to program a Graphic LCD?

The display is 128 pixels horizontal by 64 pixels vertical. The LCD can be broken into 8 horizontal pages. They are numbered from 3 to 0 and 7 to 4 up to down. Each page includes 128 columns and 8 rows of pixels. To address the pixels, specifying the page and column number, and send a byte to fill 8 vertical pixels at once.

The display has SPI (Serial Peripheral Interface) to connect to Pi. SPI requires 3 lines MOSI, MISO and Clock. The Pi is the master and the GLCD is the slave. In this example, Only writing to GLCD and not ready, so the connection to MOSI and Clock lines are needed. MOSI is the output from the Pi to the GLCD and the Clock synchronizes the timing.

  1. Enable SPI on Raspberry Pi first
  2. From the raspi-config menu, select Advanced Options, then SPI. Then select Yes for “ Would like the SPI interface to be enabled”. Hit OK, Reboot. Select Yes for “ the SPI kernel module to be loaded by default”. Reboot the Pi after enabling SPI. Then test SPI using IsmodIt should return SPI_bcm2708 or spi_bcm2835 depending on the Pi version. The python SPI library requires python2.7 dev which can be installed with apt-get install:
  3. The Python SPI library is called py-spidev. It can be installed using git:GLCD Python library for the Pi can be downloaded from the GitHub site.
  4. The main ST7565 library (st7565.py) handles drawing, text & bitmaps, and a font module (xglcd_font.py) to load X-GLCD fonts. Here are the basic drawing commands which to create points, lines, rectangles, circles, ellipses, and regular polygons:For more details, please refer to the reference below or contact our engineers.

Getting started with projects based on STM32G071RB Board using STM32CubeIDE

Getting started with projects based on STM32G071RB Board using STM32CubeIDE

Check out our Control Board!

Getting started with a 32-bit ARM-based microcontroller is always a little daunting. There are too many of available microcontrollers, platforms, development boards, tools, and software. This note describes step by step how to begin a LED project.

Getting started: about Development Board STM32G071RB


  • Core: Arm® 32-bit Cortex®-M0+ CPU, frequency up to 64 MHz
  • Up to 128 Kbytes of Flash memory, 36 Kbytes of SRAM
  • 7-channel DMA controller with flexible mapping
  • 12-bit, 0.4 µs ADC (up to 16 ext. channels)
  • Two 12-bit DACs, low-power sample-and-hold
  • Two I2C, Four USARTs , one low-power UART , two SPIs


Getting started: Install STM32CubeIDE

You can download STM32CubeIDE from their st.com.  It’ s free. Install STM32CubeIDE following STM32CubeIDE installation guide.


Your first project: LED blink

Before we can start writing code we need to create a project. This is similar to most other IDEs – projects are used to bundle together all of your settings, code, and definitions into a single collection all managed from the same application.



STEP 1: Start a new project, From the top left icon ( Or under the menu File > New > STM32 Project) to get started.


Step 2: Project name: G0_LED, then click Finish Button.

From schematic diagram that the LED4 is controlled by STM32G071 and the port is PA5.

Step 3: From System Core > SYS, select Serial Wire, setup PA5 as GPIO_OUTPUT.

Setup use label for PA5 as LED_GREEN as below:


Step 4: Then Generate code.


CubeIDE, which this functionality is developed upon, generates C files to work with under a Src directory, and puts a HAL (Hardware Abstraction Layer) into an Includes directory. It appears CubeIDE works the exact same way. Expand the folders on the right under the project view and see what it has generated to work for you.



Step 5: Let’ s add a smidge of C code of our own now! After the Infinite Loop area, we’re going to add code to toggle the LED under section 3 as below:



Compiling the project and downloading it to the board

STM32CubeIDE actually makes it pretty easy to compile our work and get it onto the STM32 chip.  The first step is to produce the compiled .elf ( a binary version of our code).  To generate the .elf, we need to do a build. This is as easy as pressing the build button on the toolbar.

Now, build information is presented in the console at the bottom of the screen.

Now what we want to do is send this compiled binary onto the STM32 microcontroller.

Let’s plug in the dev kit:

The Red power LED (to the left of the blue switch) is lit, as is the larger communication LED (by the USB cable). Inside STM32CubeIDE, select the run button.

This will open the Run dialog ( as it’s the first time we’ve run it). The settings we choose now will be saved as a run configuration which we can re-use or edit later.

Simply press Apply and then OK and the download will proceed. The Console will now fill with some interesting text:

The LED is on and off every 500ms. you’ve got everything set up.

STM32 vs Arduino

STM32 vs Arduino

Check out our Control Board!



Arduino is more creative, it weakens the operation of specific hardware, its functions and syntax are very simple, and it is very “dumb”.

Most of Arduino’s main control is AVR microcontroller. The advantage of Arduino is that it has high code encapsulation and fewer sentences, which reduces the difficulty of software development.

Arduino is relatively easy to get started, as long as you understand a little hardware and C++, you can develop.

Most of the functions of Arduino have well-built libraries, so it is very simple to use, but the controllability of slightly more complicated functions is poor. 



STM32 pays more attention to engineering practice. In fact, there are many simple instruments in the factory, such as temperature controllers, ordinary motor controllers, low-end PLCs, and some civilian toys, game controllers, wired keyboards and mice, and other peripherals and so on are very practical.

STM32 is mainly used as products for professional developers, which requires certain professional knowledge, but at the same time, it is relatively complicated to write code to realize functions. For example, the serial port outputs a simple string. For Arduino, it may start from a new project and it can be realized with 10 lines of code. However, if you use STM32 development tools such as Keil, it may require hundreds of lines of code or more.

In terms of open source: things made with STM32 can be open source if you want to open source, and you can not publish anything if you don’t want open source.




Here are some suggestions for choosing:

If you are an ordinary student below the university level who does not have a deep understanding of programming languages, it is recommended to get started with Arduino. If the C skills are weak and come up with STM32, you will soon have the idea of giving up.

If you only study for employment, decisively STM32 microcontroller.

If you are learning just for fun and you are not a major in electronics and have no confidence, Arduino is recommended.

If you have good programming skills, STM32 is recommended. After you get it done, you can take a look at the things made by the Arduino open-source community, and you can easily get it done with STM32.

Of course, if you have the ability, you can make contact with both. Generally, you can master the basic features of Arduino in less than a week. If you need it in the future, you can freely transplant the Arduino code to MCU platforms such as STM32.

In fact, the two are actually aimed at slightly different directions. Arduino is the choice of general electronics hobbyists and DIY, while STM32 is often used for the development and manufacturing of actual products.