嵌入式面试中可能问到的题目和答案整理(硬件篇)

本文详细对比了NAND Flash与NOR Flash的区别,包括它们的数据读取方式及在嵌入式系统中的应用。重点介绍了NOR Flash能够直接执行代码的特点,以及NAND Flash在操作上的特殊性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       写在前面:在大战之前,最好还是先做好准备,鉴于上一次的失利,所以接下来面试之前,还是要整理一下自己的问题库,这样才不会出现面试的时候,一问基础,懵逼的回答不上来,那就实在是太尴尬了。
  

硬件相关

1、nandflash和norflash的区别,对norflash的操作方式的理解

       两种芯片的结构不同 NORflash之所以可以片内执行,就是因为他符合CPU去指令译码执行的要求。CPU送一个地址出来,NORflash就能给一个数据让CPU执行,中间不需要额外的处理操作。    

       NAND flash不一样是因为nandflash有地址,数据,命令共用IO口的问题,cpu把地址发出来之后,并不能直接得到数据,还需要控制线的操作才能完成。就是他没有专用的SRAM接口。

       嵌入式系统中代码的执行方式主要有3种:

       1、完全映射

       2、按需分页

       3、eXecute In Place (XIP)片上执行。    

参考: 

1)http://blog.youkuaiyun.com/amberman/article/details/8122300
2)http://blog.youkuaiyun.com/qq_30866297/article/details/72622107

2、



<think>嗯,用户想了解嵌入式软件开发面试中C语言的常考点答案。我得先回想一下常见的C语言面试问题,特别是嵌入式领域比较关注的部分。首先,嵌入式系统通常对内存管理、指针、位操作、volatile关键字、数据结构、中断处理这些方面比较重视。 首先,关键字static的作用。在C语言中,static有三种用法:函数内部修饰变量,使其生命周期延长;文件内修饰函数或全局变量,限制作用域。这部分需要详细说明,并举例子。 然后是volatile关键字。嵌入式里经常处理硬件寄存器,volatile告诉编译器不要优化,每次都从内存读取。比如状态寄存器的例子,如果不加volatile可能导致循环条件被优化。 const的用法,特别是指针相关的情况,比如const在前在后时的不同含义,比如const int*int* const的区别。这部分容易混淆,需要清晰解释。 接下来是内存管理,堆栈的区别。嵌入式系统资源有限,堆栈溢出是常见问题,需要解释两者的分配方式、大小限制以及使用场景。 指针数组的区别,特别是当它们作为函数参数时的不同。比如sizeof操作符在数组指针上的结果不同,以及数组名是常量指针等。 位操作,比如置位、清零、翻转特定位的方法。嵌入式常用位操作来控制硬件寄存器,比如使用位掩码移位操作。 结构体的内存对齐问题,为什么要对齐,如何手动调整对齐方式,可能还需要提到#pragma pack或者__attribute__((packed))这些编译器指令。 中断服务函数(ISR)需要注意的事项,比如不能有返回值、参数,不能调用不可重入函数,尽量短小等。这部分是嵌入式特有的,需要强调。 预处理器的作用,比如宏定义的优缺点,条件编译的使用场景,如#ifdef DEBUG这样的例子。 还有可能涉及到的大小端问题,如何判断系统是大端还是小端,这在嵌入式数据通信中很重要。可以用联合体或者指针的方法检测。 函数指针的应用,比如在回调函数、状态机中的应用,嵌入式系统中常用函数指针来实现灵活的调用机制。 可能还需要提到动态内存分配的问题,嵌入式系统通常避免使用malloc/free,因为容易导致碎片,而更喜欢静态分配。 还有const指针的结合使用,比如指向常量的指针常量指针的区别,用户可能容易搞混,需要例子说明。 另外,递归函数在嵌入式中的使用风险,因为栈空间有限,可能导致溢出,所以嵌入式代码中通常避免深度递归。 还有关于内存映射的I/O操作,如何通过指针访问特定地址的硬件寄存器,这也是嵌入式开发中的常见操作。 可能还需要解释一下什么是野指针,如何避免,比如释放后置空,指针初始化等。 还有结构体联合体的区别,联合体在节省内存方面的应用,比如协议解析时常用联合体结构体结合。 最后,可能还要提到一些常见的代码题,比如字符串操作、链表操作、算法优化等,但用户主要问的是八股,所以可能更偏向理论点。 需要确保覆盖到这些点,并且每个问题给出简洁准确的答案,最好分点列出,结构清晰。同时注意使用$$...$$格式的独立公式,比如在举例位操作时可能需要用数学表达式。不过C语言的题目可能数学表达式不多,但像位运算的例子可能需要用代码块或者行内代码,不过根据系统指令,数学表达式需要用$...$,可能用LaTeX表示位运算的例子,比如掩码计算。 不过可能大部分内容更适合用代码块,但用户要求的是数学表达式用LaTeX。可能需要调整,例如位运算中的表达式,比如置位第n位可以成:x |= (1 << n),用行内代码或者数学表达式?这里可能需要确认,但根据系统指令,变量、表达式需要用$...$,所以可能用$x |= (1 << n)$这样的形式。 总之,整理这些知识点,分门别类,每个问题给出答案示例,尽量简明扼要,符合面试准备的要点。</think>以下是嵌入式软件开发面试中C语言常考知识点及参考答案,按重点分类整理: --- ### 一、**关键字与存储类** 1. **`static`的作用** - **作用1**:修饰局部变量,延长生命周期(存储在静态区)。 ```c void func() { static int count = 0; // 只初始化一次 count++; } ``` - **作用2**:修饰全局变量或函数,限制作用域为当前文件(隐藏性)。 2. **`volatile`的作用** - 告知编译器变量可能被意外修改(如硬件寄存器),禁止优化,每次从内存读取。 - **示例**: ```c volatile uint32_t *status_reg = (uint32_t*)0x40000000; while (*status_reg & 0x01); // 防止被优化为死循环 ``` 3. **`const`的不同用法** - `const int *p`:指向常量的指针(值不可改)。 - `int * const p`:常量指针(指针地址不可改)。 - `const int * const p`:指针值均不可改。 --- ### 二、**内存管理** 1. **堆(Heap)与栈(Stack)的区别** - **栈**:编译器自动分配,存放局部变量/函数参数;大小固定(嵌入式通常较小)。 - **堆**:手动分配(`malloc`/`free`),空间大但需防内存泄漏/碎片。 2. **内存对齐原则** - **原因**:CPU访问对齐数据更高效。 - **手动对齐**: ```c #pragma pack(1) // 1字节对齐 struct Data { char a; int b; // 默认对齐可能插入填充字节 }; ``` --- ### 三、**指针与数组** 1. **指针与数组的区别** - **`sizeof`结果不同**: ```c int arr[10]; int *p = arr; sizeof(arr); // 40(假设int为4字节) sizeof(p); // 4或8(指针大小) ``` - **数组名是常量指针**:`arr`不可修改,`p`可指向其他地址。 2. **函数指针的应用** - **回调函数示例**: ```c void callback(int data) { /* ... */ } void register_callback(void (*func)(int)) { func(100); } ``` --- ### 四、**位操作与硬件交互** 1. **位操作技巧** - **置位第n位**:`x |= (1 << n)` - **清零第n位**:`x &= ~(1 << n)` - **判断第n位**:`(x & (1 << n)) != 0` 2. **寄存器访问** - **直接地址操作**: ```c #define GPIO_DATA (*(volatile uint32_t*)0x40020000) GPIO_DATA |= 0x01; // 置位第0位 ``` --- ### 五、**中断与优化** 1. **中断服务函数(ISR)注意事项** - 不可传递参数/返回值,避免调用非可重入函数(如`malloc`)。 - 尽量简短,通过标志位与主程序通信。 2. **`volatile`防止编译器优化** - 多线程共享变量或硬件寄存器必须用`volatile`修饰。 --- ### 六、**预处理器与宏** 1. **宏定义的优缺点** - **优点**:代码复用,减少函数调用开销。 - **缺点**:易出错,无类型检查。 - **示例**: ```c #define MAX(a, b) ((a) > (b) ? (a) : (b)) ``` 2. **条件编译** - **调试代码控制**: ```c #ifdef DEBUG printf("Debug: %d\n", value); #endif ``` --- ### 七、**数据结构** 1. **联合体(Union)应用** - 节省内存,同一位置存储不同类型数据。 - **示例**: ```c union Data { int i; float f; char str[4]; }; ``` --- ### 八、**常见代码题** 1. **判断大小端** ```c int check_endian() { union { int i; char c[4]; } u = {0x01020304}; return u.c[0] == 0x01; // 返回1为大端 } ``` 2. **字符串反转** ```c void reverse(char *str) { int len = strlen(str); for (int i = 0; i < len/2; i++) { char temp = str[i]; str[i] = str[len-1-i]; str[len-1-i] = temp; } } ``` --- ### 总结 嵌入式C语言面试注重底层理解(内存、指针、硬件交互),建议结合代码实践加深理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值