找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3216|回复: 0
打印 上一主题 下一主题
收起左侧

linux嵌入式ARM-linux基础题目

[复制链接]
跳转到指定楼层
楼主
ID:101093 发表于 2017-1-10 12:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
                                    ARM体系结构
1、 请简述ARM处理器的特点,至少说出5个以上的特点。(5分)
:低功耗;低成本,高性能,RISC结构;指令定长;支持Thumb(16位)/ARM(32位)双指令集;体积小;
2、 请写出ARM内核和ARM SoC处理器的异同,并举例进行说明。(5分)
:ARM内核是ARM SoC处理器中的核心部分,所有ARM SoC都采用ARM的体系结构和指令集,ARM SoC主要是在ARM 内核基础上继承了Memory Controller,Interrtupt Controller,Timer,DMA Controller 以及像 GPIO,USB,IIC,LCD 等外设控制器。
3、 ARM内核有多少种工作模式?请写出这些工作模式的英文缩写。(7分)
:ARM有7种工作模式,usr、sys、svc、irq,abt,und、fiq。
4、 ARM内核有多少个寄存器,请列举出这些寄存器的名字和数量。(5分)
:ARM有37个寄存器,(1)未分组寄存器:R0-R7,共8个;(2)分组寄存器R8-R14,其中FIQ模式下有单独的一组R8-R12共5个,另外6种模式共用一组R8-R12,共5个,USR和SYS模式共用一组R13-R14,共2个,另外5种模式下各有独自的一组R13-R14,共10个;(3)程序计数器PC即R15寄存器,共1个;(4)状态寄存器CPSR,和5个备份状态寄存器SPSR,共6个;ARM总计37个寄存器。
5、 ARM通用寄存器中,有3个寄存器有特殊功能和作用,请写出它们的名字和作用。(6分)
:R13:SP栈指针寄存器,用来保存程序执行时的栈指针位置;R14:LR返回链接寄存器,用来保存程序执行BL指令或模式切换时的返回原程序继续执行的地址;R15:PC程序计数器,保存程序执行的当前地址。
6、 请描述一下CPSR寄存器中相关Bit的情况和作用。(5分)
:条件位(指令进行算术运算后的结果是否有进位,借位等),I位(IRQ异常允许位),F位(FIQ异常允许位),T位(ARM/Thumb工作状态),模式位(处理器工作模式)
7、 请写出以下相关ARM指令语句的注释:(7分)
MOV   R0, PC             把PC的值传送到 R0寄存器,此时PC地址为当前指令位置+8                                                           
ADD R0, R1, #1         把R1加上1的结果给R0寄存器                                                        
LDR R0,  =0x56000010     是伪指令,把0x56000010放到R0寄存器中,采用文字池技术。                                                           
LDR PC, [PC, #4]      把当前PC值加4位置的内容赋值给PC,实现绝对跳转     
MRS R0, CPSR      把CPSR的值传送给R0                                                         
BL LOOP    带返回地址的跳转指令,把下一条指令给LR后,跳转到Loop 地址                                                     
STMFD    R13!,{R0-R12}    压栈指令,把R0到R12寄存器的值通过R13栈指针进行压栈保存,同时这个栈是满递减方式的栈。
8、 什么是立即数?请简要描述立即数在使用时有什么注意要点。(2分)
立即数,主要是指寻址时直接在指令中出现的数,在使用时注意(1)立即数前需要加#(2)ARM指令只有32位长,立即数在指令中占12位存储空间,ARM用这12位空间8位表示有效数字-基数B,4位表示译为的数M,按照把B循环右移M*2位,构造成一个新的32位的数,其它位补0,所以在使用立即数时,要注意其是否合法。
9、 请问BL指令跳转时LR寄存器保存的是什么内容?并请简述原因。(3分)
BL跳转时,LR中保存的是执行BL跳转指令的下一条指令的地址,考虑流水线的情况,即当前的PC-4。LR用来在需要返回程序时从LR中还原程序执行的位置继续执行。
10、 请描述一下什么是处理器现场,如何进行保存现场?(5分)
每种工作模式下都包含R0-R15,CPSR这17个寄存器,程序的执行当前状态就保存在这些寄存器中,称为处理器现场。当发生模式切换时,由于其中的一些寄存器是多种模式下共用的寄存器,为了防止共用处理器寄存器中的值被破坏,所以需要保存原模式下的处理器现场,利用STM批量存储指令,把处理器现场对应的寄存器保存到栈上,待还原时再出栈恢复(模式和返回地址)。其中保存现场的工作,硬件完成了CPSR模式的保存和PC返回地址的保存,其他寄存器的保存工作主要依靠软件压栈完成,其中LR因为可能被异常处理程序中的BL跳转指令修改,所以一般都需要软件压栈再保存。
11、 请描述一下什么是小尾端Littler-Endian存储格式,如何编程确定处理器的存储格式?(2分)
小尾端:低地址存低字节,高地址存高字节。测试:按字节打印int型的0x12345678,如是小尾端,则先打78.(通过 union 的方式也可以实现测试是否是小尾端)
12、 请写出一条完整的ARM软件中断指令,并简要描述其作用。(2分)
SWI 0x1。SWI指令触发软中断异常,使程序的执行流跳转到异常向量表地址0x8,0x1是软中断的中断号,软中断处理程序可根据不同的中断号调用对应的处理子程序。一般SWI软中断都用于操作系统的系统调用。
13、 请描述一下ARM体系中异常向量表的概念。(7分)
异常向量表是从0x0地址开始,一共32个字节,包含8个表项,其中有1个保留不用,其他7个表项对应7种异常发生后的跳转位置,这7种异常发生后分别对应到5种异常模式。每个表项里面放的一般都是一条跳转指令,用来跳转到真正的异常处理程序入口,通过B指令,或者LDR PC,[PC, #?] 的方式都可以实现此类跳转。
14、 产生软中断和硬中断异常时,程序计数器跳转到的地址是哪里?(2分)
软中断:0x8,硬中断:0x18。
15、 请写出发生异常后,在进行异常响应时,硬件完成了哪些工作?(5分)
异常响应时:(1)硬件自动保存程序的返回地址到要切换的工作模式下的LR中;(2)硬件自动保存CPSR到要切换的工作模式下的SPSR中;(3)修改CPSR的模式位;(4)映射相应模式下的寄存器;(5)设置PC跳转到要进入的异常向量表的入口地址。

ARM SOC编程开发
16、 请写出一个ARM程序生成的bin文件映像中包含哪些内容?(3分)
ARM生成的bin文件包含:RO,RW 两个段,注意 ZI 段一般都不在 bin 文件中占用存储空间。
17、 请写出完整编译生成bin文件的命令行:使用文件为 start.s  main.c  (5分)
armasm start.s –o start.o
armcc –c main.c –o main.o
armlink start.o main.o –first start.o –o main.axf
fromelf –bin main.axf –o main.bin
18、 请写出armlink时经常使用的参数选项及其作用,不少于3个。(3分)
-first 指定目标二进制文件哪个链接时放在存储的最前面;-entry 指定程序的入口地址,即程序从哪里开始首先执行;-ro-base 指定程序链接时RO段采用的内部加载基址;-rw-base 指定RW段加载时的加载地址。
19、 请举例说明在ARM处理器上进行一次中断处理和中断异常处理的差异。(3分)
中断处理相比异常处理,主要是中断需要初始化中断源和中断控制器,中断发生后在ISR中要清除相应Pending位,而且要在进入中断处理程序一开始就清除。
20、 请写出从中断异常进行返回时,软件编程要处理的事项和注意要点。(2分)
(1)返回地址LR的调整。(2)在恢复PC的同时,恢复CPSR(恢复原来的模式,返回被打断的地址。)
21、 请详细描述我们在S3C2440开发板实验过程中进行串口初始化的流程和要点。(5分)
时钟频率设置(MPLL,PCLK的设置),串口数据位8位,停止位1位,奇偶校验无,波特率设置需要根据PCLK代入公式进行计算等
22、 请详细描述我们在S3C2440开发板实验过程中进行按键中断触发的流程和要点。(8分)
SVC和IRQ模式下的SP栈指针设置,IO管脚复用设置,设置按钮的触发模式(下降沿触发),管脚的中断模式使能,中断掩码寄存器屏蔽位打开,清除PND寄存器中的pending位,打开CPSR-I位;
23、 请说明S3C2440处理器,关于 memory map 的情况。(5分)
2440的memory分为8个bank,每个bank的固定大小为128M,每个bank均可以产生一个片选信号,共1G的地址空间,8个片选信号,bank0-bank5用来存放SROM器件,bank6和bank7用来存放SDRAM器件。
24、 请详细描述 bootloader 启动代码的设计流程,并说明你目前所实现的bootloader已经完成的功能有哪些,实现中遇到了哪些困难和bug问题? (5分)
bootloader的设计流程:硬件的初始化(1)初始化看门狗(2)关中断(3)设置处理器时钟(4)初始化SDRAM器件(5)初始化串口(6)实现shell命令解释器功能,(7) 提供通过串口的下载功能download和执行功能Go。要求能够讲的出你自己实现bootloader过程中遇到的实际问题和解决办法,这个很重要。
25、 请说明以下代码中可能存在的3个bug,并给出解决办法。(3分)
#define UART_BASE  0x50000000
#define UTRSTAT0   *(volatile unsigned int *) UART_BASE+0x10
#define UTXH0   *(volatile unsigned int *) UART_BASE+0x20
int main(void)
{
if( UTRSTAT0 & 0x4 == 0x4 )
UTXH0 = 'a';
return 0;
}
(1) UART_BASE+0x10应该加上括号(2)& 的优先级比 == 要低,所以要加括号。(3) if应该改为while( !(UTRSTAT0 & 0x4) )

附加题:
请说明SRAM, SDRAM, Nor Flash 和Nand Flash的异同,并详细描述各自编程上的注意要点。
异同见教材,编程上要注意说明 SRAM和NorFlash无须初始化就可以使用,SDRAM和NandFlash都需要初始化驱动代码才可以工作,NorFlash的写需要靠芯片手册规定的时序来做,STR指令不能够直接写入NorFlash和NandFlash,但可以直接写入SRAM和SDRAM。 NandFlash器件是属于IO方式进行读,和其他3种器件的总线读方式不一样,因此读写NandFlash需要相应的驱动。

                                                 Linux体系
答:ARM技术的设计者将ARM处理器在应用中可能产生的状态进行了分类,并针对同一类型的异常状态设定了一个固定的入口点,当异常产生时,程序会自动跳转到对应异常入口处进行异常服务。
    1.用户模式:非特权模式,也就是正常程序执行的模式,大部分任务在这种模式下  执行。在用户模式下,如果没异常发生,不允许应用程序自行改变处理器的工作模式,如果有异常发生,处理器会自动切换工作模式
    2.FIQ模式:也称为快速中断模式,支持高速数据传输和通道处理,当一个高优先级(fast)中断产生时将会进入这种模式。
    3.IRQ模式:也称为普通中断模式,:当一个低优先级(normal)中断产生时将会进入  这种模式。在这模式下按中断的处理器方式又分为向量中断和非向量中断两种。通常的中断处理都在IRQ模式下进行。
    4.SVC模式:称之为管理模式,它是一种操作系统保护模式。当复位或软中断指  令执行时处理器将进入这种模式。
    5.中止模式:当存取异常时将会进入这种模式,用来处理存储器故障、实现虚拟存储或存储保护。
    6.未定义指令异常模式:当执行未定义指令时会进入这种模式,主要是用来处理未  定义的指令陷阱,支持硬件协处理器的软件仿真,因为未定义指令多发生在对协处理器的操作上。
    7.系统模式:使用和User模式相同寄存器组的特权模式,用来运行特权级的操作系统任务。
    在这7种工作模式中,除了用户模式以外,其他6种处理器模式可以称为特权模式,  在这些模式下,程序可以访问所有的系统资源,也可以任意地进行处理器模式的切 换。
    在这6种特权模式中,除了系统模式外的其他5种特权模式又称为异常模式,每种  异常都对应有自己的异常处理入口点

1.解释命令ls -a | more具体含义.
ls -a命令显示当前目录下的所有文件包括隐藏文件,并将ls -a命令的执行结果通过管道传送给more命令分
屏显示。

2.LINUX中的管道指什么重定向又指什么
Linux中管道用 “|”表示,将一个命令的输出,作为你一个命令的输入。
重定向
3.GCC -g -o test.elf test.c的具体含义.
将源代码test.c文件编译连接成目标文件test.elf文件,同时对test.elf设置gdb调试开关
4.浅述GCC编译器在编译时都有哪几个过程
gcc编译c源码有四个步骤:预处理,编译,汇编,链接。

5,在题3的基础上编写一MAKEFILE文件,要求能自动完成编译和清除功能
SRCS = $(wildcard *.c)  -->定义变量SRCS,其职为当前文件夹下所有.c文件
OBJS = $(SRCS:.c = .o)  -->建SRCS中所有.c文件编译成.o文件
CC = gcc --> 编译器gcc
INCLUDES = -I/  --定义额外引用的头文件路径
LIBS = -I/  --定义额外使用的库路径名
CCFLAGS = -g -Wall -00  --CCFLAGS存放编译选项

test.elf : $(OBJS)  --test.elf是编译的最终目标文件,依赖于所有.o文件
    $(CC) $^ -O $@ $(INCLUDES) $(LIBS) --$^代表$(OBJS),$@代表test.elf
%.o : %.c
    $(CC) -c $< $CCFLAGS --将所有的.c文件编译成.o目标文件, $<代表所有的.c文件
clean:
rm *.o --清除所有的.o文件


.    Linux中的用户模式和内核模式是什么含意?
MS-DOS等操作系统在单一的CPU模式下运行,但是一些类Unix的操作系统则使用了双模式,可以有效地实现时间共享。在Linux机器上,CPU要么处于受信任的内核模式,要么处于受限制的用户模式。除了内核本身处于内核模式以外,所有的用户进程都运行在用户模式之中。
内核模式的代码可以无限制地访问所有处理器指令集以及全部内存和I/O空间。如果用户模式的进程要享有此特权,它必须通过系统调用向设备驱动程序或其他内核模式的代码发出请求。另外,用户模式的代码允许发生缺页,而内核模式的代码则不允许。
在2.4和更早的内核中,仅仅用户模式的进程可以被上下文切换出局,由其他进程抢占。除非发生以下两种情况,否则内核模式代码可以一直独占CPU:
(1)它自愿放弃CPU;
(2)发生中断或异常。
2.6内核引入了内核抢占,大多数内核模式的代码也可以被抢占。
   1) Linux中主要有哪几种内核锁?
     2) Linux中的用户模式和内核模式是什么含意?
    3) 怎样申请大块内核内存?   
   4) 用户进程间通信主要哪几种方式?     
5) 通过伙伴系统申请内核内存的函数有哪些?  
   6) 通过slab分配器申请内核内存的函数有?     
7) Linux的内核空间和用户空间是如何划分的(以32位系统为例)?  
   8) vmalloc()申请的内存有什么特点?   
   9) 用户程序使用malloc()申请到的内存空间在什么范围?   
   10) 在支持并使能MMU的系统中,Linux内核和用户程序分别运行在物理地址模式还是虚拟地址模式?
     11) ARM处理器是通过几级也表进行存储空间映射的?   
  12) Linux是通过什么组件来实现支持多种文件系通的?   
   13) Linux虚拟文件系统的关键数据结构有哪些?(至少写出四个)  
   14) 对文件或设备的操作函数保存在那个数据结构中?   
  15) Linux中的文件包括哪些?     
16) 创建进程的系统调用有那些?
     17) 调用schedule()进行进程切换的方式有几种?
     18) Linux调度程序是根据进程的动态优先级还是静态优先级来调度进程的?     
19) 进程调度的核心数据结构是哪个?     
20) 如何加载、卸载一个模块?   
   21) 模块和应用程序分别运行在什么空间?     
  22) Linux中的浮点运算由应用程序实现还是内核实现?《》   
   23) 模块程序能否使用可链接的库函数?   
   24) TLB中缓存的是什么内容?
     25) Linux中有哪几种设备?     
  26) 字符设备驱动程序的关键数据结构是哪个?   
  27) 设备驱动程序包括哪些功能函数?     
28) 如何唯一标识一个设备?   
    29) Linux通过什么方式实现系统调用?     
   30) Linux软中断和工作队列的作用是什么?



7. 如何使用gdb调试多进程
答:最常用的是attach方法,首先写程序时在子进程中调用sleep函数休眠30-60秒,

将程序编译成可执行文件,后台运行可执行文件,ps -fu root查看进程号,gdb,

attach进程号,再使用stop暂停子进程,设置一些断点和一些watch,break设置断点

,list命令察看源代码,step单步运行,next运行下一步,continue继续运行,

print打印变量信息。


3.GCC -g -o test.elf test.c的具体含义  将test.c 文件编译输出为test.elf

带上调试信息,可以用GDB调试用


4.浅述GCC编译器在编译时都有哪几个过程  要经历四个相互关联的步骤:预处理(也

称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接

(Linking)。 预处理(Preprocessing):命令gcc首先调用cpp进行预处理,在预处理

过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进

行分析。 编译(Compilation):接着调用cc进行编译,这个阶段根据输入文件生成以

.o为后缀的目标文件。 汇编(Assembly):汇编过程是针对汇编语言的步骤,调用as

进行工作,一般来讲,.s为后缀的汇编语言源代码文件和汇编.s为后缀的汇编语言文

件经过预编译和汇编之后都生成以.o为后缀的目标文件。 连接(Linking):当所有的

目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在

连接阶段,所有的目标文件被安排在可执行程序中的恰当位置,同时,该程序所调用

到的库函数也从各自所在的档案库中连到合适的地方

13.浅谈bootloader,kelnel,filesystem三者之间的关系.  嵌入式是linux启动过

程如下。 bootloader->kernel->filesystem->application 先是bootloader,

它是linux-kernel移植的基石,Bootloader是在系统启动之后、Kernel运行之前所

执行的第一段代码,其任务是为调用Kernel准备必要的软硬件环境。完成bootlaoder

的移植后,就是kernel的移植。主要包括添加特定模块的驱动,针对具体要求对内核

进行配置。这里有两点要注意:一是有些参数要与所用的bootloader向对应,如nand

的分区参数。二是bootlaoder对特定模块的驱动在进入kernel后便会有kernel接管

,并有kernel重新驱动文件系统主要是建立根文件和一些系统功能的实现,如bash。

用busybox很容易搞定。   3. Linux系统下.ko文件是什么文件?.so文件是什么文

件?   Linux下面文件名不代表什么。但是从常识上讲,.ko代码是驱动编译成的格

式, .so文件一般是动态库文件


  2、查看驱动模块中打印信息应该使用什么命令?如何查看内核中已有的字符设备的信息?如何查看正在使用的有哪些中断号?
答:1) 查看驱动模块中打印信息的命令:dmesg
2) 查看字符设备信息可以用lsmod 和modprobe,lsmod可以查看模块的依赖关系,modprobe在加载模块时会加载其他依赖的模块。
    3)显示当前使用的中断号cat /proc/interrupt



这几天面试几个想做安卓Linux驱动的,总体感觉上驱动基础还是比较薄弱,大部分情况是虽然做过驱动,但是基本上都是采用内核现成的,或者是开发板上已经有的,单独写过模块驱动很少,驱动机制理解不是很透彻.以下是几个随口问过的基础问题,供参考.

1、字符型驱动设备你是怎么创建设备文件的,就是/dev/下面的设备文件,供上层应用程序打开使用的文件?

2、写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的?

3、自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?

4、原子操作你怎么理解?为了实现一个互斥,自己定义一个变量作为标记来作为一个资源只有一个使用者行不行?

5、insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

6、在驱动调试过程中遇到过oops没?你是怎么处理的?

7、ioctl和unlock_ioctl有什么区别?

8、驱动中操作物理绝对地址为什么要先ioremap?

9、设备驱动模型三个重要成员是?platfoem总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没?

1、字符型驱动设备你是怎么创建设备文件的,就是/dev/下面的设备文件,供上层应用程序打开使用的文件?
答:mknod命令结合设备的主设备号和次设备号,可创建一个设备文件。
评:这只是其中一种方式,也叫手动创建设备文件。还有UDEV/MDEV自动创建设备文件的方式,UDEV/MDEV是运行在用户态的程序,可以动态管理设备文件,包括创建和删除设备文件,运行在用户态意味着系统要运行之后。那么在系统启动期间还有devfs创建了设备文件。一共有三种方式可以创建设备文件。
2、写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的?
答:中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。
评:写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后推出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。
第二:中断服务程序中不能有阻塞操作。为什么?大家可以讨论。      
第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。

3、自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?
答:使用自旋锁的进程不能睡眠,使用信号量的进程可以睡眠。中断服务例程中的互斥使用的是自旋锁,原因是在中断处理例程中,硬中断是关闭的,这样会丢失可能到来的中断。
评:回答的还可以。
4、原子操作你怎么理解?为了实现一个互斥,自己定义一个变量作为标记来作为一个资源只有一个使用者行不行?
答:原子操作指的是无法被打断的操作。我没懂第二句是什么意思,自己定义一个变量怎么可能标记资源的使用情况?其他进程又看不见这个变量
评:第二句话的意思是:
  定义一个变量,比如 int flag =0;
   if(flag == 0)
  {
       flag = 1;

       操作临界区;
      flag = 0;
   }这样可否?
5、insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?
答:insmod调用init函数,rmmod调用exit函数。这两个函数在设计时要注意什么?卸载模块时曾出现卸载失败的情形,原因是存在进程正在使用模块,检查代码后发现产生了死锁的问题。

评:要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,工作队列等等。也就是一个模块注册进内核,退出内核时要清理所带来的影响,带走一切不留下一点痕迹。
6、在驱动调试过程中遇到过oops没?你是怎么处理的?
没有。。
评:其他人可以接着说。
7、ioctl和unlock_ioctl有什么区别?
没用过unlock_ioctl。。
评:其他人可以接着说。
8、驱动中操作物理绝对地址为什么要先ioremap?
答:因为内核没有办法直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址。
评:其他人可以接着说。
9、设备驱动模型三个重要成员是?platfoem总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没?
这个真不知道。。
1
#define GPBCON (*(volatile unsigned long *)0x56000010)的理解
A:volatile
   当计算机需要一个数值的时候,会先把内存中(ARM处理寄存器地址)的值读取到寄存器(这
里指的是r0-r1....r15),然后下次在使用该值的时候就直接读取寄存器(r0-r1....r15)中的值
了。加上volatile之后,程序就会在每次需要该值的时候都读取一次内存。这是为了防止某些原
因硬件会改变其值。
B:
(volatile unsigned long *)即为强制类型转换;(volatile unsigned long *)0x56000010
的意思就是把0x56000010强制转换为unsigned long类型的指针。这时(volatile unsigned long
*)0x56000010就可以看做是一个指针p了。*(volatile unsigned long*)0x56000010等价于*p 。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表