单片机
返回首页

makefile及其相关知识介绍

2025-02-21 来源:cnblogs

makefile是用来管理工程的。


示例1:


1 exe: a.c b.c

2         gcc a.c b.c -o exe

4 clean:

5         rm exe

基本概念:


目标:顶格写,在:前面


依赖: 在:后面,用来产生目标的原材料


命令:前面一定是table,不能是多个空格。命令是生成目标所做的动作


示例2:


 1 led.bin: start.o 

 2         arm-linux-ld -Ttext 0x0 -o led.elf $^

 3         arm-linux-objcopy -O binary led.elf led.bin

 4         arm-linux-objdump -D led.elf > led_elf.dis 

 5         gcc mkv210_image.c -o mkx210   // 该处生成的mkx210是为了在Linux下执行的,这里的gcc和交叉编译工具链的gcc不相同

 6         ./mkx210 led.bin 210.bin  

 7     

 8 %.o : %.S

 9         arm-linux-gcc -o $@ $< -c

10 

11 %.o : %.c

12         arm-linux-gcc -o $@ $< -c 

13 

14 clean:

15         rm *.o *.elf *.bin *.dis mkx210 -f


示例分析:


(1)Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是: 


$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件


(2)交叉编译工具链工具及作用


先决条件:linux系统下面有一个环境变量叫PATH,必须把该工具链的地址导入到该环境变量下面,export PATH=工具链地址:$PATH


最好是该语句加到~/.bash文件中,这样每次启动终端都会执行该语句。


arm-linux-gcc:


用来编译源文件


arm-linux-ld:


用来链接,其中,-Ttest是用来指定链接地址的,在该处也可以使用链接脚本来去进行链接。在该处生成的elf文件还不能烧录执行。


objcopy:


作用以led.elf为源材料为源材料制作镜像的工具。


解释:led.elf已经是可执行程序,在操作系统下已经可以执行,裸机中需要的是可以烧录的二进制文件(镜像image)。


以led.elf为源材料为源材料制作镜像


objdump:


作用:反汇编,将elf格式的可执行程序反过来得到其汇编源代码。


mkx210(由mkv210_image.c得到):


作用:以led.bin为源材料得到210.bin(为BL1添加校验头)


解释:usb启动时不需要头校验,SD卡启动时需要,让led.bin加上header(校验头)成为210.bin。


附:mkv210_image.c源程序:


  1 /*

  2  * mkv210_image.c的主要作用就是由usb启动时使用的led.bin制作得到由sd卡启动的镜像210.bin

  3  *

  4  * 本文件来自于友善之臂的裸机教程,据友善之臂的文档中讲述,本文件是一个热心网友提供,在此表示感谢。

  5  */

  6 /* 在BL0阶段,Irom内固化的代码读取nandflash或SD卡前16K的内容,

  7  * 并比对前16字节中的校验和是否正确,正确则继续,错误则停止。

  8  */

  9 #include

 10 #include

 11 #include

 12 

 13 #define BUFSIZE                 (16*1024)

 14 #define IMG_SIZE                (16*1024)

 15 #define SPL_HEADER_SIZE         16

 16 //#define SPL_HEADER              'S5PC110 HEADER  '

 17 #define SPL_HEADER              '****************'

 18 

 19 int main (int argc, char *argv[])

 20 {

 21     FILE        *fp;

 22     char        *Buf, *a;

 23     int        BufLen;

 24     int        nbytes, fileLen;

 25     unsigned int    checksum, count;

 26     int        i;

 27     

 28     // 1. 3个参数

 29     if (argc != 3)

 30     {

 31         printf('Usage: %s n', argv[0]);

 32         return -1;

 33     }

 34 

 35     // 2. 分配16K的buffer,并且全部填充为0

 36     BufLen = BUFSIZE;

 37     Buf = (char *)malloc(BufLen);

 38     if (!Buf)

 39     {

 40         printf('Alloc buffer failed!n');

 41         return -1;

 42     }

 43 

 44     memset(Buf, 0x00, BufLen);

 45 

 46     // 3. 读源bin到buffer

 47     // 3.1 打开源bin

 48     fp = fopen(argv[1], 'rb');

 49     if( fp == NULL)

 50     {

 51         printf('source file open errorn');

 52         free(Buf);

 53         return -1;

 54     }

 55     // 3.2 获取源bin长度

 56     fseek(fp, 0L, SEEK_END);                                // 定位到文件尾

 57     fileLen = ftell(fp);                                    // 得到文件长度

 58     fseek(fp, 0L, SEEK_SET);                                // 再次定位到文件头

 59     // 3.3 源bin长度不得超过16K-16byte

 60     count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE))

 61         ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);

 62     // 3.4 buffer[0~15]存放'S5PC110 HEADER  '

 63     memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE);

 64     // 3.5 读源bin到buffer[16]

 65     nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp);

 66     if ( nbytes != count )

 67     {

 68         printf('source file read errorn');

 69         free(Buf);

 70         fclose(fp);

 71         return -1;

 72     }

 73     fclose(fp);

 74 

 75     // 4. 计算校验和

 76      // 4.1 从第16byte开始统计buffer中共有几个1

 77     // 4.1 从第16byte开始计算,把buffer中所有的字节数据加和起来得到的结果

 78     a = Buf + SPL_HEADER_SIZE;

 79     for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)

 80         checksum += (0x000000FF) & *a++;

 81     // 4.2 将校验和保存在buffer[8~15]

 82     a = Buf + 8;                            // Buf是210.bin的起始地址,+8表示向后位移2个字,也就是说写入到第3个字

 83     *( (unsigned int *)a ) = checksum;

 84 

 85     // 5. 拷贝buffer中的内容到目的bin

 86     // 5.1 打开目的bin

 87     fp = fopen(argv[2], 'wb');

 88     if (fp == NULL)

 89     {

 90         printf('destination file open errorn');

 91         free(Buf);

 92         return -1;

 93     }

 94     // 5.2 将16k的buffer拷贝到目的bin中

 95     a = Buf;

 96     nbytes    = fwrite( a, 1, BufLen, fp);

 97     if ( nbytes != BufLen )

 98     {

 99         printf('destination file write errorn');

100         free(Buf);

101         fclose(fp);

102         return -1;

103     }

104 

105     free(Buf);

106     fclose(fp);

107 

108     return 0;

109 }


(3)指令解释


-c: 只编译不链接


-o: 用来指定名字


-D: 表示反汇编(反汇编工具有多种用法,-D表示反汇编用法)


-Ttext: 指定代码段的起始地址(链接地址)


(4)其它


第8行到第12行叫做makefile的规则,当看到.S和.c文件会自动转化为.o文件。


printf移植中用到的makefile


 1 CC         = arm-linux-gcc

 2 LD         = arm-linux-ld

 3 OBJCOPY = arm-linux-objcopy

 4 OBJDUMP = arm-linux-objdump

 5 AR         = arm-linux-ar

 6 

 7 INCDIR := $(shell pwd)

 8 

 9 # c预处理器的flag,flag就是编译器可选的选项

10 CPPFLAGS    := -nostdlib -nostdinc -I$(INCDIR)/include

11 # C编译器的flag

12 CFLAGS        := -Wall -O2 -fno-builtin                

13 

14 # 导出这些变量到全局,其实就是给子文件下面的makefile使用

15 export CC LD OBJCOPY OBJDUMP AR CPPFLAGS CFLAGS

16 

17 

18 objs := start.o led.o clock.o uart.o main.o

19 objs += lib/libc.a

20 

21 uart.bin: $(objs) 

22     $(LD) -Tlink.lds -o uart.elf $^

23     $(OBJCOPY) -O binary uart.elf uart.bin

24     $(OBJDUMP) -D uart.elf > uart_elf.dis

25     gcc mkv210_image.c -o mkx210

26     ./mkx210 uart.bin 210.bin

27     

28 lib/libc.a:

29     cd lib; make; cd ..

30     

31 

32     

33 %.o : %.S

34     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 

35 

36 %.o : %.c

37     $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -c 

38 

39 clean:

40     rm *.o *.elf *.bin *.dis mkx210 -f

41     cd lib; make clean; cd ..


 -nostdlib 不用标准库


-nostdinc 不用标准的头文件


-O2   编译器的优化等级


-Wall  显示所有警告


-I           用来表示寻找头文件的目录(一般用相对路径表示)


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章