工程师笔记|常见的嵌入式软件工程师面试题

Q:什么是ISR?

A:ISR 是指中断服务程序。 这些是存储在特定内存地址的函数,当发生某种类型的中断时会调用这些函数。 Cortex-M 处理器系列具有管理中断执行的 NVIC


Q:我们可以给ISP传递参数或从ISR返回一个值吗?为什么?

A:ISR 不返回任何内容并且不允许传递任何参数。

当硬件或软件中断发生时会调用 ISR,它不会被任何代码调用,所以这就是没有参数传递到 ISR 的原因。因为它不会被任何代码调用,所以它不会有返回值。


Q:什么是 volatile 关键字?

A:volatile 关键字是一个类型限定符,可防止对象进行编译器优化。根据 C 标准,具有 volatile 限定类型的对象可能会以实现未知的方式进行修改或具有其他未知的副作用。您也可以说 volatile 限定对象的值可以随时更改,而无需代码采取任何操作。如果对象由 volatile 限定符限定,则每次程序访问该对象时,编译器都会从内存中重新加载该值,这意味着它可以防止将变量缓存到寄存器中。从内存中读取值是检查值不可预测变化的唯一方法。


Q:标准C语言和嵌入式C语言有什么区别?

A:C语言:是一种通用编程语言,广泛用于设计任何类型的基于桌面的应用程序。 它是一种用于开发操作系统的系统编程语言。 C 语言的主要特点包括对内存的低级访问、一组简单的关键字和干净的风格,这些特点使 C 语言适用于操作系统或编译器开发等系统编程。 本质上它采用原生平台开发方案,即它开发的应用程序是平台相关的,只能在单一平台上使用。

嵌入式 C:是标准C的扩展,而不能说是标准C的一部分。嵌入式C语言用于开发基于微控制器的应用程序。 嵌入式C语言对标准C的扩展是I/O硬件寻址、定点算术运算、访问地址空间等。


Q:C 中的 const 和 volatile 限定符有什么区别?

A:const 关键字是编译器强制执行的,它表示程序无法更改对象的值,这意味着它使对象成为不可修改的类型。 让我们看一个例子,

const int a = 0;

如果我们尝试修改“a”的值,我们将得到编译器错误,因为“a”用 const 关键字限定,防止更改“a”(整数变量)的值。

volatile 会阻止任何编译器优化,并表示对象的值可以被程序控制之外的东西更改,因此编译器不会对对象做出任何假设。 看个例子,

volatile int a;

当编译器看到上面的声明时,它会避免对“a”做出任何假设,并在每次迭代中从分配给“a”的地址读取值。


Q:C中的变量可以既是const又是volatile吗?

A:是的,可以同时使用 const 和 volatile。

将 volatile 和 const 关键字一起使用的一个重要用途是在访问 GPIO 寄存器时。在 GPIO被配置为输入的情况下,读取到的值将取决于外部因素(如开关或其他设备的输出信号)的改变。在这种情况下, volatile 发挥着重要作用,并确保编译器始终从 GPIO 地址读取值并避免做出任何优化。

使用 volatile 关键字后,无论何时访问端口,您都会获得正确的值,但仍然存在另一个问题,因为指针不是 const 类型,当您的程序更改了指针的指向地址时,所获取的数值就是错误的,这样我们就必须创建一个带有 volatile 关键字的常量指针。

定义的用法为:

int volatile * const PortRegister;

理解:

图片


Q:常用的使用volatile的场合?

A:1、访问内存映射外设寄存器或硬件状态寄存器。

#define COM_STATUS_BIT  0x00000006

uint32_t const volatile * const pStatusReg = (uint32_t*)0x00020000;

unit32_t GetRecvData()
{
    unit32_t RecvData;
    
    //Code to receive data
    while (((*pStatusReg)  & COM_STATUS_BIT) == 0)
    {
        // Wait until flag does not set
        //Received data in RecvData

    }
    return RecvData;
}

2、在多个线程之间共享全局变量或缓冲区
3、在中断例程或信号处理程序中访问全局变量

volatile int giFlag = 0;

ISR(void)
{
    giFlag = 1;
}

int main(void)
{

    while (!giFlag)
    {
        //do some work
    }

    return 0;
}

Q:什么是中断延迟?

A:中断延迟是处理器响应中断请求所用的时钟周期数。 这个时钟周期数是在中断请求的发生和中断处理程序的第一条指令之间计数。

Cortex-M 处理器的中断延迟非常低。 在下表中列出了 Cortex-M 处理器的中断延迟。

图片


Q:如何减少中断延迟?

A:中断延迟取决于许多因素,我在下面的陈述中提到了一些因素。

平台和中断控制器。

CPU 时钟速度。

定时器频率

缓存配置。

应用程序。

因此,通过正确选择平台和处理器,我们可以轻松减少中断延迟。 我们还可以通过缩短 ISR 并避免在 ISR 内调用函数来减少中断延迟。


Q:在中断服务程序(ISR) 中调用printf() 是否安全?

A:不建议在接ISR中调用printf()


Q:可以在 ISR 中放置断点吗?

A:可以设置断点,但是不建议这么做。


Q:在ISR中可以调用任何函数吗?

A:是的,但是不建议在中断中直接调用函数;建议在中断中先设置相关标志或执行数据准备,在主循环中进行数据处理。


Q:什么是中断嵌套?

A:在嵌套中断系统中,即使正在执行中断服务函数,也可以随时随地进行中断。 但是,只有最高优先级的 ISR 会立即执行。 优先级次高的 ISR 将在最高优先级的 ISR 完成后执行。


嵌套中断系统的规则是:

所有中断都必须被设定中断优先级。

初始化后,任何中断都可以随时随地发生。

如果低优先级 ISR 被高优先级中断中断,则执行高优先级 ISR。

如果高优先级 ISR 被低优先级中断中断,则高优先级 ISR 继续执行。

必须按时间顺序执行相同优先级的 ISR


Q:ARM Cortex 中的NVIC是什么?

A:Cortex-M 处理器系列中的嵌套向量中断控制器 (NVIC) 是具有极其灵活的中断优先级管理的中断控制器的一个示例。 它支持可编程优先级、自动嵌套中断支持以及对多个中断屏蔽的支持,同时仍然非常易于程序员使用。

NVIC 的 Cortex-M3 和 Cortex-M4 处理器支持多达 240 个中断输入,具有 8 个多达 256 个可编程优先级。

图片


Q:可以更改 Cortex-M 处理器系列的中断优先级吗?

A:可以。


Q:什么是启动代码,在进入main函数前芯片都做了什么工作?

A:芯片上电后,进入 main 函数之前调用的代码是启动代码,一般是用汇编语言编写的一小段代码。
启动代码至少包括以下部分

堆栈区的声明

堆区的声明

矢量表

重置处理程序代码

其他异常处理程序代码


Q:如何访问内存的固定地址?

A:

//Memory address, you want to access
#define RW_FLAG 0x1FFF7800

//Pointer to access the Memory address
volatile uint32_t *flagAddress = NULL;

//variable to stored the read value
uint32_t readData = 0;

//Assign addres to the pointer
flagAddress = (volatile uint32_t *)RW_FLAG;

//Read value from memory
* flagAddress = 12; // Write

//Write value to the memory
readData = * flagAddress;

Q:什么是堆栈溢出?

A:如果您的程序尝试访问超出可用堆栈内存的限制,则会发生堆栈溢出。换句话说,如果调用堆栈指针超出堆栈边界,则可以说发生堆栈溢出。
如果发生堆栈溢出,程序可能会崩溃,或者可以说是堆栈溢出导致的分段错误


Q:I2C和SPI的区别是什么?

A:在嵌入式系统中,I2C和SPI都扮演着重要的角色。这两种通信协议都是同步通信的例子,但仍然有一些重要的区别。I2C 和 SPI 通信协议之间的重要区别。

I2C 支持半双工,而 SPI 是全双工通信。

I2C 只需要两线进行通信,而 SPI 需要三线或四线进行通信(取决于要求)。

与 SPI 通信相比,I2C 速度较慢。

I2C 比 SPI 消耗更多功率。

I2C 比 SPI 更不易受噪声影响。

与 SPI 通信协议相比,I2C 的实现成本更低。

I2C 工作在线路和逻辑上,它有一个上拉电阻,而在 SPI 的情况下不需要上拉电阻。

在 I2C 通信中,我们在每个字节后获得确认位,SPI 通信协议不需要。

I2C 确保从设备接收发送的数据,而 SPI 不验证数据是否正确接收。

I2C 支持多主机通信,而 SPI 不支持多主机通信。

I2C 和 SPI 之间的一大区别在于,I2C 支持同一总线上的多个设备,而无需任何额外的选择线(基于设备地址工作),而 SPI
需要额外的信号(从选择线)线来管理同一总线上的多个设备。

I2C 支持仲裁,而 SPI 不支持仲裁。

I2C 支持时钟延长,而 SPI 不支持时钟延长。

I2C 可以被一个未能释放通信总线的设备锁定。

由于起始位和停止位,I2C 有一些额外的开销。

I2C 更适合长距离,而 SPI 更适合短距离。


Q:RS232和RS485有什么区别?

A:RS232 和 RS485 之间的一些重要区别:

图片

  • 6
    点赞
  • 144
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python学习笔记|字符串与正则表达式练习题答案 1. 练习题1: 题目:给定一个字符串s,找出其中的连续的最长的数字串。 答案:可以通过正则表达式来匹配数字串,然后使用max函数找出最长的。 代码示例: import re def find_longest_num_str(s): num_str_list = re.findall('\d+', s) longest_str = max(num_str_list, key=len) return longest_str s = "ab1234c56789def" print(find_longest_num_str(s)) 输出:56789 2. 练习题2: 题目:给定一个字符串s,将其中的每个空格替换为"%20"。 答案:可以通过正则表达式的sub函数来实现替换。 代码示例: import re def replace_space(s): new_s = re.sub(' ', '%20', s) return new_s s = "Hello World" print(replace_space(s)) 输出:Hello%20World 3. 练习题3: 题目:给定一个字符串s,判断它是否为回文字符串。 答案:可以使用切片操作将字符串反转,然后与原字符串进行比较。 代码示例: def is_palindrome(s): return s == s[::-1] s = "abcba" print(is_palindrome(s)) 输出:True ### 回答2: 以下是关于字符串和正则表达式练习题的答案: 1. 给定一个字符串s,编写一个函数,返回该字符串的反转字符串。 def reverse_string(s): return s[::-1] 2. 给定一个字符串s,编写一个函数,返回是否是回文字符串。 def is_palindrome(s): return s == s[::-1] 3. 给定一个字符串s和一个字符c,编写一个函数,返回字符串s中字符c的出现次数。 def count_char(s, c): return s.count(c) 4. 给定一个字符串s,编写一个函数,返回字符串s中的所有单词列表。 def split_words(s): return s.split() 5. 给定一个字符串s,编写一个函数,返回字符串s中的所有数字列表。 import re def extract_numbers(s): return re.findall(r'\d+', s) 这只是一些可能的答案,其中的解决方法可以有很多种。每个问题都有不同的解决方案,具体取决于个人的编程风格和需求。希望这些答案能够帮助你理解和学习Python中的字符串和正则表达式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值