【嵌入式Linux】16-裸机-BSP工程管理

此笔记由个人整理

塞上苍鹰_fly

课程来自:正点原子_手把手教你学Linux

一、BSP工程管理原理

  • 工程管理的目的是为了模块化管理代码,同一个属性的文件存放在同一个目录里面
  • 新建所需的文件夹
    • bsp–外设驱动
    • imx6ul–芯片库
    • obj–编译连接产生的文件
    • project–主函数和启动汇编文件
image-20201209103832712
  • imx6ul内部文件

  • project内部文件

【嵌入式Linux】16-裸机-BSP工程管理_第1张图片

  • bsp内部文件
    • clk–时钟驱动程序
    • delay–延时驱动程序
    • led–led灯驱动程序

【嵌入式Linux】16-裸机-BSP工程管理_第2张图片

  • 创建bsp_clk.h文件
#ifndef __BSP_CLK_H
#define __BSP_CLK_H

#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
#include "cc.h"

/*初始化时钟*/
void clk_enable(void);

#endif // !__BSP_CLK_H
  • 创建bsp_clk.c文件
#include "bsp_clk.h"

/*使能外设时钟*/
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文件
#ifndef __BSP_DELAY_H
#define __BSP_DELAY_H

#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
#include "cc.h"

/*短延时*/
void delay_short(volatile unsigned int n);
/*长延时*/
void delay(volatile unsigned int n);

#endif // !__BSP_DELAY_H
  • 创建bsp_delay.c文件
#include "bsp_delay.h"

/*短延时*/
void delay_short(volatile unsigned int n)
{
    while(n--){}
}

/*长延时(大概一毫秒)*/
/*n:延时毫秒数*/
void delay(volatile unsigned int n)
{
    while(n--){
        delay_short(0x7ff);
    }
}
  • 创建bsp_led.h文件
#ifndef __BSP_LED_H
#define __BSP_LED_H

#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
#include "cc.h"

#define LED0	0

/*初始化led*/
void led_init(void);
/*打开led*/
void led_on(void);
/*关闭led*/
void led_off(void);
/*控制led灯*/
void led_switch(int led, int status);

#endif // !__BSP_LED_H
  • 创建bsp_led.c文件
#include "bsp_led.h"

/*初始化led*/
void led_init(void)
{
    /*设置复用*/
    IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
    
    /*设置电气属性*/
    IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10B0);

    GPIO1->GDIR = 0x0000008;               /*设置为输出*/
    GPIO1->DR = 0x0;                       /*打开led*/
}

/*打开led*/
void led_on(void)
{
    GPIO1->DR &= ~(1<<3);    /*bit3清零*/
}

/*关闭led*/
void led_off(void)
{
    GPIO1->DR |= (1<<3);     /*bit3置一*/
}

/* LED控制函数,控制LED打开还是关闭*/
void led_switch(int led, int status)
{	
	switch(led)
	{
		case LED0:
			if(status == ON)			/*在cc.h中宏定义ON为1*/
				GPIO1->DR &= ~(1<<3);	/* 打开LED0 */
			else if(status == OFF)		/*在cc.h中宏定义OFF为0*/
				GPIO1->DR |= (1<<3);	/* 关闭LED0 */
			break;
	}
}
  • bsp驱动文件夹编写完成
【嵌入式Linux】16-裸机-BSP工程管理_第3张图片
  • 创建main.h
#ifndef __MAIN_H
#define __MAIN_H

#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"
#include "fsl_common.h"
#include "cc.h"

#endif // !__MAIN_H

  • 修改main.c函数
#include "bsp_clk.h"
#include "bsp_led.h"
#include "bsp_delay.h"
#include "main.h"
/*主函数*/
int main(void)
{
    /*使能外设时钟*/
    clk_enable();
    /*初始化led*/
    led_init();
    /*设置led闪烁*/
    while(1)
    {
        led_on();
        delay(500);

        led_off();
        delay(500);
    }
    return 0;
}

二、Makefile编写

  • 用到的函数
    • patsubst:模式字符串替换函数
      • $(patsubst < pattern>,< replacement>,< text>)
        • 查找< text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式< pattern>,如果匹配的话,则以< replacement>替换。
        • < pattern>可以包括通配符“%”, 表示任意长度的字串。 如果< replacement>中也包含“%”, 那么, < replacement>中的这个“%”将是< pattern>中的那个“%”所代表的字串。(可以用“\”来转义, 以“%”来表示真实含义的“%”字符)
    • foreach:用来做循环
      • $(foreach < var>,< list>,< text>)
        • 把参数< list>中的单词逐一取出放到参数所指定的变量中,然后再执行< text>所包含的表达式。
    • dir:取目录函数
      • 从文件名序列< names>中取出目录部分。目录部分是指最后一个反斜杠(“/”)之前的部分。如果没有反斜杠,那么返回“./”。
    • notdir:取文件函数
      • 从文件名序列< names>中取出非目录部分。非目录部分是指最后一个反斜杠(“ /”)之后的部分。
  • wildcard—通配符
    • 在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”
  • VPATH–文件搜索
    • 如果没有指明这个变量,make 只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当前目录找不到的情况下,到所指定的目录中去找寻文件了。
  • 编写Makefile
CROSS_COMPILE 	?= arm-linux-gnueabihf-
TARGET		  	?= bsp

CC			  	:= $(CROSS_COMPILE)gcc
LD			  	:= $(CROSS_COMPILE)ld
OBJCOPY			:= $(CROSS_COMPILE)objcopy
OBJDUMP			:= $(CROSS_COMPILE)objdump

INCUDIRS		:=  imx6ul \
					bsp/clk \
					bsp/led \
					bsp/delay

SRCDIRS			:=  project \
					bsp/clk \
					bsp/led \
					bsp/delay

INCLUDE			:=	$(patsubst %, -I %, $(INCUDIRS))

SFLES			:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.s))
CFLES			:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

SFLENDIR		:=	$(notdir	$(SFLES))
CFLENDIR		:=	$(notdir	$(CFLES))

SOBJS			:=	$(patsubst %, obj/%, $(SFLENDIR:.s=.o))
COBJS			:=	$(patsubst %, obj/%, $(CFLENDIR:.c=.o))

OBJS			:=	$(SOBJS) $(COBJS)

VPATH			:=	$(SRCDIRS)

.PHONY: clean

$(TARGET).bin : $(OBJS)
	$(LD) -Timx6u.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).bin $(TARGET).dis $(TARGET).elf $(OBJS)

print:
	@echo	INCLUDE = $(INCLUDE)
	@echo	SFLES	= $(SFLES)
	@echo 	CFLES	= $(CFLES)
	@echo	SFLENDIR= $(SFLENDIR)
	@echo	CFLENDIR= $(CFLENDIR)
	@echo	SOBJS= $(SOBJS)
	@echo	COBJS= $(COBJS)
  • 修改.lds链接文件

    • 在start.s的前面添加obj/,明确具体位置
  • 编译链接

【嵌入式Linux】16-裸机-BSP工程管理_第4张图片
  • 插入SD卡进行下载

【嵌入式Linux】16-裸机-BSP工程管理_第5张图片

  • 将SD卡插入开发板中,led进行闪烁

  • 最终文件夹

【嵌入式Linux】16-裸机-BSP工程管理_第6张图片

你可能感兴趣的:(嵌入式Linux,嵌入式,makefile,linux)