linux进阶-I.MX 6ULL

目录

启动模式(8引脚设置启动模式)

对应原理图

boot ROM程序

空偏移

映像向量表(Image vector table,IVT)

IVT结构体

Boot data

DCD(外设寄存器配置信息,初始化关键外设)

NXP官方I.MX 6ULL开发SDK


启动模式(8引脚设置启动模式)

三大模式:

熔丝:烧录一次,发布产品。

外部:USB、串口等。

内部:SD卡、EMMC、NAND。

设置方法BOOT_MODE0、BOOT_MODE1

内部介质设置方法BT_CFG1[4:7]

接口编号设置方法BT_CFG2[3]

介质属性设置方法:如SD、EMMC,位宽(BT_CFG2[5]

对应原理图

boot ROM程序

选择内部启动方式,启动boot ROM程序

        初始化时钟、外部DDR3

        从外部存储介质加载代码

镜像空偏移,由芯片厂商设定

Image vector table(IVT),关键数据位置。

Boot data,启动数据。镜像加载地址、大小。

Device configuration data(DCD),关键外设的寄存器配置信息(时钟、DDR3相关)。

bin文件,真正程序文件

空偏移

镜像不是从存储介质头部开始存储的,不同介质分别对应一段偏移地址。

映像向量表(Image vector table,IVT)

映像向量表是ROM从提供程序映像的引导设备中读取的数据结构,该程序映像包含成功启动所需的数据组件。

IVT包含程序映像入口点、指向设备配置数据(DCD)的指针和ROM在引导过程中使用的其他指针。

IVT结构体

Boot data

Boot data记录“镜像”在内存中的加载地址和大小。

DCD(外设寄存器配置信息,初始化关键外设)

复位后,芯片使用系统中所有外设的默认寄存器值。但是,这些默认值对于实现最佳系统性能来说并不理想,深圳有些外设在使用之前必须进行配置。DCD是包含在程序镜像中的配置信息,ROM对其解释以配置芯片上的各种外设。

例如,EIM默认配置允许核心在复位后立即连接到NOR闪存设备。这允许芯片与任何NOR闪存设备接口,但缺点是性能慢。此外,一些组件(如DDR)在准备使用之前需要一些寄存器编程作为配置的一部分。DCD可用于将EIM寄存器和MMDC寄存器编程到最佳配置。

ROM根据IVT的信息可确定DCD的位置。

NXP官方I.MX 6ULL开发SDK

NXP官网 I.MX 6ULL SDK

下载SDK2.2_iMX6ULL_LINUX。下载完成后名字为:SDK_2.2_MCIM6ULL_RFP_Linux.run

虚拟机通过共享文件夹得到。并运行。

./SDK_2.2_MCIM6ULL_RFP_Linux.run

运行完成,会在\opt\生成SDK_2.2_MCIM6ULL文件夹。

在\opt\SDK_2.2_MCIM6ULL\tools\imgutil\readme.txt附有说明文档。

1、复制.bin文件到imgutil\evkmcimx6ull文件下,并重命名为sdk20-app.bin。

2、在imgutil\evkmcimx6ull文件下,终端中运行mkimage.sh命令,获取可启动的镜像文件sdk20-app.imag。

        如果镜像是用RAM链接文件构成的,使用“mkimage.sh ram”命令制作可启动镜像。

        如果镜像是用Flash链接文件构成的,使用“mkimage.sh flash”命令制作可启动的XIP镜像。

        如果镜像是用RAM链接文件构成的,并希望从MicroSD卡启动,使用“mkimage.sh sd”命令制作可启动镜像。

根据mkimage.sh和dcd.config文件,dcdgen.bin生成DCD表,imgutil.bin生成img可烧录镜像。

VSCode

VSCode官网

下载deb_x64文件,存于虚拟机linux中。

安装:sudo dpkg -i xxx.deb

启动:code

使用特点:

无需新建项目,直接打开文件夹。

不同目录下的文件夹,可保存在工作区。

默认预览模式。不需要可在Setting中输入“preview”,取消勾选:Workbench > Editor:Enable Preview

推荐插件:

c/c++:函数跳转、自动补全。

Chinese:中文。

material theme:UI。

CodeSpell Checker:拼写检查。

rainbow-highlighter:变量彩虹高光。

        shift+alt+z:变量彩虹高光。

        shift+alt+a:取消变量彩虹高光。

ARM:汇编插件。

高效工作:

移动光标到行首:home

移动光标到行尾:end

跳转文档头部:ctrl+home

跳转文档尾部:ctrl+end

花括号跳转:ctrl+shift+\

文件跳转:ctrl+p

行跳转:ctrl+g

批量修改:F2

GPIO

数量:五组GPIO(GPIO1~GPIO5),每组最多32个,共124个。

GPIO1_IO0~GPIO1_IO31

GPIO2_IO0~GPIO2_IO21

GPIO3_IO0~GPIO3_IO28

GPIO4_IO0~GPIO4_IO28

GPIO5_IO0~GPIO5_IO11

clock controller module(CCM模块)用于配置芯片的各种外设时钟。跟GPIO相关的时钟主要有CCM_CCGR(0~3)寄存器。

//经典汇编led.s
.global _start

_start:

@使能GPIO时钟
ldr r0,=0x20c406c    @将0x20c406c加载到寄存器r0
ldr r1,=0xffffffff   @将0xffffffff加载到寄存器r1
str r1,[r0]          @将寄存器r1的值存储到r0寄存器指向的地址

@设置引脚复用为GPIO
ldr r0,=0x20e006c    
ldr r1,=5   
str r1,[r0]         

@设置引脚属性(上下拉、速率、驱动能力)
ldr r0,=0x20e02f8 
ldr r1,=0x10b0  
str r1,[r0]   

@控制GPIO引脚输出高低电平
ldr r0,=0x209c004
ldr r1,=16
str r1,[r0] 

ldr r0,=0x209c000
ldr r1,=0
str r1,[r0] 

1、下载裸机的gcc编译器:sudo apt-get install gcc-arm-none-eabi

2、编译汇编文件为可重定位文件led.o:arm-none-eabi-gcc -c led.s -o led.o

3、把重定位文件链接起来,得到可执行程序(elf文件):arm-none-eabi-ld -Ttext 0x80000000 led.o -o led.elf

4、把elf文件去掉冗余的段和elf头,得到纯净的bin文件:arm-none-eabi-objcopy -O binary led.elf led.bin

5、给bin文件添加6ull特殊的头部信息(IVT + boot data + DCD),并烧录到sd卡:./mkimage.sh xxx.bin

使用官方SDK

引入SDK头文件目的:解决寄存器地址难查、难设置。

        devices/MCIMX6Y2/MCIMX6Y2.h:记录外设寄存器及其相关操作。

        devices/MCIMX6Y2/drivers/fsl_iomuxc.h:记录引脚复用及其相关操作。

devices/MCIMX6Y2/MCIMX6Y2.h:

        注释:

#include "core_ca7.h"

#include "system_MCIMX6Y2.h"

        添加:

#define __O volatile

#define __IO volatile

#define __I volatile const

 

#define uint32_t unsigned int

#define uint16_t unsigned short

#define uint8_t unsigned char

bin文件组成(段是程序的基本组成元素):

.text段:代码文本

.rodata段:只读变量,如const修饰的变量

.data段:非零的全局变量、静态变量。

.bss段:值为0的全局变量、静态变量。

.comment段:存放注释。

链接脚本引入

目的:指定链接地址、起始代码在text段的位置,其他段的位置。

SECTIONS{

        . = xxx        //链接起始地址

        .段名

        {

                xxx

                *(.段名)

        }

        ...

}

led.s

.global _start

_start:

@设置栈地址为64M,0x80000000~0xA0000000,512MB
ldr sp,=0x84000000

@跳转main函数
b main

led.c

#include "../include/MCIMX6Y2.h"
#include "../include/fsl_iomuxc.h"

/* 简单延时函数 */
void delay(uint32_t count)
{
        volatile uint32_t i=0;

        for(i=0; i<count; i++)
        {
                __asm("NOP");   /* 调用nop空指令 */
        }
}

int main()
{
        /* 使能GPIO1时钟 */
        CCM->CCGR1 = 0Xffffffff;

        /* 设置 红灯引脚的复用以及属性 */
        IOMUXC_SetPinMux(IOMUXC_GPIO1_IO04, 0);
        IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO04, 0x10b0);

        /* 设置 GPIO1_04为输出模式 */
        GPIO1->GDIR |= (1<<4);

        /* 设置 GPIO1_04输出电平为高电平 */
        GPIO1->DR |= (1<<4);

        while(1)
        {
                GPIO1->DR &= ~(1<<4);   //红灯亮
                delay(0xfffff);
                GPIO1->DR |= 1<<4;      //红灯灭
                delay(0xfffff);
        }

        return 0;
}

script.lds

SECTIONS{
        .=0x80000000;

        .text ALIGN(4):
        {
                build/start.o
                *(.text)
        }

        .rodata ALIGN(4):
        {
                *(.rodata)
        }

        .data ALIGN(4):
        {
                *(.data)
        }

        __bss_start=.;
        .bss ALIGN(4):
        {
                *(.bss)
                *(COMMON)
        }
        __bss_end=.;
}

Makefile

ifeq ($(ARCH),x86)
        CC=gcc
else
        CC=arm-none-eabi-gcc
        LD=arm-none-eabi-ld
        OBJCOPY=arm-none-eabi-objcopy
endif

TARGET=led
BUILD_DIR=build
SRC_DIR=sources
INC_DIR=include
CFLAGS=$(patsubst %,-I %,$(INC_DIR))
INCLUDES=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h))

SOURCE_c=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
SOURCE_s=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.s))
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCE_c)))
OBJS+=$(patsubst %.s,$(BUILD_DIR)/%.o,$(notdir $(SOURCE_s)))
VPATH=$(SRC_DIR)

$(BUILD_DIR)/$(TARGET).bin:$(OBJS)
        $(LD) -Tscript.lds -o $(BUILD_DIR)/$(TARGET).elf $^
        $(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $@
$(BUILD_DIR)/%.o:%.c $(INCLUDE) | create_build
        $(CC) -c $< -o $@ $(CFLAGS)
$(BUILD_DIR)/%.o:%.s $(INCLUDE) | create_build
        $(CC) -c $< -o $@ $(CFLAGS)

.PHONY:clean create_build burn
clean:
        rm -r $(BUILD_DIR)
create_build:
        mkdir -p $(BUILD_DIR)
burn:
        cp $(BUILD_DIR)/$(TARGET).bin /home/couvrir/make_testfile1
        cd /home/couvrir/make_testfile1 && ./mkimage.sh $(TARGET).bin

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值