imx6ull-qemu bare Tutorial 1: GPIO, IOMUX, I2C

Inadvertently found to Wei Dongshan teacher 6ul website, qemu emulator a 6ul above, download with the use, very easy to use, there are UI, a lot more functionality than 6ul development board original qemu-system-arm provided .
The following is posted Wei Dongshan teacher qemu website:
Hundred Questions Network imx6ull-qemu
but the default run linux, no bare metal routines. Therefore, this paper wrote a few bare procedures for reference to learn some peripheral IP on 6ul soc. Purpose is the easiest code to help friends using IP properties of interest 6ul.
This tutorial source
target to achieve the following modules bare metal driver tutorial:

  • GPIO LED
  • GPIO BUTTON
  • I2C AT24CXX EEPROM
  • GPT timer
  • USDHC SD card
  • eLCDIF
  • QuadSPI Flash

Note: this article only applies to drivers using the QEMU emulator, not be able to run up on a real chip. The main reason is with the clock, timing related. Because things are pure software qemu, qemu does not have strict requirements for timing, so all the drivers are not on the clock and timing are processed in this article.

1. 6UL SOC start writing code

1.1 System memory map

First look 6UL SOC memory map of
Here Insert Picture DescriptionHere Insert Picture Description
our concern following paragraphs of memory space:

  • 0x0000_0000 - 0x0001_7FFF BootROM。 6ul真实芯片启动的第一条代码是从BootROM 0地址启动,6ul qemu第一条指令也是从0地址开始启动。但是不同的是,6ul qemu并没有BootROM的启动代码,所以我们编写的裸机程序的代码从0地址开始链接,这段ROM空间我们可以用作text段。在真实的芯片上,BootROM会从不同的启动设备上读出Boot Image,典型的如Uboot,然后把Boot Image扔到DDR或者OCRAM上去跑。
  • 0x0090_0000 - 0x0097_FFFF OCRAM。这段OCRAM我们可以用来存放data段,bss段和stack段。
  • 0x8000_0000 - 0xFFFF_FFFF DDR。这段内存可以用作通用内存,暂时在本文的代码中没用到。

1.2 链接文件

6ul_bare_metal/6ul_bare_metal.ld

ENTRY(reset)
SECTIONS
{
	. = 0x00000000;
 	.startup . : { start.o(.text) }
 	.text : { *(.text) }
    . = 0x00900000;
 	.data : { *(.data) }
 	.bss : { *(.bss COMMON) }
 	. = ALIGN(8);
 	. = . + 0x8000; /* 32kB of stack memory */
 	svc_stack_top = .;
}

正如上一节所述,test位于BootROM上,data,bss和stack段位于OCRAM上。其中:

  • start.o是启动文件及异常向量表, 所以将其链接到最顶端。
  • stack占用32KB大小内存。

1.3 启动汇编代码

6ul_bare_metal/start.S

.align 4
.global reset
.global c_entry
.section .isr_vector
.text
reset:
	B reset_handler
	B .
	B .             //SVC
	B .
	B .
	B .
	B .             //IRQ
	B .             //FIQ


reset_handler:
    ldr r0, =0x00900000
    mcr p15,0,r0,c12,c0,0
    ldr sp, =svc_stack_top
    bl c_entry
    b .

reset处存放了arm向量表,除了reset之外其他都是一个死循环。本文所有代码作了以下简化:

  • 不使用任何中断,所有驱动都查询中断标志位的方式。
  • 所有代码运行在特权模式下。
    每一个demo都实现了一种外设,在运行模式下切换没有什么意义,增加了demo的复杂性,所以对所有裸机demo做了以上简化。

启动代码很简单,0地址就是一条B reset_handler的代码,然后reset handler设了一下特权模式下的栈指针,就跳转c函数的入口c_entry中。以下是start.s编译器编出来的代码。

00000000 <reset>:
   0:	ea000006 	b	20 <reset_handler>
   4:	eafffffe 	b	4 <reset+0x4>
   8:	eafffffe 	b	8 <reset+0x8>
   c:	eafffffe 	b	c <reset+0xc>
  10:	eafffffe 	b	10 <reset+0x10>
  14:	eafffffe 	b	14 <reset+0x14>
  18:	eafffffe 	b	18 <reset+0x18>
  1c:	eafffffe 	b	1c <reset+0x1c>

00000020 <reset_handler>:
  20:	e3a00609 	mov	r0, #9437184	; 0x900000
  24:	ee0c0f10 	mcr	15, 0, r0, cr12, cr0, {0}
  28:	e59fd004 	ldr	sp, [pc, #4]	; 34 <reset_handler+0x14>
  2c:	eb000034 	bl	104 <c_entry>
  30:	eafffffe 	b	30 <reset_handler+0x10>
  34:	00908008 	addseq	r8, r0, r8

使用cgdb debug启动代码如下:
Here Insert Picture Description

Published 21 original articles · won praise 52 · views 80000 +

Guess you like

Origin blog.csdn.net/u011280717/article/details/104069829