Basic Experiment 1: light up 2 LED lights

Catalogue of series articles

Porting Linux 0.0 GPIO operation from 11 to Hi3518EV200 development board


By lighting the LED light through basic experiments, you can be familiar with some basic knowledge of the target hardware platform, such as memory address space range, how to configure multiplexing pins, how to operate GPIO, how to write bare metal Makefile, etc.

1. Execution process of bare metal programs

Bare metal program skymixos The function of bin is simply to light up two LED s, which is loaded and executed by u-boot, just as embedded Linux is loaded and executed by u-boot.

2. Implementation analysis

2.1 hardware schematic diagram

Pin ID # GPIO # remarks


PWM1/GPIO7_3            GPIO7_3. Pull down and turn on the LED

PWM2/GPIO7_4             GPIO7_4. Pull down and turn on the LED


As can be seen from the schematic diagram, to light the LED, you only need to output the corresponding GPIO on Hisilicon to a low level. GPIO operations are generally divided into the following steps:

  • Configure the corresponding multiplexing pin as GPIO function
  • Configure GPIO as output, and then output high and low levels

2.2 code analysis

As can be seen from the above execution flow, the executable program skymixos Bin is loaded and executed after u-boot execution. Therefore, the hardware platform at this time has completed the initialization related to CPU and memory. When executing C code execution, we can simply set the stack pointer register to jump to C code execution. head.S is to use assembly code to complete the simplest initialization, and then jump to C code execution:

head.S implementation code is as follows:

 .extern     main
.global _start
    ldr sp, =0x84000000       /* Set stack at memory address 0x84000000 */
    ldr lr, =halt_loop        /* Set the target for jump return */
    ldr pc, =main             /* Jump to the main label for execution */
    b   halt_loop             /* After returning from the main function, the loop will be executed here */

The main function is in main In C, the code to light LED is also called led_ in main. Test implementation.

#include "platform.h"
#include "osal_io.h"

 * muxctrl_reg59            0x0ec           bit[0]      0: PWM1; 1: GPIO7_3
 * muxctrl_reg60            0x0f0           bit[1:0]    00: PWM2; 01: GPIO7_4;  10: SPI1_CSN1; Others: reserved
#define MUXCTRL_REG59_OFF       0x0EC
#define MUXCTRL_REG60_OFF       0x0F0

static void pinmux_init()
    /* Configure the two GPIO multiplexing pins of the control LED as the GPIO function */

void led_test()

    OSAL_WRITEL(1 << 3 | 1 << 4, GPIO7_REG_BASE + 0x400);
    OSAL_WRITEL(0x00, GPIO7_REG_BASE + 0x3FC);      // Turn on 2 LED s  

int main(void)
    return 0;

The Makefile implementation of this bare metal program is also very simple:


INCLUDEDIR  := $(shell pwd)/include
CFLAGS      := -Wall -O2
CPPFLAGS    := -nostdinc -I$(INCLUDEDIR)


TARGET := skymixos

objs := head.o main.o led.o

${TARGET}.bin: $(objs)
    ${LD} -T${TARGET}.lds -o ${TARGET}_elf $^
    ${OBJCOPY} -O binary -S ${TARGET}_elf $@
    ${OBJDUMP} -D -m arm ${TARGET}_elf > ${TARGET}.dis

    ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

    ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

    rm -f ${TARGET}.bin ${TARGET}_elf ${TARGET}.dis *.o

The link script specified in Makefile is skymixos LDS, and specify the link address of the program and the arrangement of each paragraph in the link script.

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
    . = 0x82000000;
    . = ALIGN(4);
    .text :
        __text_start = .;
        __init_end = .;
        ASSERT(((__init_end - __text_start) < 0x4000), "init sections too big!");
    . = ALIGN(4);
    .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
    . = ALIGN(4);
    .data : { *(.data) }
    . = ALIGN(4);
    .got : { *(.got) }
    __u_boot_cmd_start = .;
    .u_boot_cmd : { *(.u_boot_cmd) }
    __u_boot_cmd_end = .;
    . = ALIGN(4);
    __bss_start = .;
    .bss : { *(.bss) }
    _end = .;

Refer to the implementation of u-boot. The initial link address is 0x82000000. During the test, use tftp to transfer the program skymixos Load bin to 0x82000000 and execute it.

2.3 testing

After the development board is powered on, it enters the interactive mode of u-boot. Download via tftp Bin to memory address 0x82000000

that 's ok.

SPI Nor(cs 0) ID: 0xc2 0x20 0x18

Block:64KB Chip:16MB Name:"MX25L128XX"

SPI Nor total size: 16MB

Cannot found a valid SPI Nand Device


EMMC/MMC/SD controller initialization.

Card did not respond to voltage select!

No EMMC/MMC/SD device found !

In:    serial

Out:   serial

Err:   serial

Hit any key to stop autoboot:  0 

hisilicon # tftp 0x82000000 skymixos.bin

Hisilicon ETH net controler

MAC:   00-00-23-34-45-66

eth0 : phy status change : LINK=DOWN : DUPLEX=FULL : SPEED=100M

eth0 : phy status change : LINK=UP : DUPLEX=FULL : SPEED=100M

TFTP from server; our IP address is

Download Filename 'skymixos.bin'.

Download to address: 0x82000000

Downloading: #################################################


Bytes transferred = 116 (74 hex)

hisilicon # go 0x82000000

## Starting application at 0x82000000 ...


Execute program skymixos After bin, 2 LED s are powered on!!!

3. Appendix

HI3518EV200 SoC internal structure:

GPIO register:



The LED on the back of bare metal Linux 0.0 is simple 11 laid the foundation for transplantation. A thousand mile trip begins with one step.

Keywords: C Operating System architecture kernel

Added by adamski on Wed, 05 Jan 2022 17:46:30 +0200