IMX6LL| C环境和SDK配置

62 阅读2分钟

一.使用c语言和sdk

引入sdk头文件

目的:解决寄存器地址难查难设置

  • devices/MCIMX6Y2/MCIMX6Y2.h

    记录外设寄存器及其相关操作

  • devices/MCIMX6Y2/drivers/fsl_iomuxc.h

    记录引脚复用及其相关操作

注意

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

使用C语言

目的:提高开发效率

bin文件组成介绍

段是程序的基本组成元素:

  • .text段:代码文本
  • .rodata段:只读变量,如const修饰的变量
  • .data段:非零的全局变量、静态变量
  • .bss:值为 0 的全局变量、静态变量
  • .comment:存放注释
  • ...

准备C语言环境

  • bss段清零
  • 栈指针(sp)

裸机程序控制外设

特点:读数据手册、设寄存器值

  • 找出外设有哪些相关寄存器
  • 找出外设相关寄存器如何设置

链接脚本引入

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

官方资料:ftp.gnu.org/old-gnu/Man…

SECTIONS{

   . =xxx //链接起始地址
   .段名
   {
       xxx
       *(.段名)
   }
   ...
}
SECTIONS{
    . =0x80000000;
    .text ALIGN(4):
    {
        build/stars.o
        *(.text)
    }

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

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

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

Makefile修改

  • 兼容.s汇编文件
  • 添加编译程序命令
  • 添加sd卡烧录命令
ARCH ?= x86
ifeq ($(ARCH),x86)
   CC=gcc
else
   #CC=arm-linux-gnueabihf-gcc
   #编译生产.o文件
   CC=arm-none-eabi-gcc  
   #链接生产elf文件
   LD=arm-none-eabi-ld
   #去掉冗余的段和elf头,得到纯净的bin文件
   OBJCOPY=arm-none-eabi-objcopy
endif



#TARGET 目标生成文件名
TARGET=led
#生成目录
BUILD_DIR=build
#存放.c的目录
SRC_DIR=sources
#存放头文件文件夹
INC_DIR=include

#指定头文件目录,和模式
CFLAGS=$(patsubst %,-I%,$(INC_DIG))
#获得所有的.h文件,包含路径
INCLUDES=$(foreach dir,$(INC_DIG),$(wildcard $(dir)/*.h))
#存放所有的.c和.s文件,包含路径
SOURCES_c=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
SOURCES_s=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.s))
#存放所有的.o文件
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCES_c)))
OBJS+=$(patsubst %.s,$(BUILD_DIR)/%.o,$(notdir $(SOURCES_s)))
#定义额外的搜索路径
VPATH=$(SRC_DIR)

#生成纯净的文件
$(BUILD_DIR)/$(TARGET).bin:$(OBJS)
   #重定位文件链接起来,得到可执行文件(elf文件)
   $(LD) -Tscript.lds $^ -o $(BUILD_DIR)/$(TARGET).elf 
   $(OBJCOPY) -O binary $(BUILD_DIR)/$(TARGET).elf $@

#.c文件编译为.o文件
$(BUILD_DIR)/%.o:%.c $(INCLUDES)| create_build
   $(CC) -c $< -o $@ $(CFLAGS)
#.s文件编译为.o文件
$(BUILD_DIR)/%.o:%.s $(INCLUDES)| create_build
   $(CC) -c $< -o $@ $(CFLAGS)


.PHONY:clear earth create_build burn

clear:
   rm -rf $(BUILD_DIR)

earth:
   . /etc/profile

create_build:
   mkdir -p $(BUILD_DIR)

burn:
   cp $(BUILD_DIR)/$(TARGET).bin /home/hq/SDK/download_tool
   cd /home/hq/SDK/download_tool && ./mkimage.sh $(TARGET).bin

star.s

.global _start

_start:

@设置栈地址为64M,OX80000000-0XA0000000(512M)

ldr sp,=0x84000000 

@跳转main函数
b main

main.c

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

/*简单延时函数*/
void delay(uint32_t count)
{
    volatile uint32_t i = 0; //volatile 防止被优化
    for (i = 0; i < count; ++i)
    {
        __asm("NOP"); //__asm内嵌汇编代码,NSP空指令
    }
}

int main(int argc, char const *argv[])
{

    //1.使能CCGR1时钟
    CCM->CCGR1 = 0xffffffff; //CCM里面有多种时钟寄存器

    //2.设置引脚复用功能
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO04_GPIO1_IO04, 0);

    //3.设置引脚属性
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO04_GPIO1_IO04, 0x10bd);

    GPIO1->GDIR |= (1 << 4);
    //4.逻辑事件
    GPIO1->DR |= (1 << 4); //GPIO1有各种GPIO1的寄存器,DR是GPIO数据寄存器,将第四个引脚变为1,输出高电平



    while (1)
    {
        GPIO1->DR &= ~(1 << 4);
        delay(0xFFFFF);
        GPIO1->DR |= (1 << 4);
        delay(0xFFFFF);
    }

    return 0;
}