一. 串口格式化函数
串口格式化函数
在 I.MX6U-ALPHA 开发板上也可以使用此方法,将 printf 和 scanf 映射到串口上,这样就可以使用串口调试助手(如 xshell工具)作为开发板的终端,完成与开发板的交互。
二. printf格式化函数的移植
本文是对正点原子提供的 printf格式化函数代码进行移植。
将 stdio 文件夹复制到代码工程的根目录,如下目录:
注意:
本次实验前提是,之前串口收发函数名分别需要设置为 putc(),puts(),与 getc() 名字。
因为待移植的代码 stdio 文件夹中的 printf 或 scanf 函数,会调用到含有以上名字的串口收发函数。
主函数更改如下:
int main(void)
{
int a = 0, b = 0;
int_init(); //中断初始化
imux6ull_clk_init(); //初始化系统时钟
GPT1_delay_init(); //GPT1定时器初始化
uart_init(); //串口初始化
clk_enable(); //使能外设时钟
led_init(); //Led初始化
beep_init(); //蜂鸣器初始化
key_init(); //key按键初始化
key_filter_init();
while(1)
{
printf("请输入两个整数,使用空格隔开:");
scanf("%d %d", &a, &b);
printf("\r\n 数据%d+%d=%d\r\n", a, b, a+b);
}
return 0;
}
更改 Makefile文件,添加 所移植的 stdio 文件。
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= printf
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
LIBPATH := -lgcc -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.4
INCUDIRS := imx6ull \
bsp/clk \
bsp/led \
bsp/delay \
bsp/beep \
bsp/key \
bsp/gpio \
bsp/int \
bsp/exterint \
bsp/epit \
bsp/key_filter \
bsp/uart \
stdio/include
SRCDIRS := project \
bsp/clk \
bsp/led \
bsp/delay \
bsp/beep \
bsp/key \
bsp/gpio \
bsp/int \
bsp/exterint \
bsp/epit \
bsp/key_filter \
bsp/uart \
stdio/lib
INCLUDE := $(patsubst %, -I %, $(INCUDIRS))
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) -Timx6ull.lds -o $(TARGET).elf $^ $(LIBPATH)
$(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 -Wa,-mimplicit-it=thumb -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
clean:
rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).dis $(OBJS)
print:
@echo INCLUDE = $(INCLUDE)
Makefile文件添加如下:
1. 添加头文件路径与 .c 文件路径:stdio/include 与 stdio/lib。
2. 添加编译选项:-nostdlib 。
-nostdlib作用: 不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader等程序,它们不需要启动文件、标准库文件。
C语言程序执行的第一条指令。并不是 main()函数。生成一个C程序的可执行文件时编译器通常会在我们的代码上加上几个被称为启动文件的文件,他们是标准库文件,这些代码设置 C 程序的堆栈等,然后调用 main() 函数。他们依赖于操作系统。
在裸板上无法执行,所以我们自己写一个。我们自己写的 *.s 汇编文件(例如我们写的 start.S)就是一个启动文件,它设置好堆栈后调用 main() 函数。因此,我们不需要系统自带的启动文件。
3. 添加编译选项: -fno-builtin。
这里作用的调用代码中实现的串口收发接口:putc()、puts()与 getc()函数,而不调用C库函数中的这几个函数。
在我们的代码中,有时可能会定义一个函数,函数名字和 C语言运行库里的函数名冲突的情况。-fno-builtin选项用来设置选择自己定义的函数,而不使用C语言库中的函数。
4. 添加编译选项:-Wa,-mimplicit-it=thumb 。
如果不加 这个编译选项,编译会出现以下问题:
/tmp/ccKkHd3g.s: Assembler messages:
/tmp/ccKkHd3g.s:42: 错误: thumb conditional instruction should be in IT block -- `addcs r5,r5,#65536'
make: *** [Makefile:68:obj/muldi3.o] 错误 1
printf 格式化函数移植实验,至此完成。
在自己的世界里能静下心学习。静与定,是专注的前提。