Catalogue of series articles
Porting Linux 0.0 GPIO operation from 11 to Hi3518EV200 development board
preface
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 .text .global _start _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 */ halt_loop: 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 */ OSAL_WRITEL(0x1, IO_CONFIG_REG_BASE + MUXCTRL_REG59_OFF); OSAL_WRITEL(0x1, IO_CONFIG_REG_BASE + MUXCTRL_REG60_OFF); } void led_test() { pinmux_init(); 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) { led_test(); return 0; }
The Makefile implementation of this bare metal program is also very simple:
CROSS_COMPLIE_PREFIX=arm-himix200-linux- CC = ${CROSS_COMPLIE_PREFIX}gcc LD = ${CROSS_COMPLIE_PREFIX}ld AR = ${CROSS_COMPLIE_PREFIX}ar OBJCOPY = ${CROSS_COMPLIE_PREFIX}objcopy OBJDUMP = ${CROSS_COMPLIE_PREFIX}objdump INCLUDEDIR := $(shell pwd)/include CFLAGS := -Wall -O2 CPPFLAGS := -nostdinc -I$(INCLUDEDIR) export CC LD AR OBJCOPY OBJDUMP INCLUDEDIR CFLAGS CPPFLAGS 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 %.o:%.c ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $< %.o:%.S ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $< clean: 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") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x82000000; . = ALIGN(4); .text : { __text_start = .; head.o __init_end = .; ASSERT(((__init_end - __text_start) < 0x4000), "init sections too big!"); *(.text) } . = 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 skymixos.com 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 MMC: 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 192.168.1.103; our IP address is 192.168.1.100 Download Filename 'skymixos.bin'. Download to address: 0x82000000 Downloading: ################################################# done Bytes transferred = 116 (74 hex) hisilicon # go 0x82000000 ## Starting application at 0x82000000 ...
1
Execute program skymixos After bin, 2 LED s are powered on!!!
3. Appendix
HI3518EV200 SoC internal structure:
GPIO register:
summary
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.