Linux——GPIO输入输出裸机实验

devtools/2024/11/15 14:43:22/

学习了正点原子Linux环境下的GPIO的输入输出的裸机实验学习,现在进行一下小结:

启动文件start.S的编写

.global _start
.global _bss_start
_bss_start:.word __bss_start.global _bss_end
_bss_end:.word __bss_end_start:/*设置处理器进入SVC模式*/mrs r0, cpsr           /*读取cpsr到r0*/bic r0, r0, #0x1f      /*清除cpsr的bit4-0*/orr r0, r0, #0x13      /*使用SVC模式*/msr cpsr, r0           /*将r0写入到cpsr*//*清除bss段*/ldr r0, =_bss_startldr r1, =_bss_endmov r2, #0
bss_loop:stmia r0!, {r2}cmp r0, r1ble bss_loop/*设置sp指针*/ldr sp, =0x80200000b main                 /*跳转到C语言main函数*/

.global指令用于定义全局变量

 .word指令定义了两个符号 _bss_start_bss_end,它们都初始化为对应的符号 __bss_start__bss_end 的地址(在后面讲到的链接脚本文件imx6u.lds中有为这两个符号赋值地址)。这些符号通常用于标识程序中BSS段的开始和结束。

BSS段(Block Started by Symbol)是程序数据段的一部分,用于存储未初始化的全局变量和静态变量。在程序启动时,BSS段会被清零,并且其大小会被计算到程序的总内存占用中,尽管它在磁盘上的表示可能非常小或甚至没有。

程序启动会先从启动文件开始执行,默认从_start处开始执行。

Makefile编写

通过make指令可以执行目录下的Makefile文件,我们可以在Makefile文件里编写编译过程的一系列指令,方便开发。 

Makefile文件以及相应的注释如下:

#变量赋值,?=如果前面已经有赋值,则用前面的,没有就用等号后面的
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET		  ?= beepCC            	:= $(CROSS_COMPILE)gcc
LD            	:= $(CROSS_COMPILE)ld
OBJCOPY       	:= $(CROSS_COMPILE)objcopy
OBJDUMP       	:= $(CROSS_COMPILE)objdump
#保存头文件所在目录的变量
# \ 表示本行和下一行属于同一行。为换行符
INCUDIRS	  	:=  project \imx6u \bsp/clk \bsp/led \bsp/delay \bsp/beep#保存源文件所在目录的变量				
SRCDIRS	  	  	:=  project \bsp/clk \bsp/led \bsp/delay \bsp/beep#将变量INCUDIRS里的值都加上-I前缀
#加-I是以为makefile语法指定头文件目录时候前面要加-I
#patsubst语法:在INCUDIRS中所有的单词前加上-I,因为%为通配符
INCLUDE			:=	$(patsubst %,-I%,$(INCUDIRS))
#foreach作用是将SRCDIRS变量的值赋值给dir然后执行最后的表达式wildcard,
#wildcard的作用是将dir目录下的所有.S文件(前面带着目录)都存入SFILES变量
SFILES			:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES			:=	$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
#notdir作用是删除SFILES变量的目录成分,只留文件名
SFILENDIR		:=  $(notdir $(SFILES))
CFILENDIR		:=  $(notdir $(CFILES))
#将没有目录的SFILENDIR的值都加上obj/前缀,并将.S.c替换成.o
SOBJS			:=	$(patsubst %.S,obj/%.o,$(SFILENDIR))
COBJS           :=  $(patsubst %.c,obj/%.o,$(CFILENDIR))
#保存所有的.o文件
OBJS			:=  $(SOBJS) $(COBJS)
#如果当前目录找不到目标文件和依赖文件,就到指定的路径去找
VPATH			:=  $(SRCDIRS)
#伪目标
.PHONY:clean
# 目标文件 : 依赖文件
#-T后面接链接脚本
#-o 指定输出文件名
#$^表示所有的依赖文件,指令的作用是链接所有的依赖文件成可执行文件.elf
#-O表示指定输出的格式为纯二进制文件
#-S表示剥除符号表和重定义表,无调试信息
#$@表示目标文件
#-D表示输出汇编文件 -m表示指定目标架构arm
#>是shell中的重定向操作符,将输出文件重定向到文件.dis
$(TARGET).bin : $(OBJS)$(LD) -Timx6u.lds -o $(TARGET).elf $^$(OBJCOPY) -O binary -S $(TARGET).elf $@$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis#-Wall表示显示警告信息
#-nostdlib表示在链接时不使用标准库
#-c表示只进行编译和汇编,不进行链接
#$@表示目标文件  $<表示规则中的第一个依赖文件
$(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).bin $(TARGET).dis $(OBJS)
#打印编译过程生成的变量
print:@echo INCLUDE = $(INCLUDE)@echo SFILES  = $(SFILES)@echo CFILES  = $(CFILES)	@echo SFILENDIR  = $(SFILENDIR)@echo CFILENDIR  = $(CFILENDIR)	@echo SOBJS  = $(SOBJS)@echo COBJS  = $(COBJS)	@echo OBJS  = $(OBJS)	

链接脚本imx6u.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=.;
}

链接脚本的主要作用有定义链接起始地址、调整链接顺序(第一个要连接的文件必须是start.o)

.为定位计数器,默认定位计数器为0,给这个特殊符号赋值0x87800000,后面的链接起始地址就会是0x87800000

代码段可以分为text段、只读数据段、数据段和BSS段'

ALIGN(4)的作用是4字节对齐

BSS段(Block Started by Symbol)是程序数据段的一部分,用于存储未初始化的全局变量和静态变量。在程序启动时,BSS段会被清零,并且其大小会被计算到程序的总内存占用中,尽管它在磁盘上的表示可能非常小或甚至没有

GPIO输入输出配置的库函数

配置复用功能函数

IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);

上面示例中的 IOMUXC_GPIO1_IO03_GPIO1_IO03是一个宏定义,如下:

上面的操作是我们通过传递参数,将对应模式的值放到我们的寄存器地址。也就是将0x5写到0x020E0068为地址的寄存器里,查看参考手册

就是向我们这个寄存器写入0x5,将其复用为GPIO1_IO03

 配置电气属性函数

IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0x10B0);

与我们的复用功能函数类似,也是通过传入参数到我们相关的配置寄存器地址中,如下:

为地址为0x020E02F4的配置寄存器写入0x10b0

通过查看参考手册进行对应的电气属性配置

写入0x10B0是配置为输出模式

写入0xF080是配置为输入模式,上拉,使能迟滞比较器

 GPIO寄存器组

 通过结构体指针操作寄存器组,进而配置GPIO为输入还是输出模式,1为输出模式。0为输入模式


http://www.ppmy.cn/devtools/134186.html

相关文章

技术整合与生态构建:Lyft与Mobileye引领自动驾驶新纪元

在科技日新月异的今天&#xff0c;自动驾驶技术正逐渐从科幻电影走进现实生活&#xff0c;成为出行服务领域的一股不可忽视的力量。近日&#xff0c;北美网约车巨头Lyft与自动驾驶技术领先者Mobileye宣布联手合作&#xff0c;共同推动自动驾驶汽车出行服务的广泛商业化进程。此…

数组的定义及打印

引入 上次讲到字符和字符串&#xff0c;二者可以打印到控制台&#xff0c;但是这样就让打印的内容固定了&#xff0c;那尝试改变一下——第一&#xff1a;单个的字符可以通过像int 、float那样定义变量&#xff0c;通过改变变量来改变打印内容&#xff1b;第二多个字符的字符串…

面试:TCP、UDP如何解决丢包问题

文章目录 一、TCP丢包原因、解决办法1.1 TCP为什么会丢包1.2 TCP传输协议如何解决丢包问题1.3 其他丢包情况&#xff08;拓展&#xff09;1.4 补充1.4.1 TCP端口号1.4.2 多个TCP请求的逻辑1.4.3 处理大量TCP连接请求的方法1.4.4 总结 二、UDP丢包2.1 UDP协议2.1.1 UDP简介2.1.2…

爬虫新姿势——使用Chrome Devtools写一个小说爬虫

目前&#xff0c;绝大部分的爬虫教程都是基于Python和Node.js。其实&#xff0c;只要有Chrome浏览器,使用Chrome F12打开的的Devtools就能随时随地轻轻松松写一个爬虫&#xff0c;完全不用装其它语言环境。今天就介绍一下只使用Chrome Devtools来爬取网站www.biqudu.com/31_317…

Wordpress常用配置,包括看板娘跨域等

一个Wordpress的博客已经搭建完成了&#xff0c;那么为了让它看起来更有人间烟火气一点&#xff0c;有一些常用的初始配置&#xff0c;这里整理一下。 修改页脚 页脚这里默认会显示Powered by Wordpress&#xff0c;还有一个原因是这里要加上备案信息。在主题里找到页脚&…

android framework ams/wms常见系统日志(main\system\events\crash,protoLog使用)

重要性 wms和ams的一些系统原生日志能够帮助我们快速定位问题日志分类 在日常framework工作中常见的日志类别如下: -b , --buffer= Request alternate ring buffer, ‘main’, ‘system’, ‘radio’, ‘events’, ‘crash’, ‘default’ or ‘all’. Additionally, ‘kerne…

压缩指令的使用

gzip 和 gunzip 是两个用于压缩和解压缩文件的命令。 下面是这两个命令的一些基本信息和使用技巧&#xff1a; gzip 压缩 基本语法 gzip 文件名功能描述&#xff1a;压缩文件&#xff0c;只能将文件压缩成 .gz 格式的文件。 经验技巧 只能压缩文件&#xff0c;不能压缩目…

docker--工作目录迁移

前言 安装docker&#xff0c;默认的情况容器的默认存储路径会存储系统盘的 /var/lib/docker 目录下&#xff0c;系统盘一般默认 50G&#xff0c;容器输出的所有的日志&#xff0c;文件&#xff0c;镜像&#xff0c;都会存在这个地方&#xff0c;时间久了就会占满系统盘。 一、…