嵌入式八股第三期

TCP和UDP区别

  1. TCP是面向连接的,UDP是无连接的(TCP需要简历连接但UDP直接发送数据)
  2. TCP是可靠的,UDP是不可靠的
  3. TCP只支持点对点通信,UDP支持一对一,一对多,多对多
  4. TCP报文首部20个字节,UDP首部8个字节

C语言怎么将某一位置一

1或 被置1

1与 被保持

0或 被保持

0与 被清零

互斥量

是对临界资源的独占式处理

任意时刻互斥量的状态只有两种,开锁或闭锁。当互斥量被任务持有时,该互斥量处于闭锁状态,这个任务获得互斥量的所有权。当该任务释放这个互斥量时,该互斥量处于开锁状态,任务失去该互斥量的所有权。

消息队列:

用于任务与任务间、中断和任务间传递一条或多条信息的数据结构

任务从队列里面读取消息时,如果队列中消息为空,读取消息的任务将被阻塞;否则任务就读取消息并且处理;

有多个消息发送到消息队列时,通常将先进入队列的消息先传给任务,消息队列的读取一般满足先进先出的原则;

片外Flash怎么操作

一般通过SPI来进行读写片外Flash

包括最开始的读写使能,读Flash的ID,按页写Flash,擦除扇区

映射到物理地址,是谁做这个操作

是MMU(memory manage unit)内存管理单元

它负责将虚拟地址转换为物理地址,并将其发送给内存控制器,从而实现对物理内存的访问

形参和实参的区别

实参是在调用时传递给函数的参数

形参是在定义函数名和函数体的时候使用的参数,用来接收调用该函数时传入的参数

形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用

实参出现在主调函数中,进入被调函数后,实参变量也不能使用

形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元

EB配置CAN有哪些项需要配置

CANController、transmit or recevice、方式是中断还是轮询、采样点、缓冲区大小、是标准帧还是拓展帧格式

劳德巴赫部分

常用命令:

RESet 复位debugger

SYStem.Mode:设置系统模式,单步或是运行

SYStem.CONFIG MMU 设置或查询存储器单元状态

SYStem.Down 关闭目标系统

Data.dump 访问内存地址

CMM脚本

智能指针:

  • auto_ptr:已经不用了
  • unique_ptr:独占式指针,同一时刻只能有一个指针指向同一个对象
  • shared_ptr:共享式指针,同一时刻可以有多个指针指向同一个对象
  • weak_ptr:用来解决shared_ptr相互引用导致的死锁问题

shared_ptr和weak_ptr之间是什么关系?

weak_ptr是用来辅助shared_ptr的,每一个weak_ptr它指向share_ptr而不是实际的操作函数

shared_ptr是不是线程安全?

  • 不是
  • 引用计数的增减是原子操作没问题,但是shared_ptr的读写本身不只包括引用计数操作,还包括资源所有权的操作,这两个操作合起来不是原子的
  • 如果要求线程安全必须加锁

shared_ptr应该要有三个成员:

  • 裸指针:指向所要管理的对象
  • 强引用计数:就是一个int指针,记录了有多少个shared_ptr指向裸指针
  • 弱引用计数:也是一个int指针,记录了有多少个weak_ptr指向裸指针

unique_ptr和shared_ptr的区别

(1)unique_ptr代表的是专属所有权,不支持复制和赋值。但是可以移动

shared_ptr 代表的是共享所有权,shared_ptr 是支持复制的和赋值以及移动的

(2)资源消耗上

unique_ptr 在默认情况下和裸指针的大小是一样的。 所以 内存上没有任何的额外消耗,性能是最优的,我们大多数场景下用到的应该都是 unique_ptr。

shared_ptr 的内存占用是裸指针的两倍。因为除了要管理一个裸指针外,还要维护一个引用计数。因此相比于 unique_ptr, shared_ptr 的内存占用更高。在使用 shared_ptr 之前应该考虑,是否真的需要使用 shared_ptr, 而非 unique_ptr。

sharedptr在64位操作系统下大小有多大两个指针,64字节

weak_ptr的原理?

shared_ptr中有一个成员时,弱引用计数。往weak_ptr被赋值时,弱引用计数自增1

weak_ptr的使用场景

用来解决悬空指针问题。

打破shared_ptr相互引用导致死锁的问题。

缓存对象

J6E MACL配置

CAN

先是配置CanController,配置波特率、ramblock(canfd必须配置)、FIFO配置硬件,处理模式是终端还是轮询,发送和接收单位

MCUClock

开启Mcu Clock Init Api

配置Clock Id、输入时钟源、分频系数、计算最后的输出速率

项目里分了几个任务,任务优先级是怎么划分的?

接收数据和发送数据同优先级,上位机按键会触发中断,会给32会依据具体按键发送对应的指令给传感器,包括复位,测量范围,停止测量等

排序算法:

插入排序:

public static void sort(int arr[],int len){
  for(int i=1; i<len, i++)
  {
      int key=arr[i];
      int j=len-i;
      while((j>0) && (arr[j]>key))
      {
          arr[j+1]=arr[j];
          j--;
      }
      arr[j+1]=key;
  }
}

快速排序:

int Paritition1(int A[], int low, int high) {
   int pivot = A[low];
   while (low < high) {
     while (low < high && A[high] >= pivot) {
       --high;
     }
     A[low] = A[high];
     while (low < high && A[low] <= pivot) {
       ++low;
     }
     A[high] = A[low];
   }
   A[low] = pivot;
   return low;
 }

 void QuickSort(int A[], int low, int high) //快排母函数
 {
   if (low < high) {
     int pivot = Paritition1(A, low, high);
     QuickSort(A, low, pivot - 1);
     QuickSort(A, pivot + 1, high);
   }
 }

单向链表和双向链表有什么区别?

  1. 单链表只有一个指向下一结点的指针,也就是只能next
  2. 双链表除了有一个指向下一结点的指针外,还有一个指向前一结点的指针,可以通过prev()快速找到前一结点,顾名思义,单链表只能单向读取

单向链表的空间比双链表小,在时间需求不严格的场景下,会使用单链表

**单向链表:**只有一个指向下一个节点的指针。

优点:单向链表增加删除节点简单。遍历时候不会死循环;

缺点:只能从头到尾遍历。只能找到后继,无法找到前驱,也就是只能前进。

适用于节点的增加删除

双向链表**:**有两个指针,一个指向前一个节点,一个后一个节点。

优点:可以找到前驱和后继,可进可退;

缺点:增加删除节点复杂,需要多分配一个指针存储空间。

适用于需要双向查找节点值的情况。

freertos和linux的区别

FreeRTOS 则是一个轻量级的实时操作系统,专注于实时性和可靠性,适用于资源受限的嵌入式系统

Linux 是一个功能强大的多用户、多任务操作系统,支持各种硬件和软件

Linux 通常用于服务器、桌面计算机、移动设备等更复杂的系统。它在需要多任务处理、丰富的软件生态和广泛的硬件支持的场景中表现出色

FreeRTOS 主要用于嵌入式系统,如物联网设备、工业控制、汽车电子等对实时性要求较高的场景

FreeRTOS 是专门设计为实时操作系统,提供了确定性的任务调度和响应时间,适用于对实时性要求严格的应用

为什么flash的起始地址是0x08000000

这是因为STM32不仅可以从内部Flash启动,还可以从系统存储器和内部SRAM启动,

我们将内部Flash定义到0x0000 0000,会导致系统存储器或者内部SRAM无法重映射到0x0000 0000。

上电启动时系统要默认从0x0000 0000地址读取中断向量表。

stm32中bootloader执行流程

单片机上电后一直到准备好C语言运行环境并跳转到main函数执行总共经历了5个步骤:1.内核初始化,上电取址;

cotexm3会去0地址取出栈指针,然后偏移四个字节取出跳转地址

内核复位和NVIC寄存器部分清零;

内核设置堆栈:内核从向量表0地址读出堆栈地址,并设置主堆栈指针;2.PC指针指向中断向量表的复位中断向量执行复位中断函数;3.在复位中断函数中调用 SystemInit 函数,进行初始化(初始化时钟,配置中断向量表等)4.调用 __main (在

IAR

中是 __iar_program_start )函数完成全局/静态变量的初始化和重定位工作,初始化堆栈和库函数5.跳转到main函数中执行

RTM测量的内容和实现原理

a. 函数开始的地方加入RTM_Start,函数结束的地方加入RTM_Stop,计算两者的时间差,可以测量函数运行时间

b.cpuload统计,主要是创建一个自己的lowprioritytask,确保优先级高于idletask,优先级要低于其他task。主要目的是让cpu空闲的时间就运行lowprioritytask,在lowprioritytask中弄个死循环,死循环中读取硬件systemticks数值和上一次的systemticks比较,

程序简要说明
while(1)
{
disableisr();
readhardware_systemticks(¤tstamp);
    if(currentstamp - laststamp > T)
    {
        我被抢占了,算算其他任务或中断时间累加
    }
    else
    {  
        没被抢占
    }
laststamp = currentstamp;
enableisr();
}

如果差值大于T(被其他任务抢占的临界值),则认为时间差值就是执行了其他高优先级任务或中断的时间,否则时间差值就是死循环执行的时间。过一段时间统计下cpuload了。

3,举个简单例子stack初始化的时候栈的数据都填充为0xCC,每次task调度完成后,去统计下未使用的0xCC的个数,一般从栈顶往栈第统计即可。统计完后可以优化我们栈的大小,一般建议产品栈不超过60%,如果ram足够这个比例可以放的更加小一些。

从浏览器地址栏输入 url 到显示页面的步骤

浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP ,向服务器发起请求;

服务器交给后台处理完成后返回数据,浏览器接收⽂件( HTML、JS、CSS 、图象等);

浏览器对加载到的资源( HTML、JS、CSS 等)进⾏语法解析,建立相应的内部数据结构 (如 HTML 的 DOM);

载⼊解析到的资源⽂件,渲染页面,最终显示。

LINUX命令考察,查询目标文件、滚动查看日志、查看进程

whereis grep

查看进程 ps top kill PID kill -9 PID1 PID2 PID3 ...

cat 命令

用于显示文件内容,可以结合管道命令如 grep 进行过滤。

  • 示例:cat /var/log/syslog | grep error

journalctl 命令

示例:journalctl -xe 查看最近的日志条目。

  • journalctl -u nginx 查看特定服务的日志(如 nginx)。
  • journalctl --since "2023-07-01" --until "2023-07-02" 查看特定时间段的日志

vim模式下/hello<Enter>向下查找hello的字段

:n,$s/name/title/ #替换第 n 行开始到最后一行中每一行的第一个 name 为 title

测试用例的内容

1、测试用例八个基本项是:测试用例编号、测试项目、测试标题、重要级别、预置条件、输入、操作步骤、预期输出

2、(不同公司的测试用例内容不尽相同)下面是更为详尽的测试用例内容:用例编码,用例名称/标题,测试背景,前置条件,优先级,重要级,测试数据,测试步骤,预期结果,实际结果,测试人员,测试时间,备注

给功能去测试,常用的测试方法

黑盒测试法

黑盒测试法也称为功能测试法,它主要从用户角度出发,测试人员只关注软件系统输出结果是否与预期一致。它不需要了解系统内部的实现细节,测试人员只需根据需求规格说明书或需求文档编写符合需求的测试用例并执行即可。

白盒测试法

白盒测试法也叫结构测试法,它主要从程序内部出发,通过检查代码和程序流程来验证功能是否正确。它需要测试人员了解软件系统的内部实现逻辑和代码细节,并编写针对代码的测试用例和覆盖率分析,检测软件系统是否满足指定要求。

边界值测试法

边界值测试法是一种特殊的测试方法。它主要测试系统在极限情况下的响应和表现,即测试边界值处的软件行为是否符合规范。例如,测试一个输入框的最小值和最大值是否能够正确接收和处理,测试登录密码是否符合长度限制等

冒烟测试法

冒烟测试法也称为系统验证测试法,它主要用于确认软件系统在最基本的功能上能够正常工作,是一种快速的初步测试方法。测试人员通过运行系统的核心功能,检查系统是否能够启动、执行基本操作和完成基本任务等。

什么是单元测试

是指对软件中的最小可测试单元进行检查和验证。至于“单元”的大小或范围,并没有一个明确的标准,“单元”可以是一个函数、方法、类、功能模块或者子系统

心跳机制:

就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。

一个驱动简单问题,在已有驱动的情况下,如何添加新的设备(不使用设备树,不重启,不使用应用层工具)

动态创建并注册 platform_device。在驱动中提供添加设备的接口,如 sysfs 接口。驱动内部维护设备实例的管理数据结构。

TCP与UDP的区别(超详细)

在TCP协议进行网络通信时,需要先建立连接,也就是说需要先将客户端与服务器的连接连好,然后在进行数据交互。

TCP是可靠的,UDP是不可靠的

数据包校验(16为数据校验和)防止发送过来的数据是错误数据确认序列号,对失序报文进行重排丢弃重复数据包,防止数据冗余重复确认应答机制,接收方接受数据之后会发送一个确认超时重传机制,发送方发出数据后会启动一个定时器,超过该定时器时间依旧未收到对方确认,便会重新发送该数据流量控制(16位窗口大小)确保接收方收到的数据在自身缓冲区中不会溢出拥塞控制,保证数据在网络中传播的可靠性,降低丢包的概率,提高TCP的可靠性

UDP没有上述TCP机制

并且如果校验和出错,则UDP会将该报文丢弃

TCP面向字节流,UDP面向数据报面向字节流是以字节为单位发送数据,并且一个数据包可以以字节大小来拆分成多个数据包,以方便发送。TCP可以先将数据存放在发送缓冲区中,可以等待数据到一定大小发送,也可以直接发送,没有固定大小可言。UDP需要每次发送都需要发送固定长度的数据包,如果长度过长需要应用层协议主动将其裁剪到适合长度。

TCP只支持点对点通信,UDP支持一对一,一对多,多对多

TCP需要双方建立连接,所以需要点对点通信。

UDP则无需这么复杂

什么时候选TCP or UDP

对某些实时性要求比较高的情况,选择UDP,比如游戏,媒体通信,实时视频流(直播),即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失

#牛客创作赏金赛##晒一晒我的offer##我的实习求职记录##互联网没坑了,还能去哪里?#
秋招嵌入式八股 文章被收录于专栏

心得和八股文(含面试真题) 全部免费

全部评论

相关推荐

不愿透露姓名的神秘牛友
12-13 08:10
OPPO 硬件工程师 年薪总包36.6万
点赞 评论 收藏
分享
评论
4
21
分享
牛客网
牛客企业服务