0%

Linux驱动学习日记(4) 移植官方SDK库和BSP文件分类方法

移植官方SDK库

  首先新建cc.h文件,存放一些SDK库文件用到的数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef _cc_h
#define _cc_h

#define __I volatile
#define __O volatile
#define __IO volatile

typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char s8;
typedef signed short int s16;
typedef signed int s32;
typedef signed long long int s64;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef unsigned long long int u64;

#endif

  将我们用到的fsl_comon.h、fsl_iomuxc.h、MCIMX6Y2.h复制进文件夹中,可以在vscode中看到产生了许多报错,我们先在三个文件顶部添加cc.h头文件解决掉标识符错误的报错。

#include “cc.h”

  接着,我们将没有复制进来但包含的头文件全部删除,然后将报错的地方一一删除即可。(此举动仅针对本次实验)
  将上一次的main.c文件复制进文件夹,并做以下改动:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "fsl_common.h"
#include "fsl_iomuxc.h"
#include "MCIMX6Y2.h"
void Clk_En()
{
CCM->CCGR1 = 0XFFFFFFFF;
}

void LED_Init()
{
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0X10B0);
GPIO1->GDIR |= (1 << 3);
GPIO1->DR &= ~(1 << 3);

}

void delay_short(volatile unsigned int n)
{
while(n--);
}

void delay(volatile unsigned int ms)
{
while(ms--)
{
delay_short(0x7ff);
}
}

void Led_Set_Pin(int a)
{
if(a == 0) // 拉低
{
GPIO1->DR &= ~(1 << 3);
}
else if(a == 1) // 拉高
{
GPIO1->DR |= (1 << 3);
}
else
return;
}

int main()
{
Clk_En();
LED_Init();
while(1)
{
delay(500);
Led_Set_Pin(1);
delay(500);
Led_Set_Pin(0);
}
return 0;
}

编写Makefile脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
CROSS_COMPILE 	?= arm-linux-gnueabihf-
NAME ?= ledc

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

OBJS := start.o main.o

$(NAME).bin:$(OBJS)
$(LD) -Timx6ul.lds -o $(NAME).elf $^
$(OBJCOPY) -O binary -S $(NAME).elf $@
$(OBJDUMP) -D -m arm $(NAME).elf > $(NAME).dis

%.o:%.s
$(CC) -Wall -nostdlib -c -O2 -o $@ $<

%.o:%.S
$(CC) -Wall -nostdlib -c -O2 -o $@ $<

%.o:%.c
$(CC) -Wall -nostdlib -c -O2 -o $@ $<

clean:
rm -rf *.o $(NAME).bin $(NAME).elf $(NAME).dis

三个赋值号的区别

?= 若外部未指定,则赋值
= 与外部绑定
:= 不绑定,只赋值

编译器后不同关键字的意思

-Wall 打开常用编译警告
-nostdlib 不链接任何标准库
-c 只编译 不链接
-O2 开启中等级别优化
-o <file> 指定输出文件名
-S(objcopy 参数)去除符号表和调试信息

烧写后运行,正常闪烁LED。

BSP工程管理

  我们建立如下图所示的文件夹。

图 1 文件夹
其中,bsp用来存放驱动文件;imx6ul用来存放跟芯片相关的文件,obj用来存放编译生成的.o文件,project存放应用文件(即start.s和main.c文件)。
图 2 文件树

以下是makefile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
CROSS_COMPILE 	?= arm-linux-gnueabihf-
TARGET ?= bsp

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

INCDIRS := 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)

第 1~7 行定义了一些变量,除了第 2 行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第 1 行即可。第 2 行的变量 TARGET 目标名字,不同的例程肯定名字不一样。
第 9 行的变量 INCDIRS 包含整个工程的.h 头文件目录,文件中的所有头文件目录都要添加到变量INCDIRS 中。比如本例程中包含.h 头文件的目录有 imx6ul、 bsp/clk、 bsp/delay 和 bsp/led,所以就需要在变量 INCDIRS 中添加这些目录。
第 14 行是变量 SRCDIRS,和变量 INCDIRS 一样,只是 SRCDIRS 包含的是整个工程的所有.c 和.S 文件目录。比如本例程包含有.c 和.S 的目录有 bsp/clk、 bsp/delay、 bsp/led 和 project。

$(patsubst 原模式, 新模式, 文本)

在文本中,把所有符合原模式的部分,替换成新模式。
第22、23行找出所有的.S、.c文件,25、26行则去掉了路径名、只保留文件名。28-30行将.c、.o文件编译为.o文件并将其放入obj文件夹中。
32行含义是当规则里写 %.c 或 %.S make 会自动去project/ bsp clk/ … 里找

运行

编译并烧录,实验结果正常。