我试图找到与avr中的#include头文件相关的.c文件。我想看一下avr-gcc库中定义的一些标准库,特别是〈avr/io. h〉中包含的PORT定义。我在/usr/lib/avr/include/avr中搜索了该库并找到了头文件,但我正在寻找的是.c文件。此文件是否存在?如果存在,在哪里可以找到它?如果不存在,头文件引用的是什么?非常感谢,夏兰
pengsaosao1#
编译器提供的库是存储在静态库中的预编译目标代码。在gcc中,库的扩展名通常是.a(由于历史原因,代表“archive”),前缀是“lib”。在构建时,链接器将搜索库档案,以找到解析引用库符号所需的目标代码模块。它提取所需的模块,并将它们链接到正在构建的二进制映像。在gcc中,库libXXX. a通常使用命令行开关-lXXX链接-因此libXXX. a命名约定在这种情况下很重要,例如标准C库libc. a看起来是通过开关-lc链接的。所以回答你的问题,编译器提供的库通常没有.c文件,这个库甚至不需要用C语言编写。也就是说,由于是开源的,源文件(.c或其他格式)可以从各种库的存储库中获得。例如,对于标准C库:https://www.nongnu.org/avr-libc/ .对于其他AVR架构和I/O支持库,您可以检查相关的头文件或文档。头文件通常会有一个样板注解,例如项目URL。
-lXXX
-lc
qoefvg9y2#
PORTB和其他特殊功能寄存器通常被定义为avr-libc提供的头文件中的宏。找到您的include/avr目录(包含io.h的目录)。在该目录中,应该有许多其他头文件。例如,iom328p.h包含以下行,该行定义了ATmega 328 P上的PORTB:
include/avr
io.h
iom328p.h
PORTB
#define PORTB _SFR_IO8(0x05)
如果您还在查找作为.a文件分发的库,则应该运行avr-gcc -print-search-dirs。
.a
avr-gcc -print-search-dirs
nc1teljy3#
有几种方法可以找出系统标头的位置以及包含哪些标头:
使用选项-v,GCC将打印(以及其他东西)它正在使用的路径。检查shell /控制台上的输出,GCC将打印搜索路径:
-v
#include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/avr/5.4.0/include /usr/lib/gcc/avr/5.4.0/include-fixed /usr/lib/gcc/avr/5.4.0/../../../avr/include
最后一个位置是AVR-LibC,它提供avr/io.h。解析..,该路径就是/usr/lib/avr/include。
avr/io.h
..
/usr/lib/avr/include
avr-gcc -H -mmcu=atmega8 foo.c ...
假设C文件foo.c的内容为:
foo.c
#include <avr/io.h> int main (void) { PORTD = 0; }
对于-H,GCC会打印出它实际包含的文件:
-H
. /usr/lib/avr/include/avr/io.h .. /usr/lib/avr/include/avr/sfr_defs.h ... /usr/lib/avr/include/inttypes.h .... /usr/lib/gcc/avr/5.4.0/include/stdint.h ..... /usr/lib/avr/include/stdint.h .. /usr/lib/avr/include/avr/iom8.h .. /usr/lib/avr/include/avr/portpins.h .. /usr/lib/avr/include/avr/common.h .. /usr/lib/avr/include/avr/version.h .. /usr/lib/avr/include/avr/fuse.h .. /usr/lib/avr/include/avr/lock.h
使用DWARF-3调试信息,宏定义将记录在调试信息中,并且在预处理文件中可见(*.i用于C代码,*.ii用于C++,*.s用于预处理汇编)。
*.i
*.ii
*.s
#define PORTD _SFR_IO8(0x12)
从包含该定义的行开始,向上滚动,直到找到说明宏定义发生在哪个文件中的注解。
# 45 "/usr/lib/avr/include/avr/iom8.h" 3
在我的工具链安装的情况下。这意味着注解后面的行跟随/usr/lib/avr/include/avr/iom8.h的第45行。如果您想查看PORTD的分辨率,请向下滚动到foo.i的末尾,其中包含预处理的源代码:
/usr/lib/avr/include/avr/iom8.h
foo.i
# 3 "foo.c" int main (void) { (*(volatile uint8_t *)((0x12) + 0x20)) = 0; }
0x12是PORTD的I/O地址,0x20是ATmega 8的I/O地址和RAM地址之间的偏移量。这意味着编译器可以通过out 0x12, __zero_reg__实现PORTD = 0:
0x12
PORTD
0x20
out 0x12, __zero_reg__
PORTD = 0
3条答案
按热度按时间pengsaosao1#
编译器提供的库是存储在静态库中的预编译目标代码。在gcc中,库的扩展名通常是.a(由于历史原因,代表“archive”),前缀是“lib”。
在构建时,链接器将搜索库档案,以找到解析引用库符号所需的目标代码模块。它提取所需的模块,并将它们链接到正在构建的二进制映像。
在gcc中,库libXXX. a通常使用命令行开关
-lXXX
链接-因此libXXX. a命名约定在这种情况下很重要,例如标准C库libc. a看起来是通过开关-lc
链接的。所以回答你的问题,编译器提供的库通常没有.c文件,这个库甚至不需要用C语言编写。
也就是说,由于是开源的,源文件(.c或其他格式)可以从各种库的存储库中获得。例如,对于标准C库:https://www.nongnu.org/avr-libc/ .
对于其他AVR架构和I/O支持库,您可以检查相关的头文件或文档。头文件通常会有一个样板注解,例如项目URL。
qoefvg9y2#
PORTB和其他特殊功能寄存器通常被定义为avr-libc提供的头文件中的宏。找到您的
include/avr
目录(包含io.h
的目录)。在该目录中,应该有许多其他头文件。例如,iom328p.h
包含以下行,该行定义了ATmega 328 P上的PORTB
:如果您还在查找作为
.a
文件分发的库,则应该运行avr-gcc -print-search-dirs
。nc1teljy3#
有几种方法可以找出系统标头的位置以及包含哪些标头:
一个月一个月
使用选项
-v
,GCC将打印(以及其他东西)它正在使用的路径。检查shell /控制台上的输出,GCC将打印搜索路径:最后一个位置是AVR-LibC,它提供
avr/io.h
。解析..
,该路径就是/usr/lib/avr/include
。avr-gcc -H -mmcu=atmega8 foo.c ...
假设C文件
foo.c
的内容为:对于
-H
,GCC会打印出它实际包含的文件:一个月八个月
使用DWARF-3调试信息,宏定义将记录在调试信息中,并且在预处理文件中可见(
*.i
用于C代码,*.ii
用于C++,*.s
用于预处理汇编)。从包含该定义的行开始,向上滚动,直到找到说明宏定义发生在哪个文件中的注解。
在我的工具链安装的情况下。这意味着注解后面的行跟随
/usr/lib/avr/include/avr/iom8.h
的第45行。如果您想查看PORTD的分辨率,请向下滚动到
foo.i
的末尾,其中包含预处理的源代码:0x12
是PORTD
的I/O地址,0x20
是ATmega 8的I/O地址和RAM地址之间的偏移量。这意味着编译器可以通过out 0x12, __zero_reg__
实现PORTD = 0
: