BSP 工程管理实验
我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。
新建名为“5_ledc_bsp”的文件夹,在里面新建 bsp、imx6ul、obj 和 project 这 4 个文件夹。
imx6ul 用来存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件;
obj 用来存放编译生成的.o 文件;
project 存放 start.S 和 main.c 文件,也就是应用文件;
将cc.h、fsl_common.h、fsl_iomuxc.h 和 MCIMX6Y2.h 这四个文件拷贝到文件夹 imx6ul 中;将 start.S 和 main.c 这两个文件拷贝到文件夹 project 中。
我们前面的实验中所有的驱动相关的函数都写到了 main.c 文件中,比如函数 clk_enable、led_init 和 delay,这三个函数可以分为三类:时钟驱动、LED 驱动和延时驱动。因此我们可以在 bsp 文件夹下创建三个子文件夹:clk、delay 和 led,分别用来存放时钟驱动文件、延时驱动文件和 LED 驱动文件,这样main.c 函数就会清爽很多,程序功能模块清晰。
一、代码实现
-
创建 imx6ul.h 文件
新建文件 imx6ul.h,然后保存到文件夹 imx6ul 中,在 imx6ul.h 中输入如下内容:
#ifndef __IMX6UL_H #define __IMX6UL_H #include "cc.h" #include "MCIMX6Y2.h" #include "fsl_common.h" #include "fsl_iomuxc.h" #endif
文件 imx6ul.h 很简单,就是引用了一些头文件,以后我们就可以在其他文件中需要引用
imx6ul.h 就可以了。
-
编写 led 驱动代码
新建 bsp_led.h 和 bsp_led.c 两个文件,将这两个文件存放到 bsp/led 中,
在 bsp_led.h 中输入输入如下内容:
#ifndef __BSP_LED_H #define __BSP_LED_H #include "imx6ul.h" #define LED0 0 /* 函数声明 */ void led_init(void); void led_switch(int led, int status); #endif
在 bsp_led.c 中输入如下内容:
#include "bsp_led.h" /* * @description : 初始化LED对应的GPIO * @param : 无 * @return : 无 */ void led_init(void) { /* 1、初始化IO复用 */ IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0); /* 复用为GPIO1_IO03 */ /* 2、、配置GPIO1_IO03的IO属性 *bit 16:0 HYS关闭 *bit [15:14]: 00 默认下拉 *bit [13]: 0 kepper功能 *bit [12]: 1 pull/keeper使能 *bit [11]: 0 关闭开路输出 *bit [7:6]: 10 速度100Mhz *bit [5:3]: 110 R0/6驱动能力 *bit [0]: 0 低转换率 */ IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0); /* 3、初始化GPIO,GPIO1_IO03设置为输出*/ GPIO1->GDIR |= (1 << 3); /* 4、设置GPIO1_IO03输出低电平,打开LED0*/ GPIO1->DR &= ~(1 << 3); } /* * @description : LED控制函数,控制LED打开还是关闭 * @param - led : 要控制的LED灯编号 * @param - status : 0,关闭LED0,1 打开LED0 * @return : 无 */ void led_switch(int led, int status) { switch(led) { case LED0: if(status == ON) GPIO1->DR &= ~(1<<3); /* 打开LED0 */ else if(status == OFF) GPIO1->DR |= (1<<3); /* 关闭LED0 */ break; } }
-
编写时钟驱动代码
新建 bsp_clk.h 和 bsp_clk.c 两个文件,将这两个文件存放到 bsp/clk 中,
在 bsp_clk.h 中输入输入如下内容:
#ifndef __BSP_CLK_H #define __BSP_CLK_H #include "imx6ul.h" /* 函数声明 */ void clk_enable(void); #endif
在 bsp_clk.c 中输入输入如下内容:
#include "bsp_clk.h" /* * @description : 使能I.MX6U所有外设时钟 * @param : 无 * @return : 无 */ void clk_enable(void) { CCM->CCGR0 = 0XFFFFFFFF; CCM->CCGR1 = 0XFFFFFFFF; CCM->CCGR2 = 0XFFFFFFFF; CCM->CCGR3 = 0XFFFFFFFF; CCM->CCGR4 = 0XFFFFFFFF; CCM->CCGR5 = 0XFFFFFFFF; CCM->CCGR6 = 0XFFFFFFFF; }
-
编写延时驱动代码
新建 bsp_delay.h 和 bsp_delay.c 两个文件,将这两个文件存放到 bsp/delay 中,
在 bsp_delay.h中输入输入如下内容:
#ifndef __BSP_DELAY_H #define __BSP_DELAY_H #include "imx6ul.h" /* 函数声明 */ void delay(volatile unsigned int n); #endif
在 bsp_delay.c中输入输入如下内容:
#include "bsp_delay.h" /* * @description : 短时间延时函数 * @param - n : 要延时循环次数(空操作循环次数,模式延时) * @return : 无 */ void delay_short(volatile unsigned int n) { while(n--){} } /* * @description : 延时函数,在396Mhz的主频下 * 延时时间大约为1ms * @param - n : 要延时的ms数 * @return : 无 */ void delay(volatile unsigned int n) { while(n--) { delay_short(0x7ff); } }
-
编写main.c代码
#include "bsp_clk.h" #include "bsp_delay.h" #include "bsp_led.h" /* * @description : mian函数 * @param : 无 * @return : 无 */ int main(void) { clk_enable(); /* 使能所有的时钟 `` */ led_init(); /* 初始化led */ while(1) { /* 打开LED0 */ led_switch(LED0,ON); delay(500); /* 关闭LED0 */ led_switch(LED0,OFF); delay(500); } return 0; }
二、编译下载
-
编写Makefile和链接脚本
在工程根目录下新建 Makefile 和 imx6ul.lds 这两个文件
Makefile代码如下:
CROSS_COMPILE ?= arm-linux-gnueabihf-TARGET ?= bspCC := $(CROSS_COMPILE)gccLD := $(CROSS_COMPILE)ldOBJCOPY := $(CROSS_COMPILE)objcopyOBJDUMP := $(CROSS_COMPILE)objdumpINCDIRS := imx6ul \ bsp/clk \ bsp/led \ bsp/delay SRCDIRS := project \ bsp/clk \ bsp/led \ bsp/delay INCLUDE := $(patsubst %, -I %, $(INCDIRS))SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))SFILENDIR := $(notdir $(SFILES))CFILENDIR := $(notdir $(CFILES))SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))OBJS := $(SOBJS) $(COBJS)VPATH := $(SRCDIRS).PHONY: clean $(TARGET).bin : $(OBJS) $(LD) -Timx6ul.lds -o $(TARGET).elf $^ $(OBJCOPY) -O binary -S $(TARGET).elf $@ $(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis$(SOBJS) : obj/%.o : %.S $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<$(COBJS) : obj/%.o : %.c $(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $< clean: rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
imx6ul.lds写入如下内容:
SECTIONS{ . = 0X87800000; .text : { obj/start.o *(.text) } .rodata ALIGN(4) : {*(.rodata*)} .data ALIGN(4) : { *(.data) } __bss_start = .; .bss ALIGN(4) : { *(.bss) *(COMMON) } __bss_end = .;}
-
dsfg
将imxdownload软件复制到工程文件夹下,给予权限,
chmod 777 imxdownload
/imxdownload ledc.bin /dev/sdb
//下载到 SD 卡中, 不能烧写到/dev/sda 或 sda1 设备里面!将SD卡插到开发板上,开发板上的DS0会每个500ms闪烁一次。
-