【重要】C/C++/嵌入式,必会的理论概念

Feelings 专栏收录该内容
9 篇文章 0 订阅

请用不超过30字给出一个最能让我们录用你的理由

代码练习:strlen / strcmp / strcat / strcpy / memset / strstr / atoi / itoa / 冒泡排序 / 单向链表 / 单链表反序函数 / 双向链表 / C++构造、析构、虚函数

斐波那契数列(递归/高运行效率) (局部静态数组方式

OSI七层网络模型(应用层、会话层、表示层、传输层、网络层、链路层、物理层

TCP/IP五层结构(应用层、传输层、网络层、链路层、物理层

网络通信三次握手(客户端发送SYN,进入SYN_SEND状态;服务器确认发送SYN+ACK,进入SYN_RECV状态;客户端确认回发ACK,同时进入..状态

析构函数和虚函数的作用和用法( 默认的析构函数什么也不做,自定义的析构函数通常用来释放不再使用的内存空间;虚函数virtual xxx() = 0通常用作接口使用

含参数的宏与函数的优缺点 (宏只能实现替换,预编译就完成,适合用于定义经常改动或调用的;函数的话功能和可操作性更强大,在运行时被调用

全局变量、局部变量(全局变量在数据段、局部变量在栈区;同名时优先局部变量,通常会优先使用局部变量

static、const、volatile(static静态属性,生命周期/本地化;const常量只读属性,修饰指针有所区别;volatile易变的,直接从内存读取,访问稳定性

什么是中断,中断发生时CPU做什么工作?计算机的中断有哪几类?(cpu暂停正在执行的程序,保留现场后自动转去处理相应的事件,处理完成后,返回断点继续完成被打断的程序。①保护现场,备份cpsr;②修改cpsr,保存返回地址到lr;③执行中断异常处理程序;④恢复现场。IRQ、FIQ

CPU上电后,进入操作系统的main之前必须做什么工作?(必要硬件初始化、关看门狗、关中断、使能MMU、内存初始化、EMMC初始化、清空BSS段,跳转

计算机的基本组成部分和各自的作用(运算器、存储器、控制器、输入设备、输出设备

什么是进程和线程,有何区别?(进程是资源分配的基本单位,线程是执行的基本单位;进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮进程创建了一个主线程。每个线程有自己的堆栈。

# 管道 ( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间 使用。
# 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间 的通信。
# 信号量 ( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段
# 消息队列 ( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限 等缺点。
# 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件 已经发生。
# 共享内存 ( shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计 的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。
# 套接字 ( socket ) : 套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信


什么时候使用共享内存?(对进程间通讯的速度有要求的时候,使用共享内存,因为直接读取内存所以访问速度快,进程间通讯速度快

什么时候使用socket?什么时候使用http?(在传输大量数据的时候用socket,少量数据或者动作是用http

shell脚本三剑客:sed  awk  grep(
sed,操作文件的行编辑器,匹配正则表达式来进行文本过滤和转换文本;
awk,操作行处理,逐行读数据再切片处理输出;
grep,文本搜索,主要用于文本过滤


I2C通信时序图(已可以自行画出,2线式,通信以8位宽,SDA下降沿start,SCL低电平跳变,SDA低0高1,第9个位的时钟周期是ack信号,SDA上升沿stop

1-wire通信时序图(http://blog.csdn.net/zhengqijun_/article/details/52505931

函数调用主要4步( 将参数压入堆栈 保存寄存器的值 保存返回地址值 跳转

找出下面一段ISR的问题
__interrupt double compute_are(double radius)
{
 double area = PI * radius * radius;
 printf("\nArea = %f", area);
 return area;
}
中断服务程序没有返回值,应该写void。
中断服务程序没有参数,应该也写void。
中断服务程序应该短而高效,浮点运算恰恰降低了其效率。
中断服务程序不应该有重入和性能上的问题,所以不能使用printf函数。

>> 请简述Bootloader到Linux内核加载流程?
系统上电--->uboot完成硬件的初始化--->执行bootcmd中的命令--->加载操作系统到内存--->传递参数给内核,并启动内核--->检查CPU ID当前内核是否支持--->创建页表开启MMU--->start_kernel--->创建一个新的内核线程--->根据参数去挂载根文件系统--->从根文件系统中找到1号进程--->创建执行1号进程--->1号进程后续会创建子进程/bin/bash--->用户可以输入命令

>> 什么是优先级反转?如何解决优先级反转?

>> Linux中怎样申请大块内核内存? (vmalloc)

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

#define MIN(A,B) ((A) <= (B) (A):(B))

#error 命令,将停止编译并输出用户自定义的错误消息。

for(;;) 无条件循环,效率更高,反汇编查看的话没有判断只有跳转。

int p; //整形变量p
int *p; //一个指向整形数的指针p
int **p; //一个指向整形数的地址的二级指针p
int *p[3]; //一个包含有3个元素的指针数组p
int (*p)[3]; //一个指向具有3个整型元素的一维数组的指针p
int *func(int, int); //一个返回整形数地址的函数func,含2整形参
int (*func)(int, int); //一个指向函数地址的函数指针func,含2整形参
int (*func[10])(int); // 一个有10个函数指针的数组,每个指针指向一个函数,该函数有一个整型参数并返回一个整型数

volatile
并行设备的硬件寄存器;
中断服务子程序访问的非自动变量;
多线程中共享的变量;

#define BIT3 (0×1<<3)
static int a;
void set_bit3(void)
{
    a |= BIT3;
}
void clear_bit3(void)
{
    a &= ~BIT3;
}


int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;

1). ISR 不能返回一个值。
2). ISR 不能传递参数。
3). 在许多的处理器/编译器中,浮点一般都是不可重入的。ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
4).printf()经常有重入和性能上的问题。

对于一个int型不是16位的处理器为说,应编写如下:
unsigned int compzero = ~0;

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
    puts(“Got a null pointer”);
else
    puts(“Got a valid pointer”); // 输出(malloc分配成功了,返回合法的指针)

sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。

getmemory函数中的malloc 不能返回动态内存, free()对str操作很危险

char szstr[10];
strcpy(szstr,”0123456789″);
长度不一样,会造成非法的操作。(后面的字符串常量是11个字符,包含\0)

纯虚函数如何定义?使用时应注意什么?
virtual void f()=0;
是接口,子类必须要实现

进程死锁的原因:资源竞争及进程推进顺序非法

死锁的4个必要条件:互斥、请求保持、不可剥夺、环路

死锁的处理:鸵鸟策略、预防策略、避免策略、检测与解除死锁

操作系统中进程调度策略有哪几种?FCFS(先来先服务),优先级,时间片轮转,多级反馈

TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。
UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP头包含很少的字节,比 TCP 负载消耗少。
tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好
udp: 不提供稳定的服务,包头小,开销小

让程序跳转到绝对地址是0x100000去执行:
函数指针:void (*) ();
定义类型:typedef void(*)() voidFuncPtr;
类型强转:*((voidFuncPtr)0x100000) ();

unsigned short A = 10;
printf("~A = %u\n", ~A); //4294967285
char c=128;
printf("c=%d\n",c);//-128

对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
答案:c用宏定义,c++用inline

软件测试都有那些种类?
答案:黑盒:针对系统功能的测试    白合:测试函数功能,各函数接口

预编译:
1、总是使用不经常改动的大型代码体。
2、多个模块都使用一组头文件或宏定义。

malloc和new区别:
1. malloc是C的函数,new是C++中的操作符;
2.malloc函数只分配内存,new不仅分配了内存还调用构造函数对对象进行了初始化操作;
3.malloc分配内存后返回内存地址为无类型指针,new出来的指针时带类型信息的。  



【C 语言
1、 C 和 C++有什么不同?

1)C语言面向过程编程,重程序的实现;C++面向对象编程,重程序的设计;

2)C是C++的一个子集;C++全面兼容C;

3)C++相对于C引入了重载、内联函数、异常处理、类的封装/继承/多态、以及STL/容器类等…

2、进程和线程的异同、关系?

       1)进程:是系统资源分配和调度的基本单位,有自己的pid;

          线程:是运行的基本单位,有自己的tid。

       2)进程:一个进程至少拥有1个线程,为主线程

          线程:同一个进程中的线程可以并发,且共享进程的资源,拥有自己独立的栈空间执行序列

       3)进程有独立的地址空间,多进程程序要比多线程程序健壮,但进程切换时,需要复制PCB,资源开销大,效率稍低;

          线程没有独立地址空间,必须依赖具体的进程才能执行,线程的切换不需要复制PCB资源开销小,效率比进程高;

       4)进程能实现跨机器迁移

          线程适合于SMP(对称多处理器)机器上运行。

3、进程间通信都有哪几种机制?其中最快的机制为哪种?

       1)管道(pipe):

          管道用于具有亲缘关系的进程间通信,其中有名管道可实现无亲缘关系的进程间通信;

       2)信号(signal):

          软中断机制,进程收到信号相当于处理器收到中断请求,用于通知进程对应的事件处理;

       IPC通信>>

       3)消息队列(message queue)

          克服了管道和信号中量有限的缺点,利用内存中公共消息缓冲区实现进程间通信;

       4)共享内存(shared memory)——【最快的IPC通信形式】因为进程可以直接读写内存,不需要数据的拷贝。

          内核维护一块由多个进程均可访问的内存,实现进程通信,需要互斥锁或信号量集配合实现同步;

       5)信号量集(semaphore)

          多进程之间或同一进程内的多线程之间实现同步和互斥的手段;

       socket网络通信>>

       6)套接字(socket):

          实现网络中不同机器之间的进程间通信,应用广泛。

4、请简述 socket 编程中 client 和 server 的大致步骤?

       以基于TCP的编程模型为例。

       server:

       1) 创建通讯端(套接字) - socket

       2) 初始化服务器的地址空间 - sockaddr_in成员

       3) 将套接字和服务器地址空间绑定 - bind

       4) 监听通讯端- listen

       5) 等待客户端连接的到来,到来返回连接描述符 - accept

       6) 通过连接描述符进行读取客户端数据 - read //data

       7) 通过连接描述符给客户端响应 - write

       8) 关闭连接描述符 – close

       client:

       1) 创建通讯端(套接字) - socket

       2) 初始化服务器的地址空间(ip转换) - sockaddr_in成员/inet_pton

       3) 连接服务器,成功返回即连接成功 - connect

       4) 向服务器发送请求信息 - write

       5) 从服务器获取响应信息 - read

       6) 对响应信息做相关的数据处理 - //data

       7) 关闭通讯端(套接字) – close

5、进程之间通信的途径?进程死锁的原因?死锁的 4 个必要条件?

       进程通信途径:管道、信号、消息队列、共享内存、信号量集、套接字。

       死锁:多个进程循环等待它方占有的资源而无限期地僵持下去的一种程序运行情况。

       进程死锁原因:

              1)系统提供资源有限

              2)系统资源分配不当

              3)多进程中进程运行推进顺序不合理

       解除死锁条件:

              1)互斥条件:1个资源每次只能被1个进程使用。

              2)请求与保持条件:1个进程因请求资源阻塞时,对已获得的资源保持不放。

              3)不抢占条件:进程已获得的资源在未使用完之前,不能强行抢占。

              4)循环等待条件:多进程之间形成一种头尾相接的循环等待资源关系。

6、死锁的处理?操作系统中进程调度策略有哪几种?

       死锁的处理方法:

              1)最简单最常用的是:系统重新启动。但代价大,进程已完成的运算都付之东流。

              2)撤销进程,剥夺资源。一次性终止参与死锁的进程,或者逆序逐步撤销参与死锁的进程,需考虑优先级及代价。

       进程调度的策略:

              1)先来先服务(FCFS)

              2)优先级

              3)时间片轮转

              4)分级调度

              5)多级反馈轮转

【区别于】常用的作业调度算法有:先来先服务算法(FCFS)、最短作业优先算法(SJF)、最高响应比优先算法(HRRN)、优先级调度算法、均衡调度算法等。

7、 TCP 和 UDP 的区别?简述 3 次握手协议?

       TCP和UDP的区别:

              1)TCP面向连接;UDP面向无连接

              2)TCP传输无差错不丢失,安全可靠效率不如UDP;UDP传输容易丢包,安全性较差传输效率高于TCP

              3)TCP连接点对点;UDP支持多对多交互通信;

              4)TCP首部开销20字节;UDP首部开销8字节;

              5)TCP是全双工可靠信道;UDP是不可靠信道

【第一次握手】:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

    SYN:同步序列编号(Synchronize Sequence Numbers)

【第二次握手】:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

【第三次握手】:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

8、什么是字节对齐,为什么要对齐?怎么样实现字节对齐?

       字节对齐概念:

              各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放。

       字节对齐原因:

              1)减少CPU访存次数,提高CPU的访问效率

2)提高对于不同硬件平台下代码的可移植性

3)合理利用可以有效节省存储空间

       字节对齐方法:

              C编译器默认为每个变量或数据单元按其自然对界条件分配空间。也可以通过以下2中方式改变对齐方式:

1)#pragma pack

· 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。

· 使用伪指令#pragma pack ( ),取消自定义字节对齐方式。

              2)__attribute( )

· __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。

· __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

9、多线程编程中要注意什么问题 ?

1)明确使用线程的目的。是对不同的资源(例如SOCKET连接)进行管理,考虑多个线程;

2)控制线程的调度和阻塞。如利用事件的触发来控制线程的调度和阻塞,也有用消息来控制的;

3)不能出现死锁问题。线程中如果用到公共资源,要考虑公共资源的线程安全。一般用互斥锁机制来控制。

4)合理使用sleep。何时Sleep,Sleep的大小要根据具体项目,做出合理安排。一般原则非阻塞状态下每个循环都要有SLeep,这样保证减少线程对CPU的抢夺。

5)线程的终止。一般要使线程体在完成一件工作的情况下终止,一般不要直接使用抛出线程异常的方式终止线程。

6)线程的优先级。一定根据程序的需要要有整体的规划。

10、什么是预编译,何时需要预编译?

       预编译又称为预处理,是做些代码文本的替换工作

处理以# 开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等,就是为编译做的预备工作的阶段。

何时需要预编译:

总是使用不经常改动的大型代码体

11、 typedef 和 #define 有什么区别?

       1)作用不同:

typedef:给已有的类型起一个类型别名

              #define:宏定义,给使用到定义的标识符进行替换

       2)执行时间不同:

              typedef在编译阶段,具有类型检查动能;#define在预处理阶段不做类型检查

       3)作用域不同:

              typedef有自己的作用域;#define没有作用域限制。

       4)修饰指针有差异:

              typedef定义指针可以同时定义多个指针;#define宏定义的指针只能对第一个变量定义为指针

13、谈谈内存分配方式?

       物理内存映射到CPU虚拟地址空间分配方式:

内核空间1G(3G ~ 4G-1)

用户空间3G(0 ~ 3G-1):

              栈stack临时局部变量存放区。栈帧数据岁函数结束而消失。——后进先出

              堆heap动态内存区。程序运行时malloc和new动态申请的区域。——手动申请/释放

              BSS静态内存分配区。存放未初始化的全局变量。——可读可写

              数据段data静态内存分配区。存放已初始化的全局变量、静态局部变量。——可读可写

              代码段text:存放程序执行代码只读常量区域。——只读

14、Unix 中进程间通信,资源的共享,加锁机制

       进程间通信:

              管道、信号、消息队列、共享内存、信号量集、套接字。

共享资源:

硬件(如uart)、文件、共享内存、线程见可见的全局变量等...

       加锁机制:

              多进程或多线程在同一时刻访问相同的共享资源时,需要加锁。

              内核的驱动模块在运行时访问相同的共享资源时,需要加锁。

15、全局变量和局部有什么区别?是怎样实现的?操作系统和编译器是怎样知道的?

       1)作用域不同:全局变量为整个程序;局部变量为当前函数或者循环

       2)生命周期不同:全局变量随程序的结束而结束,局部变量随函数或者循环的退出而释放;

       3)存储方式不同:全局变量在数据段;局部变量在区;

       4)使用方式不同:函数内部会优先使用与全局变量同名的局部变量

       怎样实现:

              全局变量在编译时,由编译器分配了虚拟地址在数据段

局部变量在程序运行时,对应使用该局部变量的函数被调用时才真正分配虚拟地址在栈区

       操作系统和编译器怎么知道:

              操作系统和编译器从变量地址所属的存放区域分辨局部变量和全局变量。

16、谈谈你对大端模式,小端模式的理解

       1)大小端是数据在内存中的存储方式。

大端:数据的高字节存放在内存的低地址,低字节存放在内存的高地址。

小端:数据的高低字节与内存的高低地址存放一致

       2)因为数据类型所占的bit位不同,在16bit、32bit、64位这样不同的处理器上,寄存器宽度已经大于1个字节,就要考虑如何去将多个字节安排存放的问题,因此有了大小端模式。

       3)目前intel的x86平台是小端模式

ARM平台默认是小端模式可切换为大端;

在C语言中一般都默认是小端;

网络中传输的数据统一是大端模式

17、static 的作用? const 作用?volatile 含义?

       static:

              1)修饰局部变量。生命周期:当前文件<也有限定当前文件可用的效果>,作用域:当前函数

2)修饰全局变量。生命周期和作用域:当前文件 <该变量只能在本文件使用>

3)修饰函数。生命周期和作用域:当前文件 <限制函数为本模块可用>

       const:

              1)被const修饰的变量或者函数等,使其变为只读属性,其内容会被放在内存的代码段区域;

              2)修饰指针的时候稍有不同,*号前代表指针指向的内容为只读,*号后面代表指针本身只读,不可改变指向;

              3)const合理使用可以保护不希望被修改的参数,一定程度减少bug的出现。

       volatile:

              表示一个变量也许会被后台程序意想不到的修改。

变量如果加了volatile修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。

volatile可以保证对特殊地址的稳定访问。

寄存器地址要加volatile修饰,主要是因为寄存器里面的值是随时变化的。

主要用在3种情况:

   1) 并行设备的硬件寄存器

   2) 中断服务子程序中会访问到的非自动变量

   3) 多线程应用中被几个任务共享的变量

18、链表和数组有什么区别?数组与指针的区别?

       数组 vs 链表:

数组的数据是顺序存储的,存储大小固定

链表的数据可以随机存储,存储大小可以动态的改变

       数组 vs 指针:(以字符型指针变量和字符数组最能说明问题)

              1)分配内存数

                     数组:<数据类型所占内存×下标>的字节数。指针:32bit系统,默认分配4字节存放内存地址。

              2)初始化赋值

                     数组:将字符串放到数组分配的存储空间去。指针:先将字符串放到内存,再将该内存首地址放到指针里。

              3)赋值方式

                     数组:数组名不能用字符串字面值直接赋值。指针:可以直接用字符串字面值赋值。

              4)输入方式

                     数组:字符串可以直接输入到字符数组中。指针:不能将字符串直接输入指针变量,需要指针指向1块内存。

              5)值的改变

                     数组:数组名代表的数组首地址不能改变。指针:指针变量的值可以改变,即指针改变指向。

19、队列和栈的异同?

       相同点:只允许在端点处插入和删除元素的数据结构。

       不同点:栈遵循后进先出原则(LIFO),队列遵循先进先出原则(FIFO)。

20、谈谈你对堆栈的理解?

       1)堆栈是两种数据结构

       2)堆栈都是一种数据项按序排列的数据结构,只能在一端对数据项进行插入和删除

       3)堆:是共有的空间,全局堆和局部堆,由程序员手动分配和释放,程序结束时由系统回收。

          栈:是线程独有的,保存其运行状态和局部变量的区域,由编译器自动分配和释放

21、简述 BSS 段,数据段,代码段,堆,栈中分别存储的是什么数据?

       栈(stack):是用户存放程序临时创建的非静态局部变量

       堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。

       BSS段:BSS段通常是用来存放程序中未初始化的全局变量

       数据段(data):通常是用来存放程序中已初始化的全局变量

       代码段(text):通常是用来存放程序执行代码、只读常量

22、所有的程序都要系统调用吗?不系统调用可以实现程序运行吗?

       不是。如ARM裸板开发。

       不系统调用可以实现系统运行,如ARM裸板下的shell程序,使用无限循环的方式实现指令输入对应调用独立实现的函数功能。

24、创建子进程的函数是什么?谈谈你对父进程和子进程间的理解?

       pid_t fork (void);

       成功:在父进程里子进程的pid==0被返回;

       失败:在父进程里返回pid==-1,子进程没有被创建,errno被设置。

       父子进程的理解:

              1)【ID】父子进程ID不同;

              2)【异步】子进程创建后,父子进程的执行是异步的,即调度先后顺序并不确定;

              3)【代码区共享】子进程是父进程的不完全副本,代码区与父进程共享,其他数据从父进程拷贝;

              4)【孤儿进程】父进程退出,但子进程还在,子进程为孤儿进程,就被1号进程收养。如系统的一些守护进程;

              5)【僵尸进城】子进程结束,父进程还没来收尸,子进程就成僵尸进程,占用系统资源,直到父进程回收才释放;

25、谈谈你对排序算法的认识?你接触过那些排序算法?

       排序算法认识:

              即把一组数字按照某种重复执行的代码算法进行顺序排列的解决方法。

       冒泡排序,快速排序。目前已掌握冒泡排序

【嵌入式】

面试题0:' 什么是嵌入式软件开发?
以应用为中心,软硬件的裁剪。
对功能性、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
    硬件和软件两部分构成:
    硬件:处理器、存储器、外设器件、I/O端口、图形控制器等;
    软件:驱动程序、操作系统(OS)、应用程序。

面试题1:' 谈谈对中断(异常)的理解?
    1. 中断是计算机中异步事件的处理机制。
    2. 结合按键和S5P6818说说中断的触发过程。(三级设置)
    3. 当按键按下后,硬件做什么,软件做什么?
        软件:
            异常向量表,跳转到中断处理函数执行,函数中【保护现场】,以便回去执行原有内容,【判断哪个中断源】触发的,调用不同的处理函数,【清除对应中断】,【恢复现场】。
        对应中断处理函数,执行速度要快。

面试题2:' FIQ比IRQ快在哪里?
    1. FIQ的优先级高于IRQ;
    2. 在异常向量表中FIQ可以比IRQ少一条跳转指令;
    3. 现场保护时,切换为FIQ模式是r8~r12不需要压栈;

面试题3:' 给你一个芯片,如何写它的驱动程序?
    1. 确定使用的开发板型号;
    2. 阅读芯片手册,电路原理图;
    3. 通信时序测试验证;
    4. 尝试先读取芯片的ID标识,读取成功后再做其他数据传输完成驱动。


面试题4:' 谈谈I2C总线?
    1. 飞利浦公司开发的一套两线式串行同步总线;
    2. 主要通过SDA数据线、SCL时钟线两套总线实现通信;
    3. 特点:
            空间小,硬件互联成本低;
            主从之分 - 真正的多主机总线;
            主设备 - 发起者;
            总线冲突仲裁;
            从设备地址唯一。

0、你为什么学习嵌入式?嵌入式软件开发的基本模式?谈谈对嵌入式linux 系统的认识?

【为什么学习】:

       从小喜欢四驱车之类的带电的小玩具,到如今社会的发展让智能硬件开始进入个人消费者,才真正接触到这些智能硬件的让我热血的初衷,没有什么比“使用软件来控制一个硬件”的感觉更让我有成就感。

【嵌入式开发的基本模式】:

①开发环境的建立:主机/开发板;②源文件编程;③交叉编译和连接;④联机下载调试

【嵌入式开发的基本流程】:

①系统定义和需求分析;

②系统设计方案初步确立;

③初步设计方案性价比评估与方案评审论证;

④完善初步方案,实施;

⑤软硬件集成测试;

⑥系统功能、性能、可靠性测试。

【对嵌入式linux系统的认识】:

1)以'应用'为中心,软硬件可'裁剪'可'移植'的系统;

2)对功能性、可靠性、成本、体积、功耗有严格要求的专用计算机系统;

3)主要应用在物联网、车联网、智能家居、智能穿戴设备等智能硬件。

1、系统调用与 API 的区别?

1)定义:

    系统调用:是一种特殊接口,用户可以访问内核空间,规定了用户进程进入内核的具体位置;

    API:是应用程序接口,一些预定义的函数。跟内核没有必然联系。

2)功能:

    系统调用,是通过中断向内核发请求,实现内核提供的某些服务。

    API,是函数的定义,规定了函数的功能,跟内核无直接联系。

2、简单说一下对嵌入式的理解?对嵌入式软件开发的理解?

嵌入式系统,是一种完全嵌入受控器件内部,为特定应用而设计的专用计算机系统。

嵌入式系统的核心,就是由一个或多个预先编程好的,用来执行少数几项任务的单片机或微处理器组成。

嵌入式软件开发的理解:

嵌入式软件就是给专门的嵌入式系统设计的软件,主要是对嵌入式系统的功耗、内存、体积、成本等有严格的要求,所以嵌入式软件一定要精简、高效。

嵌入式软件就是用来驱动硬件工作以达到系统工作的目的。

3、简单说一下移植的流程?

① 从厂家获取uboot引导文件,确定主机和目标板的数据传输方式,烧写uboot到硬件设备;

② 从linux官网下载linux系统,进行剪裁编译,传输并写入到硬件;

③ 编写嵌入式驱动源文件,安装交叉编译器,进行编译连接,传输并写入硬件;

③ 功能测试。

4、简单说一下驱动的框架结构?

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE ("GPL");

int __init func_init (void) { return 0;}

void __exit func_exit (void) { }

module_init (func_init);

module_exit (func_exit);

1、对设备初始化和释放;

2、把数据从内核传送到硬件和从硬件读取数据;

3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据;

4、检测和处理设备出现的错误。

5、什么是中断?中断发生时 CPU 做什么工作?

       CPU在执行一个程序时,对系统发生的某个事件(程序自身或外界的原因)作出的一种反应:CPU暂停正在执行的程序,保留现场后自动转去处理相应的事件,处理完该事件后,到适当的时候返回断点,继续完成被打断的程序。

①保存现场 - 备份cpsr

硬件结构自动将PS和PC寄存器的内容压栈作为现场信息保存起来。

②修改cpsr,保存返回地址到lr

②执行中断异常处理程序

③恢复现场

6、简述 UART 协议?

uart,即通用串行异步收发器。

串行通信是指利用一条传输线将资料一位位地顺序传送。

异步通信以一个字符为传输单位,通信中两个字符间的时间间隔是不固定的,然而在同一个字符中的两个相邻位间的时间间隔是固定的。

数据传送速率用波特率来表示,即每秒钟传送的二进制位数。

数据通信格式:

    起始位:先发出一个逻辑”0”信号,表示传输字符的开始。

    数据位:可以是5~8位逻辑”0”或”1”。如ASCII码(7位),扩展BCD码(8位)。小端传输

    校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验)

    停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。

    空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。

7、简述 IIC 协议?

IIC,是飞利浦公司开发的一套“两线式串行同步通信总线”,用于连接微控制器及其外围设备。两套总线:SCL时钟线,SDA数据线。一个时钟周期一个比特位。

特点如下:

    1)占用空间小,硬件互连成本低;

    2)主从之分,真正的多主机总线;

    3)发起者一定是主设备;

    4)支持总线冲突仲裁;

    5)从设备地址唯一。

8、简述 1-wire 协议?

       一线式单总线传输协议。

9、谈谈对 GPIO 的认识?

在ARM里,所有I/O都是通用的,称为GPIO(General Purpose Input/Output)。每个GPIO端口包含8个管脚,如PA端口是PA0~PA7。GPIO模块支持多个可编程输入/输出管脚(具体取决于与GPIO复用的外设的使用情况)。GPIO模块包含以下特性:

 1)可编程控制GPIO中断

    ---屏蔽中断发生

    ---边沿触发(上升沿、下降沿、双边沿)

    ---电平触发(高电平、低电平)

 2)输入/输出可承受5V

 3)在读和写操作中通过地址线进行位屏蔽

 4)可编程控制GPIO管脚配置:

    ---弱上拉或弱下拉电阻

    ---2mA、4mA、8mA驱动,以及带驱动转换速率(Slew Rate)控制的8mA驱动

    ---开漏使能

    ---数字输入使能

   GPIO管脚可以被配置为多种工作模式,其中有3种比较常用:高阻输入、推挽输出、开漏输出

10、简述同步通信和异步通信?

同步通信原理

    同步通信是一种连续串行传送数据的通信方式,一次通信只传送一帧信息。

异步通信原理

    异步通信是一种很常用的通信方式。异步通信在发送字符时,所发送的字符之间的时间间隔可以是任意的。

同步通信与异步通信区别:

   1.同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节。

    2.同步通信效率高;异步通信效率较低。

    3.同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。

    4.同步通信可用于点对多点;异步通信只适用于点对点。

11、中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?

中断:CPU对系统发生的某个事件作出的一种反应:CPU暂停正在执行的程序,保留现场后自动地转去执行相应的处理程序,处理完该事件后再返回断点继续执行被“打断”的程序。

异常:是由于软件错误而引起的。

中断,是CPU所具备的功能【硬件】。

异常,是软件运行过程中的一种开发过程中没有考虑到的程序错误【软件】。

12、中断和轮询哪个效率高?怎样决定是采用中断方式还是采用轮询方式去实现驱动?

中断,能够协调CPU与外设间的速度差异,能够协调各种外设间的速度差异,提高系统工作效率。

轮询,是使用程序控制方式,其速度指标由总线传输速度,端口相应速度共通决定。

中断,通常用于高优先级,高响应性,低频度业务,串口的接收就是一个典型。

轮询,通常用于低优先级,低响应性,高频度大数据量业务,键盘扫描是一个典型。

通常情况是中断与轮询相配合,例如定时功能,在定时器中断里设置标志位,程序主任务里轮询该标志位,做具体操作。键盘扫描也通常是外部中断记录按下了哪个键,轮询在做进一步的扫描处理(例如去抖功能)。

13、 U-boot 的启动过程?

(1)第一阶段的功能

① 硬件设备初始化

② 加载U-Boot第二阶段代码到RAM空间

③ 设置好栈

④ 跳转到第二阶段代码入口

(2)第二阶段的功能

① 初始化本阶段使用的硬件设备

② 检测系统内存映射

③ 将内核从Flash读取到RAM中

④ 为内核设置启动参数

⑤ 调用内核

14、简述 ARM-linux 启动过程?

①内核自解压阶段

②内核引导阶段

③内核初始化阶段

④BusyBox初始化阶段

15、在 linux 内核中希望你的中断处理程序执行时间越短越好,但是中断处理程序要完成的功能不变,内核是通过什么机制解决矛盾?

1)顶半部 top half

在其中完成最紧急的工作,通常就是寄存器的读写,清除中断标志。

登记底半部(告诉内核,活没干完,由内核找个合适的时机继续完成剩余工作)。

2)底半部 bottom half

完成那些中断处理过程不太紧急,比较耗时的工作。

16、 Linux 设备中字符设备、块设备和网络设备有什么主要的区别?

字符设备:读写顺序固定,读写过程中不涉及缓存。如键盘...(较多)

块设备:读写顺序不固定,读写过程中有缓存。如磁盘/硬盘...(基本已标准化)

网络设备:读写顺序固定,读写过程中有缓存。如网卡...(可能涉及一点移植)

17、请简述主设备号和次设备号的用途?

一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各设备。

    主设备号:用来区分不同类型的设备。

    次设备号:用来区分同类设备中各个设备。

19、驱动里面为什么要有并发、互斥的控制?如何实现?

【竞态】竞争共享资源的状态。

    共享资源:硬件(如uart)、文件、共享内存、线程见可见的全局变量

    临界区:访问共享资源的代码

【竞态产生的原因】

    1)SMP-对称多处理器的多个cpu之间,使用共同的系统总线,会抢占;

    2)抢占式内核中,多进程之间的竞争;

    3)进程和中断之间的抢占;

    4)中断和中断之间的抢占;

【如何实现】

使用中断屏蔽、原子操作、自旋锁、信号量等策略保护临界区资源。

20、 Linux 内核互斥机制都有哪些?

       中断屏蔽、原子操作、自旋锁、信号量、互斥锁等…

21、裸版的中断和 Linux 系统下的中断以及 UC 所讲的中断的异同?(?暂?略?

22、 CISC 体系与 RISC 体系分别指什么?

    CISC:复杂指令集。

    RISC:精简指令集。

23、谈谈对中断的顶半部底半部机制的理解?

    中断服务程序执行速度越快越好,但是某些硬件对其中断处理就是非常耗时,不能很快结束,针对以上矛盾,linux内核中将中断处理过程分为两部分:

        1)顶半部 top half

            在其中完成最紧急的工作,通常就是寄存器的读写,清除中断标志。

            登记底半部(告诉内核,活没干完,由内核找个合适的时机继续完成剩余工作)

        2)底半部 bottom half

            完成那些中断处理过程不太紧急,比较耗时的工作

24、 谈谈 ARM 裸板程序怎么编程?

1)裸板电路图(底板/核心板);

2)CPU芯片手册;

3)从电路图找到控制电平高低的GPIO管脚;

4)从芯片手册中找到对应控制GPIO管脚的输入输出功能相关的寄存器,针对对应的比特位进行置位操作;

5)裸板编程,必须包含执行入口的main函数、strcmp字符串比较、uart通信驱动程序以及其他设备驱动模块。

25、 谈谈 Norflash 和 Nandflash 的区别?

1)NOR的读速度比NAND稍快一些。

2)NAND的写入速度比NOR快很多。

3)NAND的4ms擦除速度远比NOR的5s快。

4)大多数写入操作需要先进行擦除操作。

5)NAND的擦除单元更小,相应的擦除电路更少。

26、 谈谈对 ARM 处理器的理解?

ARM处理器是英国Acorn有限公司设计的低功耗成本的第一款RISC微处理器。

ARM处理器的三大特点是:耗电少功能强、16位/32位双指令集和合作伙伴众多。

1)体积小、低功耗、低成本、高性能;

2)支持Thumb(16位)/ARM(32位)双指令集,能很好的兼容8位/16位器件;

3)大量使用寄存器,指令执行速度更快;

4)大多数数据操作都在寄存器中完成;

5)寻址方式灵活简单,执行效率高;

6)指令长度固定。

27、 linux 内核分离思想?

外设a、b、c的驱动与主机控制器A、B、C的驱动不相关,主机控制器驱动不关心外设,而外设驱动也不关心主机,外设只是访问核心层的通用的API进行数据传输,主机和外设之间可以进行任意的组合。

【C++
1、谈谈你对面向对象的认识 ?
2、指针和引用的区别?谈谈你对指针和引用的理解?常引用有什么作用?
3、 C++中的 class和 struct 的区别?
4、类成员函数的重载、覆盖和隐藏区别?
5、面向对象的三个基本特征,并简单叙述乊?
6、谈谈对设计模式的理解?
7、关联、聚合(Aggregation)以及组合(Composition)的区别?
8、谈谈你对拷贝构造函数和赋值运算符的认识?
9、什么是浅拷贝?什么是深拷贝?
10、 C++容器的分类及各自的特性?

  • 5
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值