嵌入式面试--问题及部分答案

RS485是如何使用的,485差分通信的逻辑“1”对应的电平差是多少。

采用差分线的好处就是,差值相减就会忽略掉干扰依旧能输出正常的信号,把这种差分接收器忽略两条信号线上相同电压的能力称为共模抑制。RS是差分信号,两条线的差值为+2到 +6时为逻辑1,两条线的差值为-2到-6为逻辑0;

当接收器使能引脚RE逻辑低时,接收器被激活。当定义为VID=VA–VB的差分输入电压为正且高于正输入阈值VIT+时,接收机输出R变高。当VID为负且低于负输入阈值VIT-,接收机输出R变低。如果VID在VIT+和VIT-之间,则输出不确定。

在堆区分别申请两个1个字节的内存,其内存空间会连续吗?为什么?

不会,堆区中的空闲内存以链表的方式保存,当第一个内存被申请后,申请块的剩余内存被保存到链表中,当下次申请时又再链表中重新寻找大于需要内存的内存块。

堆分配的空间在逻辑地址上是连续的,但在物理地址上是不连续的(因为采用了页式内存管理,windows下有段机制、分页机制),如果逻辑地址空间上已经没有一段连续且足够大的空间,则分配内存失败。

堆区和栈区申请内存的区别

栈区:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,内存的分配是连续的。栈是向低地址扩展的数据结构,是一块连续的内存的区域,栈的大小是较小的。栈由系统自动分配,速度较快。但程序员是无法控制的。

堆区:一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收。堆是向高地址扩展的数据结构,是不连续的内存区域,堆的保存类似链表,不连续因此操作更加灵活,堆的空间较大。堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

堆区和栈区出现数组越界,各自的表现

在栈区:可能会对越界位置的数据进行操作,如:栈区是由高到低保存数据的,数组下标增加时地址是由低到高的,即ARR[10]相对放置ARR[0]的高地址当中,当访问ARR[11]时可能会对上一个保存在栈中的数据进行操作。

栈区数组越界:

1:栈区数组越界会将形参或者局部变量踩,可能导致函数运行参数取空,进程崩溃。

2:形参或者局部变量是循环停止条件,可能导致死循环。

3:函数调用栈越界,可能将下一条指令跳转地址或者上层函数地址踩,导致命令执行异常,或者访问非法函数地址。

如图,定义数组时申请的空间为三,当数组越界时,arr[5]就是a,当对arr[5]操作时将会修改

堆区数组越界:

1:堆访问越界,当越界地址没有分配给其他内容,则不会存在明显副作用。已经分配给其他线程使用,则会出现踩内容。同时由于堆分配的内存,实际会比malloc的大,在踩内存是不一定会踩到其他变量或者线程的空间

项目中如何使用到RT-Thread的消息队列和信号量的?

static关键字

使用static关键字会将变量变成静态变量。

对于全局变量:全局变量本来就保存在静态区,不能改变其生命周期,只是变成静态变量后只能被声明该变量的文件所引用,不能被其他文件所引用,即便是 extern 外部声明也不可以,原本全局变量通过extern方式可以在不同文件中引用。

对于局部变量:会将局部变量保存在静态区,生命周期与程序的周期相同,当函数结束后不会被释放,只有在第一次才会初始化该静态变量,后面再次调用函数时不会对变量进行初始化操作。在main函数之前初始化,在程序退出时销毁。(无论是局部静态还是全局静态)

修饰函数:被static修饰的函数只能在被定义的文件中使用,并且定义和声明在同一个文件当中。

修饰成员函数

用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量。静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。例如可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);还可以实现某些特殊的设计模式:如Singleton;

存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用,所以静态数据成员不能在任何函数内分配空间和初始化。未经初始化的静态全局变量会被程序自动初始化为0(在函数体内声明的自动变量的值是随机的,除非它被显式初始化,而在函数体外被声明的自动变量也会被初始化为 0);

C变量有3种链接属性:外部链接、内部链接或无链接。具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量。这意味着这些变量属于定义它们的块、函数或原型私有。具有文件作用域的变量可以是外部链接或内部链接。外部链接变量可以在多文件程序中使用,内部链接变量只能在一个翻译单元中使用。全局变量是外部链接,当加上static关键字后将它的链接属性改为内部链接。

const用法

修饰普通变量:使该变量变为只读变量后面不可修改。

修饰指针 :(以int为例)

const int* p1( int const * p1)为常量指针,不可以通过解引用的方式修改变量的值,但是可以修改指针指向的地址,或者通过变量修改所指向的值 。

int * const p2 为指针常量,可以通过解引用的方式修改指向的地址的值,但指针本身是一个常量,不可以修改指向的地址。

const int * const p3,常指针常量,两个都不能修改

int a=4;
int b=5;
const int* p1=&a;//const在 * 前为常量指针
//*p1=6//为非法操作
  a=5;//通过修改变量来修改地址变量的值  
p1=&b;可以修改指向的地址
int * const p2=&b;//指针常量必须初始话
//p2=&a//为非法操作,不能修改指向的地址    

栈和堆的区别
TCP/UDP区别?
TCP如何保证传输可靠的?
快速排序/冒泡排序算法讲解?时间复杂度多少?
如何判断排序算法的稳定性

若待排序序列中两个数相等arr[i] = arr[j],排序前i在j前面,排序后i仍在j前面,则表示该排序算法稳定,否则不稳定。

生成可执行程序的编译过程?
预处理:展开宏和头文件
编译:将源代码编译为汇编语言
汇编:将汇编语言翻译为二进制文件
链接:将目标文件、启动文件、相应的静态库/动态库文件链接起来,生成可执行文件
链接过程分为动态链接和静态链接,分别用在哪些场景下?
何为内存泄露、内存越界?若运行过程中出现内存泄漏,有哪些定位手段?
有使用过一些基础的STL容器吗
进程通讯方式有哪几种?开发过程中使用过哪几种?讲下消息队列创建和销毁的过程?进程间通讯消息队列是怎么保证同步传递过去的?
通过调用哪些接口实现TCP通讯?
服务端存在多客户端同时通讯时,这种高并发处理有哪些方法?
开发过程中遇到死机、越界等问题你会怎样去排查?
用过操作系统吗?FreeRTOS的任务管理深入了解过吗?项目中用到了哪些FreeRTOS相关支持
[3] Linux了解过吗?学习过哪些知识?做过哪些吧相关的应用?
[4] 说下一些常用指令?文件编译为可执行文件的命令是什么?
static、volatile
头文件中<>、“”区别

RS232/RS485/CAN通信的原理(硬件、软件)、区别

CAN通信一直无法进入接收中断可能是什么原因?
  • 波特率不匹配

  • 发送的帧格式存在问题进入了Event中断—缺少总线仲裁,屏蔽不用的中断

  • 未使能中断

  • 接收中断中要从接收缓冲区RxFIFO将数据读到RxFrame中

如何判断有限长链表是否有环?
<think>好的,我现在要处理用户关于嵌入式开发面试常见问题答案的查询。首先,用户已经提供了两个引用内容,我需要先仔细阅读这些内容,确保回答准确并正确引用。 用户提到引用[1]和引用[2],其中引用[1]主要涉及嵌入式面试的基础知识、项目经验、问题解决能力和对系统的理解,特别是C/C++的别。引用[2]则讨论了结构体内存对齐的规则。我需要确保在回答中正确引用这些内容,并生成相关问题。 接下来,我需要整理常见的嵌入式面试问题。通常,嵌入式面试问题分为几个大类:基础知识(如C/C++、数据结构、操作系统)、硬件相关(如微控制器、外设通信)、项目经验、问题解决和实际应用。根据用户提供的引用,我应该重点在基础知识和内存管理部分展开,同时结合其他常见问题。 首先,关于C和C++的别,引用[1]提到这是常见问题,需要详细说明。需要提到面向对象特性、标准库、内存管理等方面。然后,结构体内存对齐规则来自引用[2],需要详细解释三个条件,并给出例子,如结构体成员的对齐和填充。 接下来,其他常见问题可能包括static关键字的作用、volatile关键字、中断处理流程、别、RTOS的理解、看门狗定时器的作用、位操作、const关键字、大小端模式以及优化代码的方法。这些问题都是嵌入式面试中的经典问题,需要逐一解答,确保每个问题都有清晰的解释和示例。 在编写答案时,要遵循用户提供的格式要求,使用$...$和$$...$$来包裹数学表达式,但可能在这个回答中数学公式较少,主要集中在代码示例或技术术语上。例如,在解释结构体对齐时,可能需要计算偏移量,这时候使用行内公式。同时,代码块需要用正确的语法高亮,如C语言代码。 另外,需要确保回答结构清晰,分点列出问题答案,每个问题有对应的引用标记。例如,在回答C/C++别时,引用[1],而在结构体内存对齐时引用[2]。其他问题如果没有直接引用来源,则不添加引用标记,但如果有相关引用内容,需要适当关联。 生成的相关问题需要涵盖用户可能感兴趣的后续问题,例如优化代码的方法、RTOS的应用场景、大小端模式的实际应用等。这些问题应该引导用户进一步深入理解嵌入式开发的各个方面。 最后,检查回答是否符合用户的所有要求:使用中文、正确引用、语法正确、结构清晰、相关问题生成等。确保没有遗漏任何系统级指令,特别是格式要求和引用标识的正确放置。</think>### 嵌入式开发面试常见问题及解答 #### 一、基础知识类问题 1. **C与C++的主要别是什么?** C是面向过程的编程语言,而C++支持面向对象编程(如类、继承、多态)。C++还引入了模板、异常处理、命名空间等特性,并扩展了标准库(如STL)。C++兼容C语法,但在内存管理(如`new/delete`)、函数重载等方面有差异[^1]。 2. **`static`关键字在C语言中的作用?** - 修饰局部变量:使变量生命周期延长至程序结束,作用域仍限于函数内。 - 修饰全局变量/函数:限制其作用域仅在当前文件内(避免命名冲突)。 示例: ```c static int count = 0; // 仅当前文件可见 void func() { static int local_count = 0; // 函数调用间保留值 } ``` 3. **结构体内存对齐规则是什么?** 规则如下[^2]: - 结构体首成员地址与结构体首地址相同。 - 成员地址偏移量是其自身大小的整数倍,否则编译器填充字节。 - 结构体总大小是最大成员大小的整数倍,否则末尾填充。 示例: ```c struct Example { char a; // 1字节(偏移0) int b; // 4字节(偏移4,中间填充3字节) }; // 总大小8字节(1+3+4) ``` --- #### 二、硬件与系统类问题 4. **嵌入式系统中`volatile`关键字的作用?** 用于告知编译器变量可能被意外修改(如硬件寄存器或中断服务程序),禁止优化对其的访问。例如: ```c volatile uint32_t *reg = (uint32_t*)0x40000000; ``` 5. **中断处理的基本流程?** - 保存当前上下文(如寄存器)。 - 执行中断服务程序(ISR)。 - 恢复上下文并返回原任务。 注意:ISR应尽量简短,避免阻塞。 6. **(Stack)与(Heap)的别?** - :由编译器自动管理,存放局部变量,分配速度快但空间有限。 - :手动分配(如`malloc`),空间更大但可能产生碎片。 --- #### 三、应用与实践类问题 7. **实时操作系统(RTOS)的核心特性?** 支持任务调度、优先级抢占、同步机制(如信号量、队列)和确定性响应时间,适用于实时性要求高的场景(如工业控制)。 8. **看门狗定时器(Watchdog Timer)的作用?** 防止程序跑飞或死锁。若未定期“喂狗”,则触发系统复位。 9. **如何优化嵌入式代码的存储空间?** - 使用`const`修饰常量,将其放入Flash而非RAM。 - 减少全局变量,启用编译器优化选项(如`-Os`)。 - 用位域替代布尔变量。 --- #### 四、进阶问题 10. **解释大小端模式(Big-Endian vs Little-Endian)?** 大端模式将高位字节存储在低地址(如网络协议),小端模式相反(如x86架构)。示例: ```c uint32_t num = 0x12345678; // 内存布局(小端):0x78 0x56 0x34 0x12 ``` 11. **`const int *p`与`int *const p`的别?** - `const int *p`:指针指向的值不可变。 - `int *const p`:指针本身不可变(指向固定地址)。 --- §§ 1. 如何分析嵌入式系统的内存泄漏? 2. 解释SPI、I2C、UART协议的别与应用场景? 3. 什么是优先级反转?如何避免? 4. 嵌入式开发中如何实现低功耗设计?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值