嵌入式

目录

1、嵌入式c编程基础知识

1.1 C的关键词

关于static:

关于define:

关于const:

关于inline:

关于volatile:

1.2 关于大小端

手写库函数 strcpy,strncpy,memcpy,memset

https://blog.csdn.net/tsh123321/article/details/52263707

 

题目:

 1、在一台64位的机器上,使用32位编译,Garfield 变量占用多少内存空间?64位编译又是如何?

2. 描述下面XXX 这个宏的作用。(总分10分)

1.3 总线回顾

1.3.1 SPI

1.3.2 I2C

1.4 CPU架构(x86与x86_64,Intel与ARM)

1.4.1 RISC与CISC造成的区别

1.5 STM32-ARM知识

1.5.1 stm32启动分析

面试问题:如果单片机启动不了,可能的原因?

1.6 Linux启动过程

1.6.1 BIOS自检

1.6.2 bootloader

1.6.3 系统初始化

2、编程

2.1、输入与输出

2.2、编程题

请写一个函数,将一个16进制字符串转换为数字

3、简述

4、汇编


 


 

嵌入式软件工程师经典笔试题

1、嵌入式c编程基础知识

程序编译时各部分介绍:

动态存储区、静态存储区、堆和栈的区别

空指针和void *类型指针

联合体判断大小端 

1.1 C的关键词

关于static:

修饰函数:使函数只能被其所在的文件访问,其他c文件不能访问static修饰的函数;

修饰变量

  • static修饰的变量会被保存在静态存储区而不是栈中(程序运行在栈中,运行完会被释放);
  • 但static修饰的变量虽然不会被释放,但跟全局 变量不同,static修饰的变量只能在其被定义的作用域内被访问;

关于define:

  • 避免了意义模糊的数字出现,使得程序语义流畅清晰
  • 便于修改函数
  • 提高了程序的执行效率,由于使用了预编译器进行值替代,并不需要为这些常量分配存储空间,所以执行的效率较高。

define 的括号里的参数表示变量

关于const:

  • const修饰的常量具有不可变性
  • 编译器不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高

常量指针和指针常量:

	char *str = "Hello World";
	//定义常量指针,即指针指向的对象是常量
	const char *pstr = str;
	printf("%c\n", *pstr);
	//*pstr = 'S';//error,指针指向的对象不可变
	printf("%c\n", *++pstr);//right,指针本身可变
	//定义指针常量 ,指针是 常量
	char* const ppstr = str;
	//ppstr++;//error
	*ppstr = 'N';//right

关于inline:

参考:inline

简单概括,inline修饰的内联函数在编译器编译时,将原本程序中的函数 调用步骤直接替换成了函数本体,因此减少了原本调用步骤产生的额外开销;但是缺点就是导致了代码膨胀!

关于volatile:

volatile为什么要修饰中断里的变量

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量 

1.2 关于大小端

大端:数据的高位存在内存的低字节,典型的如ARM、PowerPC

小端:数据的低位存在内存的高字节,典型的如Intel

注意:大端小端是字节存储位置的不同,而不是每一个bit不同

例如:a=0x12345678

将a分别在大端处理器和小端处理器中写入内存0x000,那么其存储如下:

内存地址 0x0000 0x0001 0x0002 0x0003
大端 0x78 0x56 0x34 0x12
小端 0x12 0x34 0x56 0x78

那么如果在内存地址0x0000-0x0003中分别存储0x12 0x34 0x56 0x78,

则小端读取得到:0x12345678

而大端读取得到:0x78563412

因为字节序只是对内置的数据类型而言(int、short、double、long....char),而对于char而言由于其本身只有一个字节则字节序和存储模式对其不影响。(因此字符串在跨平台传输时不用考虑字节序

因此网络通讯时常常要将字节序转化成网络字节序(大端)

再举一个例子:

struct stucA{
    unsigned int a:1;
    unsigned int b:2;
    unsigned int c:3;
    unsigned int d:4;
    unsigned int e:5;
    unsigned int f:6;
    unsigned int g:11;
}A;
memset(&A,0,sizeof(A));
A.d=11;

在小端中:a:0,b:00,c:000,d:1101,e,f,g都为0,因为小端中数据低位存在内存低位,因此数据存储(高位地址->低位地址)为:

0000 0000 0000 0000 0000 0010 1100 0000,即使从低位到高位分别为 0xc0,0x02,0x00,0x00;

在大端中:因为数据的高位存在内存的低位,则数据存储(高位地址->低位地址)为:

0000 0011 0100 0000 0000 0000 0000 0000,按照每位数字来看,刚好与小端模式完全相反,但是!,大端中字节的读取方式也是高位数据在低位地址,因此 得到数据(从低位地址到高位地址依次显示)为  0x00 0x00 0x02 0xc0.

可以用以下代码测试:

#include 
#include 
#include 
using namespace std;
struct strA {
	unsigned int a : 1;
	unsigned int b : 2;
	unsigned int c : 3;
	unsigned int d : 4;
	unsigned int e : 5;
	unsigned int f : 6;
	unsigned int g : 11;
};
struct ch {
	char c[4];
};
union test
{
	strA A;
	ch   C;
}T;
int main()
{
	memset(&T, 0, sizeof(T));
	T.A.d = 11;
	for (int i = 0; i < 4; i++)
		printf("%02x\n", (unsigned)(unsigned char)T.C.c[i]);//以16进制输出,不足两位前面补0
	getchar();
}

 

手写库函数 strcpy,strncpy,memcpy,memset

https://blog.csdn.net/tsh123321/article/details/52263707

 

题目:

 1、在一台64位的机器上,使用32位编译,Garfield 变量占用多少内存空间?64位编译又是如何?

struct CAT_s{
int ld;//32
char Color;、、
unsigned short Age;
char *Name;
void(*Jump)(void);
}Garfield;
数据类型 32位编译器/字节 64位编译器/字节 备注
char     1 1 例如:0xff
short 2 2 例如:0xffff
int 4 4 例如:0xffff ffff
long 4 8  
float 4 4  
char* 4 8 实际指向的是一个地址,地址字节数由编译器决定
long long 4 8  
double 8 8  
long double 10/12 10/16 有效字节10位,但 为了对齐实际分配12/16字节

所以使用32位编译器时:

  • 1个int 4字节;
  • char、unsigned shore 共3字节,为了对齐,算4字节;
  • char* 4字节;void * 4字节,

合计16字节

所以使用64位编译器时(8字节/64位对齐):

  • 1个int 4字节,char、unsigned shore 共3字节,为了对齐,合计算8字节;
  • char* 8字节;
  • void * 8字节,

合计24字节

2. 描述下面XXX 这个宏的作用。(总分10分)

 

#define offsetof(TYPE,MEMBER)   ((size_t)&((TYPE*)0)->MEMBER)
#define XXX(ptr,type,member)      ({\
                                 const typeof(((type*)0)->member)*__mptr=(ptr);\
                                 (type*)(char*)__mptr – offsetof(type,member));})offsetof(type,member));})

第一条语句:

#define offsetof(TYPE,MEMBER)   ((size_t)&((TYPE*)0)->MEMBER)

         TYPE代表一个结构体,MEMBER代表结构体成员,因此这条宏定义强行将结构体起始地址定义为0,那么member就代表成员地址的偏移量;

步骤如下:

  • (TYPE*)0  //将0转型为TYPE类型,即TYPE类型首地址为0
  • &((TYPE*)0)->MEMBER//取TYPE类型下MEMBER成员的地址,因为首地址为 0,因此可以看做成员地址的偏移量
  • (size_t)&((TYPE*)0)->MEMBER)//将改地址转型为(size_t)类型

第二条语句:

  • typeof(((type*)0)->member)  //取type类型下成员member的类型,例如:member是char,那么就代表char
  • const typeof(((type*)0)->member)*__mptr=(ptr);//将ptr指向的地址赋值给_mptr,_mptr的类型是const typeof(typeof到底是char,还是其他由member的类型决定!)
  • (type*)(char*)__mptr – offsetof(type,member))//将mptr转化成结构体下成员member的指针,而offsetof()是member的地址偏移量,因此相减得到结构体的起始地址!

 3、在一个多任务嵌入式系统中,有一个CPU 可直接寻址的32位寄存器REGn ,地址为 0x1F000010,编写一个安全的函数,将寄存器REGn 的指定位反转(要求保持其他bit 的值不变)

void bit_reversal(uint32_t nbit)
{
      *((volatial unsigned int *)0x1F000010)^=0x01<

((volatial unsigned int *)0x1F000010)为地址定义,例如(int *)0x1F111111,代表可寻址的地址。

4、 有10000个正整数,每个数的取值范围均在1到1000之间,变成找出从小到大排在第 3400(从0开始算起)的那个数,将此数的值返回,要求不使用排序实现。(总分10分)

输入参数 数组a,数组长度n ,要查找的第index个数;返回:0 -未找到   i-第index数的数值

int fun_find(int *a, int n, int index)
{
	int c = 0;
	int count[1001] = {0};
	for (int i = 0; i < n; i++)
	{
		count[a[i]]++;
	}
	for (int i = 0; i < 1001; i++)
	{
		c += count[i];
		if (c >= index)
			return i;
	}
	return 0;
}

1.3 总线回顾

1.3.1 SPI

接口:SDI、SDO、SCLK、CS

特点:有主从之分、全双工、高速、速度遵从事实标准

面试题之坑:SPI速率是多少?

答:。SPI是一种事实标准,由Motorola开发,并没有一个官方标准。已知的有的器件SPI已达到50Mbps。具体到产品中SPI的速率主要看主从器件SPI控制器的性能限制。

  1. SPI的最大时钟频率
  2. CPU处理SPI数据的能力
  3. 输出端驱动能力(PCB所允许的最大信号传输速率)

1.3.2 I2C

  • 总线:SCL、SDL
  • 传输:按照字节传输,每个字节必须是八位;传输一个字节后主机必须发送一个响应位;先发送高位,即MSB传输
  •  I2C地址:共8位,前四位为每种设备的固定地址,后三位可以由用户自己配置,最后一位为R/W;主地址(4bit)+从地址(3bit)+读写位(R/W)
  • 速率:S(标准模式)测量与控制场合,100kb/s; F(快速模式),速率为 400kb/s;Hs(高速模式),速率为 3.4Mb/s。 

因此最多可以挂载2^7=128个设备,同一种设备最多挂在2^3=8个。I2C传输速率有三个标准!

 

1.4 CPU架构(x86与x86_64,Intel与ARM)

最大的区别:Intel采用小端结构,复杂指令集(CISC);ARM采用大端结构,精简指令集(RISC)

1.4.1 RISC与CISC造成的区别

  1. 指令系统:RISC偏向于处理简单的任务,CISC偏向于处理复杂的任务;在使用RISC的平台上处理复杂任务,效率相对较低
  2. 存储器操作:RISC对存储器操作有限制,使控制简单化;CISC对存储器操作的指令较多,更直接
  3. 程序:RISC的汇编程序较大,尤其是要处理复杂操作的时候;CISC汇编程序较短
  4. 中断:RISC机器在一条指令执行的适当地方可以响应中断;而CISC机器是在一条指令执行结束后响应中断。
  5. CPU:RISCCPU包含有较少的单元电路,因而面积小、功耗低;而CISCCPU包含有丰富的电路单元,因而功能强、面积大、功耗大。
  6. 设计周期:RISC微处理器结构简单,布局紧凑,设计周期短,且易于采用最新技术;CISC微处理器结构复杂,设计周期长。
  7. 用户使用:RISC微处理器结构简单,指令规整,性能容易把握,易学易用;CISC微处理器结构复杂,功能强大,实现特殊功能容易。
  8. 应用范围:由于RISC指令系统的确定与特定的应用领域有关,故RISC机器更适合于专用机;而CISC机器则更适合于通用机。

1.5 STM32-ARM知识

1.5.1 stm32启动分析

      Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。

      因此STM32启动文件,主要做了3个工作:

  • 分配和初始化堆、栈;
  • 定义复位向量并初始化;
  • 中断向量表及其相应的异常处理程序。

其中,复位向量的地址根据BOOT的不同而不同。

启动模式选择引脚

启动模式 说明 地址
BOOT1 BOOT0
X 0 主闪存存储器 主闪存存储器作为启动区域 0x8000000
0 1 系统存储器 系统存储器作为启动区域  
1 1 内置SRAM 内置SRAM作为启动 0x2000000

这篇博文讲的很详细:STM32F407启动流程浅析

启动汇编代码如下:

总的概括起来,stm32启动步骤如下:

  1. 启动文件的汇编代码定义堆栈大小,起始地址(起始地址根据硬件boot配置应该有所不同),例如从flash启动,地址为0x8000000
  2. 执行SystemInit(),配置中断向量表,假如:        0x8000000地址存放的是栈顶地址__initial_sp,0x8000004地址存放的是复位中断向量Reset_Handler(STM32使用32位总线,因此存储空间为4字节对齐)。
  3. 执行main_,该函数属于C/C++库函数,作用是
  • 完成全局/静态变量的初始化工作
  • 初始化堆栈
  • 库函数的初始化
  • 程序的跳转,进入main()函数。
;******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
;* File Name          : startup_stm32f40_41xxx.s
;* Author             : MCD Application Team
;* Version            : V1.3.0
;* Date               : 08-November-2013
;* Description        : STM32F40xxx/41xxx devices vector table for MDK-ARM toolchain.   STM32F40/41XX器件向量表
;*                      This module performs:     stm32启动以后模块执行以下操作
;*                      - Set the initial SP      设置初始化的SP指针
;*                      - Set the initial PC == Reset_Handler  设置初始PC--->指向Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address   设置具有异常ISR地址的向量表条目
;*       - Configure the system clock and the external SRAM mounted on STM324xG-EVAL board to be used as data memory (optional, to be enabled by user)
         配置系统时钟和外部SRAM并挂载到STM324xG-EVAL板用作数据存储器(可选,可由用户设置)
;*                      - Branches to __main in the C library (which eventually  分支跳转到C库中的_main(最终调用main())
;*                        calls main()).
;*                      After Reset the CortexM4 processor is in Thread mode,  复位后CortexM4处理器处于线程模式,
;*                      priority is Privileged, and the Stack is set to Main.  优先级是Privileged,并且Stack被设置为Main。
;* <<< Use Configuration Wizard in Context Menu >>>   
;*******************************************************************************
;
; Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
; You may not use this file except in compliance with the License.
; You may obtain a copy of the License at:
;
;        http://www.st.com/software_license_agreement_liberty_v2
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
;*******************************************************************************

; Amount of memory (in bytes) allocated for Stack   为堆栈分配的内存量(以字节为单位)
; Tailor this value to your application needs       根据您的应用程序需求定制此值
;  Stack Configuration               
;    Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; 

Stack_Size      EQU     0x00000400          设置堆栈大小为0X400(1k)   EQU伪指令,作用是左边的符号名代表右边的表达式
                AREA    STACK, NOINIT, READWRITE, ALIGN=3    ;定义栈段:名称为STACK,未初始化,可读写,ELF 的栈段按2^3=8对齐 
Stack_Mem       SPACE   Stack_Size          分配一片连续的存储区域并初始化为 0,栈空间:0x400个字节 
__initial_sp                                ;栈顶空间地址(低地址)?


;  Heap Configuration                    ;堆定义 
;     Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; 

Heap_Size       EQU     0x00000200         
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base                                ;堆空间起始地址 
Heap_Mem        SPACE   Heap_Size          ;堆空间:0x200个字节
__heap_limit                               ;堆空间结束地址 

                PRESERVE8                   ;PRESERVE8 指令指定当前文件保持堆栈八字节对齐     
                THUMB                       ;告诉汇编器下面是32位的Thumb指令,如果需要汇编器将插入位以保证对齐   


; Vector Table Mapped to Address 0 at Reset  ;中断向量表定义;向量表在复位时映射到地址0
                                              实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表实际起始地址即为0x8000000,映射到0) 
                AREA    RESET, DATA, READONLY ;定义一块数据段,只可读,段名字是RESET 
                EXPORT  __Vectors             ;EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用 
                EXPORT  __Vectors_End         ;在程序中声明一个全局的标号__Vectors_End 
                EXPORT  __Vectors_Size        ;在程序中声明一个全局的标号__Vectors_Size  ;DCD(DCDU)用于分配一片连续的字存储单元并用指定的数据初始化。 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
    假如:        0x8000000地址存放的是栈顶地址__initial_sp,
                0x8000004地址存放的是复位中断向量Reset_Handler(STM32使用32位总线,因此存储空间为4字节对齐)。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++               
大BOSS:向量表 这个向量表的编写是有讲究的,跟硬件一一对应不能乱写的,CPU找入口地址就靠它了,bin文件开头就是他们的地址               
__Vectors       DCD     __initial_sp               ; Top of Stack        ;该处物理地址值存储---栈顶地址
__initial_sp所表示的地址值,即为 __Vetors 标号所表示的值 
                DCD     Reset_Handler              ; Reset Handler
    上电后根据boot引脚来决定PC位置,比如boot设置为flash启动,则启动后PC跳到0x08000000。
    此时CPU会先取2个地址,第一个是栈顶地址,第二个是复位异常地址,故有了上面的写法,这样就跳到reset_handler。
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
    当发生硬件错误中断时,调转到中断错误处理函数--->stm32f4xx_it.c--->
                        void HardFault_Handler(void)   //可以发现这个函数是一个什么也不做的死循环,所以发生硬件
                        {                               //错误时代码会跑死
                            /* Go to infinite loop when Hard Fault exception occurs */
                            while (1)
                            {
                                //CODE可以添加  如果有必要,可以在这种中断处理函数中添加自己的coding
                            }
                        }
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler             ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler                   ; Window WatchDog       ;以下为外部中断向量表                                     
                DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                       
                DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line           
                DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
                DCD     FLASH_IRQHandler                  ; FLASH                                           
                DCD     RCC_IRQHandler                    ; RCC                                             
                DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
                DCD     EXTI1_IRQHandler                  ; EXTI Line1                                             
                DCD     EXTI2_IRQHandler                  ; EXTI Line2                                             
                DCD     EXTI3_IRQHandler                  ; EXTI Line3                                             
                DCD     EXTI4_IRQHandler                  ; EXTI Line4                                             
                DCD     DMA1_Stream0_IRQHandler           ; DMA1 Stream 0                                   
                DCD     DMA1_Stream1_IRQHandler           ; DMA1 Stream 1                                   
                DCD     DMA1_Stream2_IRQHandler           ; DMA1 Stream 2                                   
                DCD     DMA1_Stream3_IRQHandler           ; DMA1 Stream 3                                   
                DCD     DMA1_Stream4_IRQHandler           ; DMA1 Stream 4                                   
                DCD     DMA1_Stream5_IRQHandler           ; DMA1 Stream 5                                   
                DCD     DMA1_Stream6_IRQHandler           ; DMA1 Stream 6                                   
                DCD     ADC_IRQHandler                    ; ADC1, ADC2 and ADC3s                           
                DCD     CAN1_TX_IRQHandler                ; CAN1 TX                                               
                DCD     CAN1_RX0_IRQHandler               ; CAN1 RX0                                               
                DCD     CAN1_RX1_IRQHandler               ; CAN1 RX1                                               
                DCD     CAN1_SCE_IRQHandler               ; CAN1 SCE                                               
                DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s                                   
                DCD     TIM1_BRK_TIM9_IRQHandler          ; TIM1 Break and TIM9                   
                DCD     TIM1_UP_TIM10_IRQHandler          ; TIM1 Update and TIM10                 
                DCD     TIM1_TRG_COM_TIM11_IRQHandler     ; TIM1 Trigger and Commutation and TIM11
                DCD     TIM1_CC_IRQHandler                ; TIM1 Capture Compare                                   
                DCD     TIM2_IRQHandler                   ; TIM2                                           
                DCD     TIM3_IRQHandler                   ; TIM3                                           
                DCD     TIM4_IRQHandler                   ; TIM4                                           
                DCD     I2C1_EV_IRQHandler                ; I2C1 Event                                             
                DCD     I2C1_ER_IRQHandler                ; I2C1 Error                                             
                DCD     I2C2_EV_IRQHandler                ; I2C2 Event                                             
                DCD     I2C2_ER_IRQHandler                ; I2C2 Error                                               
                DCD     SPI1_IRQHandler                   ; SPI1                                           
                DCD     SPI2_IRQHandler                   ; SPI2                                           
                DCD     USART1_IRQHandler                 ; USART1                                         
                DCD     USART2_IRQHandler                 ; USART2                                         
                DCD     USART3_IRQHandler                 ; USART3                                         
                DCD     EXTI15_10_IRQHandler              ; External Line[15:10]s                                 
                DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line                 
                DCD     OTG_FS_WKUP_IRQHandler            ; USB OTG FS Wakeup through EXTI line                       
                DCD     TIM8_BRK_TIM12_IRQHandler         ; TIM8 Break and TIM12                 
                DCD     TIM8_UP_TIM13_IRQHandler          ; TIM8 Update and TIM13                 
                DCD     TIM8_TRG_COM_TIM14_IRQHandler     ; TIM8 Trigger and Commutation and TIM14
                DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare                                   
                DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                           
                DCD     FSMC_IRQHandler                   ; FSMC                                           
                DCD     SDIO_IRQHandler                   ; SDIO                                           
                DCD     TIM5_IRQHandler                   ; TIM5                                           
                DCD     SPI3_IRQHandler                   ; SPI3                                           
                DCD     UART4_IRQHandler                  ; UART4                                           
                DCD     UART5_IRQHandler                  ; UART5                                           
                DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                   
                DCD     TIM7_IRQHandler                   ; TIM7                   
                DCD     DMA2_Stream0_IRQHandler           ; DMA2 Stream 0                                   
                DCD     DMA2_Stream1_IRQHandler           ; DMA2 Stream 1                                   
                DCD     DMA2_Stream2_IRQHandler           ; DMA2 Stream 2                                   
                DCD     DMA2_Stream3_IRQHandler           ; DMA2 Stream 3                                   
                DCD     DMA2_Stream4_IRQHandler           ; DMA2 Stream 4                                   
                DCD     ETH_IRQHandler                    ; Ethernet                                       
                DCD     ETH_WKUP_IRQHandler               ; Ethernet Wakeup through EXTI line                     
                DCD     CAN2_TX_IRQHandler                ; CAN2 TX                                               
                DCD     CAN2_RX0_IRQHandler               ; CAN2 RX0                                               
                DCD     CAN2_RX1_IRQHandler               ; CAN2 RX1                                               
                DCD     CAN2_SCE_IRQHandler               ; CAN2 SCE                                               
                DCD     OTG_FS_IRQHandler                 ; USB OTG FS                                     
                DCD     DMA2_Stream5_IRQHandler           ; DMA2 Stream 5                                   
                DCD     DMA2_Stream6_IRQHandler           ; DMA2 Stream 6                                   
                DCD     DMA2_Stream7_IRQHandler           ; DMA2 Stream 7                                   
                DCD     USART6_IRQHandler                 ; USART6                                           
                DCD     I2C3_EV_IRQHandler                ; I2C3 event                                             
                DCD     I2C3_ER_IRQHandler                ; I2C3 error                                             
                DCD     OTG_HS_EP1_OUT_IRQHandler         ; USB OTG HS End Point 1 Out                     
                DCD     OTG_HS_EP1_IN_IRQHandler          ; USB OTG HS End Point 1 In                       
                DCD     OTG_HS_WKUP_IRQHandler            ; USB OTG HS Wakeup through EXTI                         
                DCD     OTG_HS_IRQHandler                 ; USB OTG HS                                     
                DCD     DCMI_IRQHandler                   ; DCMI                                           
                DCD     CRYP_IRQHandler                   ; CRYP crypto                                     
                DCD     HASH_RNG_IRQHandler               ; Hash and Rng
                DCD     FPU_IRQHandler                    ; FPU

__Vectors_End        ;Vectors结束 

__Vectors_Size  EQU  __Vectors_End - __Vectors      ;得到向量表的大小,304个字节也就是0x130个字节(以上代码累加)  4*(142-66)
                AREA    |.text|, CODE, READONLY     ;定义一个代码段,可读,段名字是.text   
                                                    ;|.text|  用于表示由 C 编译程序产生的代码段,或用于以某种方式与 C 库关联的代码段 

; Reset handler    (复位中断发生以后执行以下过程)    ;利用PROC、ENDP这一对伪指令标记程序开始、结束,把程序段分为若干个过程,
                                                    使程序的结构加清晰 
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]  ;WEAK(弱声明)声明其他的同名标号优先于该标号被引用,
                                                  就是说如果外面声明了的话,调用外面的对应函数 
        IMPORT  SystemInit                ;IMPORT:(导出符号表供外部调用(系统初始化))伪指令用于通知编译器要使用的标号在其他的源文件中定义 
        IMPORT  __main                    ;导出符号表

                     LDR     R0, =SystemInit ---->存储器到寄存器的数据加载 system_stm32f4xx.c 中的void SystemInit(void)
                                            设置微控制器系统初始化嵌入式Flash接口,PLL并更新 SystemFrequency变量。
                     BLX     R0                ;带链接的跳转,同时切换指令集,跳到SystemInit 
                     LDR     R0, =__main    ;系统初始化之后跳转到main函数执行
                     BX      R0             ;切换指令集,main函数不返回跳到__main,进入C的世界 
                     ENDP

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC
                EXPORT  NMI_Handler                [WEAK]  不可屏蔽中断处理函数 
                B       .
                ENDP
HardFault_Handler\             ;\意为换行连接符
                PROC
                EXPORT  HardFault_Handler          [WEAK]  硬件错误处理函数 
                B       .
                ENDP
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler          [WEAK]
                B       .
                ENDP
BusFault_Handler\
                PROC
                EXPORT  BusFault_Handler           [WEAK]
                B       .
                ENDP
UsageFault_Handler\
                PROC
                EXPORT  UsageFault_Handler         [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler                [WEAK]
                B       .
                ENDP
DebugMon_Handler\
                PROC
                EXPORT  DebugMon_Handler           [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler             [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

Default_Handler PROC   (默认的处理函数---->导出符号表)
  ;输出异常向量表标号,方便外部实现异常的具体功能,
  [WEAK]是弱定义的意思,如果外部定义了,优先执行外部定义,否则下面的函数定义(与上面相同,上面为定义,这边为导出)
            EXPORT  WWDG_IRQHandler                   [WEAK]                                       
            EXPORT  PVD_IRQHandler                    [WEAK]                     
            EXPORT  TAMP_STAMP_IRQHandler             [WEAK]         
            EXPORT  RTC_WKUP_IRQHandler               [WEAK]                     
            EXPORT  FLASH_IRQHandler                  [WEAK]                                         
            EXPORT  RCC_IRQHandler                    [WEAK]                                           
            EXPORT  EXTI0_IRQHandler                  [WEAK]                                           
            EXPORT  EXTI1_IRQHandler                  [WEAK]                                             
            EXPORT  EXTI2_IRQHandler                  [WEAK]                                           
            EXPORT  EXTI3_IRQHandler                  [WEAK]                                           
            EXPORT  EXTI4_IRQHandler                  [WEAK]                                           
            EXPORT  DMA1_Stream0_IRQHandler           [WEAK]                               
            EXPORT  DMA1_Stream1_IRQHandler           [WEAK]                                   
            EXPORT  DMA1_Stream2_IRQHandler           [WEAK]                                   
            EXPORT  DMA1_Stream3_IRQHandler           [WEAK]                                   
            EXPORT  DMA1_Stream4_IRQHandler           [WEAK]                                   
            EXPORT  DMA1_Stream5_IRQHandler           [WEAK]                                   
            EXPORT  DMA1_Stream6_IRQHandler           [WEAK]                                   
            EXPORT  ADC_IRQHandler                    [WEAK]                         
            EXPORT  CAN1_TX_IRQHandler                [WEAK]                                               
            EXPORT  CAN1_RX0_IRQHandler               [WEAK]                                               
            EXPORT  CAN1_RX1_IRQHandler               [WEAK]                                               
            EXPORT  CAN1_SCE_IRQHandler               [WEAK]                                               
            EXPORT  EXTI9_5_IRQHandler                [WEAK]                                   
            EXPORT  TIM1_BRK_TIM9_IRQHandler          [WEAK]                 
            EXPORT  TIM1_UP_TIM10_IRQHandler          [WEAK]               
            EXPORT  TIM1_TRG_COM_TIM11_IRQHandler     [WEAK]
            EXPORT  TIM1_CC_IRQHandler                [WEAK]                                   
            EXPORT  TIM2_IRQHandler                   [WEAK]                                           
            EXPORT  TIM3_IRQHandler                   [WEAK]                                           
            EXPORT  TIM4_IRQHandler                   [WEAK]                                           
            EXPORT  I2C1_EV_IRQHandler                [WEAK]                                             
            EXPORT  I2C1_ER_IRQHandler                [WEAK]                                             
            EXPORT  I2C2_EV_IRQHandler                [WEAK]                                           
            EXPORT  I2C2_ER_IRQHandler                [WEAK]                                               
            EXPORT  SPI1_IRQHandler                   [WEAK]                                           
            EXPORT  SPI2_IRQHandler                   [WEAK]                                           
            EXPORT  USART1_IRQHandler                 [WEAK]                                         
            EXPORT  USART2_IRQHandler                 [WEAK]                                         
            EXPORT  USART3_IRQHandler                 [WEAK]                                         
            EXPORT  EXTI15_10_IRQHandler              [WEAK]                                 
            EXPORT  RTC_Alarm_IRQHandler              [WEAK]                 
            EXPORT  OTG_FS_WKUP_IRQHandler            [WEAK]                       
            EXPORT  TIM8_BRK_TIM12_IRQHandler         [WEAK]                 
            EXPORT  TIM8_UP_TIM13_IRQHandler          [WEAK]                 
            EXPORT  TIM8_TRG_COM_TIM14_IRQHandler     [WEAK]
            EXPORT  TIM8_CC_IRQHandler                [WEAK]                                   
            EXPORT  DMA1_Stream7_IRQHandler           [WEAK]                                         
            EXPORT  FSMC_IRQHandler                   [WEAK]                                             
            EXPORT  SDIO_IRQHandler                   [WEAK]                                             
            EXPORT  TIM5_IRQHandler                   [WEAK]                                             
            EXPORT  SPI3_IRQHandler                   [WEAK]                                             
            EXPORT  UART4_IRQHandler                  [WEAK]                                           
            EXPORT  UART5_IRQHandler                  [WEAK]                                           
            EXPORT  TIM6_DAC_IRQHandler               [WEAK]                   
            EXPORT  TIM7_IRQHandler                   [WEAK]                   
            EXPORT  DMA2_Stream0_IRQHandler           [WEAK]                                 
            EXPORT  DMA2_Stream1_IRQHandler           [WEAK]                                   
            EXPORT  DMA2_Stream2_IRQHandler           [WEAK]                                   
            EXPORT  DMA2_Stream3_IRQHandler           [WEAK]                                   
            EXPORT  DMA2_Stream4_IRQHandler           [WEAK]                                 
            EXPORT  ETH_IRQHandler                    [WEAK]                                         
            EXPORT  ETH_WKUP_IRQHandler               [WEAK]                     
            EXPORT  CAN2_TX_IRQHandler                [WEAK]                                               
            EXPORT  CAN2_RX0_IRQHandler               [WEAK]                                               
            EXPORT  CAN2_RX1_IRQHandler               [WEAK]                                               
            EXPORT  CAN2_SCE_IRQHandler               [WEAK]                                               
            EXPORT  OTG_FS_IRQHandler                 [WEAK]                                       
            EXPORT  DMA2_Stream5_IRQHandler           [WEAK]                                   
            EXPORT  DMA2_Stream6_IRQHandler           [WEAK]                                   
            EXPORT  DMA2_Stream7_IRQHandler           [WEAK]                                   
            EXPORT  USART6_IRQHandler                 [WEAK]                                           
            EXPORT  I2C3_EV_IRQHandler                [WEAK]                                             
            EXPORT  I2C3_ER_IRQHandler                [WEAK]                                             
            EXPORT  OTG_HS_EP1_OUT_IRQHandler         [WEAK]                     
            EXPORT  OTG_HS_EP1_IN_IRQHandler          [WEAK]                     
            EXPORT  OTG_HS_WKUP_IRQHandler            [WEAK]                       
            EXPORT  OTG_HS_IRQHandler                 [WEAK]                                     
            EXPORT  DCMI_IRQHandler                   [WEAK]                                             
            EXPORT  CRYP_IRQHandler                   [WEAK]                                     
            EXPORT  HASH_RNG_IRQHandler               [WEAK]
            EXPORT  FPU_IRQHandler                    [WEAK]
以下为只是定义而没有实现的空函数 
WWDG_IRQHandler                                                       
PVD_IRQHandler                                     
TAMP_STAMP_IRQHandler                 
RTC_WKUP_IRQHandler                               
FLASH_IRQHandler                                                       
RCC_IRQHandler                                                           
EXTI0_IRQHandler                                                         
EXTI1_IRQHandler                                                           
EXTI2_IRQHandler                                                         
EXTI3_IRQHandler                                                         
EXTI4_IRQHandler                                                         
DMA1_Stream0_IRQHandler                                       
DMA1_Stream1_IRQHandler                                         
DMA1_Stream2_IRQHandler                                         
DMA1_Stream3_IRQHandler                                         
DMA1_Stream4_IRQHandler                                         
DMA1_Stream5_IRQHandler                                         
DMA1_Stream6_IRQHandler                                         
ADC_IRQHandler                                         
CAN1_TX_IRQHandler                                                           
CAN1_RX0_IRQHandler                                                         
CAN1_RX1_IRQHandler                                                           
CAN1_SCE_IRQHandler                                                           
EXTI9_5_IRQHandler                                               
TIM1_BRK_TIM9_IRQHandler                       
TIM1_UP_TIM10_IRQHandler                     
TIM1_TRG_COM_TIM11_IRQHandler 
TIM1_CC_IRQHandler                                               
TIM2_IRQHandler                                                           
TIM3_IRQHandler                                                           
TIM4_IRQHandler                                                           
I2C1_EV_IRQHandler                                                         
I2C1_ER_IRQHandler                                                         
I2C2_EV_IRQHandler                                                       
I2C2_ER_IRQHandler                                                           
SPI1_IRQHandler                                                         
SPI2_IRQHandler                                                           
USART1_IRQHandler                                                       
USART2_IRQHandler                                                       
USART3_IRQHandler                                                     
EXTI15_10_IRQHandler                                           
RTC_Alarm_IRQHandler                           
OTG_FS_WKUP_IRQHandler                               
TIM8_BRK_TIM12_IRQHandler                     
TIM8_UP_TIM13_IRQHandler                       
TIM8_TRG_COM_TIM14_IRQHandler 
TIM8_CC_IRQHandler                                               
DMA1_Stream7_IRQHandler                                                 
FSMC_IRQHandler                                                           
SDIO_IRQHandler                                                           
TIM5_IRQHandler                                                           
SPI3_IRQHandler                                                           
UART4_IRQHandler                                                         
UART5_IRQHandler                                                         
TIM6_DAC_IRQHandler                           
TIM7_IRQHandler                             
DMA2_Stream0_IRQHandler                                         
DMA2_Stream1_IRQHandler                                         
DMA2_Stream2_IRQHandler                                           
DMA2_Stream3_IRQHandler                                           
DMA2_Stream4_IRQHandler                                       
ETH_IRQHandler                                                         
ETH_WKUP_IRQHandler                               
CAN2_TX_IRQHandler                                                           
CAN2_RX0_IRQHandler                                                         
CAN2_RX1_IRQHandler                                                         
CAN2_SCE_IRQHandler                                                         
OTG_FS_IRQHandler                                                   
DMA2_Stream5_IRQHandler                                         
DMA2_Stream6_IRQHandler                                         
DMA2_Stream7_IRQHandler                                         
USART6_IRQHandler                                                       
I2C3_EV_IRQHandler                                                         
I2C3_ER_IRQHandler                                                         
OTG_HS_EP1_OUT_IRQHandler                           
OTG_HS_EP1_IN_IRQHandler                           
OTG_HS_WKUP_IRQHandler                               
OTG_HS_IRQHandler                                                   
DCMI_IRQHandler                                                           
CRYP_IRQHandler                                                   
HASH_RNG_IRQHandler
FPU_IRQHandler

                B       .

                ENDP

                ALIGN       ;默认是字对齐方式,也说明了代码是4字节对齐的 

;*******************************************************************************
; User Stack and Heap initialization   用户堆栈初始化 
;*******************************************************************************
                 IF      :DEF:__MICROLIB     ;判断是否使用DEF:__MICROLIB(micro lib),如果勾选了micro lib 

                 EXPORT  __initial_sp
                 EXPORT  __heap_base
                 EXPORT  __heap_limit

                 ELSE                              ;如果没有勾选micro lib 

                 IMPORT  __use_two_region_memory    ;两区堆栈空间,堆和栈有各自的空间地址 
                 EXPORT  __user_initial_stackheap

__user_initial_stackheap
                      ;标号__user_initial_stackheap,表示用户堆栈初始化程序入口 
                      ;此处是初始化两区的堆栈空间,堆是从由低到高的增长,栈是由高向低生长的,
                      两个是互相独立的数据段,并不能交叉使用。 

                 LDR     R0, =  Heap_Mem               ;保存堆起始地址 
                 LDR     R1, =(Stack_Mem + Stack_Size)  ;保存栈结束地址
                 LDR     R2, = (Heap_Mem +  Heap_Size)  ;保存堆结束地址
                 LDR     R3, = Stack_Mem                ;保存栈起始地址
                 BX      LR

                 ALIGN

                 ENDIF

面试问题:如果单片机启动不了,可能的原因?

答:

  1. 检查Vcc和GND
  2. 检查晶振
  3. 检查RESER脚电平
  4. 检查程序是从Flash启动还是外部ROM启动
  5. 检查调试程序问题(看门狗等问题)

1.6 Linux启动过程

参考文章:https://blog.csdn.net/u014379540/article/details/52243187

https://www.cnblogs.com/bluestorm/p/5981435.html

Linux启动过程可以简单由下图描述:

嵌入式_第1张图片

1.6.1 BIOS自检

BIOS(basic Input/Output System),是计算机操作系统输入输出管理的一部分,目前大多存储与板上Flash-EEPROM上,里面内容可升级

BIOS分为两部分:

  • POST(Power On Self Test)上电自检程序,检测外围设备是否存在问题;
  • 启动Running time服务:Running time服务会自动搜索处于激活状态的或者是可引导的程序,搜索顺序由CMOS决定(即BIOS中的设置),一般从硬盘启动的话,会读取硬盘上第一个扇区MBR(master boot recrd),即主引导记录.MBR中存储了bootloader;
  • MBR装入RAM中后,操作权被交给MBR,接下来就是bootloader的任务啦

1.6.2 bootloader

bootloader分为stag1stag2两个阶段.

stag1:

  1. 初始化硬件设备(复位,设置CPU为超级保护模式,屏蔽看门狗,初始化内存控制器,...初始化串口打印信息...)
  2. 代码重定位,为加载stag2分配RAM空间(代码重定位主要检查自己是否在内存中。如果是跳到堆栈段(stack_setup代码段)设置堆栈,不是就加载自己到RAM空间。)
  3. 加载stag2到RAM
  4. 设置堆栈跳转到第二段代码入口 

stag2:

  1. 初始化本阶段要使用到的硬件设备
  2. 检测系统内存映射(所谓内存映射就是指在整个4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的RAM 单元。个人觉得是因为有一段地址用于DMA直接寻址,不经过cpu的mmu单元)
  3. 加载内核映像和根文件系统映像
  4. 设置内核的启动参数
  5. 启动内核

1.6.3 系统初始化

init进程起来后,系统启动的控制权移交给init进程。
/sbin/init进程是所有进程的父进程,当init起来之后,它首先会读取配置文件/etc/inittab,进行以下工作:
1)执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,到此系统基本算运行起来了,后面需要进行运行级别的确定及相应服务的启动;
2)确定启动后进入的运行级别;
3) 执行/etc/rc.d/rc,该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/rcn.d(n=0~6)目录下,所有的文件均链接至/etc/init.d下的相应文件。
4)有关key sequence的设置
5) 有关UPS的脚本定义
6)启动虚拟终端/sbin/mingetty
7)在运行级别5上运行X
这时呈现给用户的就是最终的登录界面。
至此,系统启动过程完毕:)

2、编程

2.1、输入与输出

输出各种进制:

int m = 255;
printf("m的十六进制:%x\n", m);
printf("m的十进制:  %d\n", m);
printf("m的八进制:  %o\n", m);
m的十六进制:ff
m的十进制:  255
m的八进制:  377

如果输入包含空格,例如输入“how are you”,用gets代替scanf;

字符串操作:

头文件string.h

内存分配:

头文件 malloc.h

算法:

2.2、编程题

请写一个函数,将一个16进制字符串转换为数字

#include 
#include 
int hextoint(char c)
{
	if (c >= 'a'&&c <= 'z')
		return (int)(c - 'a' + 10);
	else if (c >= 'A'&&c <= 'Z')
		return (int)(c - 'A' + 10);
	else if (c >= '0'&&c <= '9')
		return (int)(c - '0' + 0);
	else return 0xffffffff;//错误
}
int stringtoint(char* a)
{
	int sum = 0;
	int n = strlen(a);
	for (int i = 0; i 

或者更简单的方法:

#include 
#include 
using namespace std;
int main()
{
	int t;
	while (cin >> hex >>t)
		cout << t << endl;
	return 0;
}

3、简述

 

3.1. 简述处理器中断处理的过程(中断向量、中断保护现场、中断嵌套、中断返回等)。

中断向量:中断服务程序的入口地址。作用是:请求中断
当某一中断源需要CPU为其进行中断服务时,就输出中断请求信号,使中断控制系统的中断请求触发器置位,向CPU请求中断。系统要求中断请求信号一直保持到CPU对其进行中断响应为止。
中断响应:
CPU对系统内部中断源提出的中断请求必须响应,而且自动取得中断服务子程序的入口地址(入口地址一般存储在中断向量地址上),执行中断 服务子程序。对于外部中断,CPU在执行当前指令的最后一个时钟周期去查询INTR引脚,若查询到中断请求信号有效,同时在系统开中断(即IF=1)的情 况下,CPU向发出中断请求的外设回送一个低电平有效的中断应答信号,作为对中断请求INTR的应答,系统自动进入中断响应周期。
保护现场:
主程序和中断服务子程序都要使用CPU内部寄存器等资源,为使中断处理程序不破坏主程序中寄存器的内容,应先将断点处各寄存器的内容压入堆栈保护起来,再进入的中断处理。现场保护是由用户使用PUSH指令来实现的。
中断服务:
中断服务是执行中断的主体部分,不同的中断请求,有各自不同的中断服务内容,需要根据中断源所要完成的功能,事先编写相应的中断服务子程序存入内存,等待中断请求响应后调用执行。
恢复现场
当中断处理完毕后,用户通过POP指令将保存在堆栈中的各个寄存器的内容弹出,即恢复主程序断点处寄存器的原值。
中断返回
在中断服务子程序的最后要安排一条中断返回指令IRET,执行该指令,系统自动将堆栈内保存的 IP/EIP和CS值弹出,从而恢复主程序断点处的地址值,同时还自动恢复标志寄存器FR或EFR的内容,使CPU转到被中断的程序中继续执行
中断嵌套
是指中断系统正在执行一个中断服务时,有另一个优先级更高的中断提出中断请求,这时会暂时终止当前正在执行的级别较低的中断源的服务程序,去处理级别更高的中断源,待处理完毕,再返回到被中断了的中断服务程序继续执行,这个过程就是中断嵌套。

2. 简述处理器在读内存的过程中,CPU 核、cache 、MMU 如何协同工作?画出CPU 核、 cache 、MMU(内存管理单元) 、内存之间的关系示意图加以说明(可以以你熟悉的处理器为例)。(总分10分)

 

3、请说明总线接口USRT 、I2C 、USB 的异同点(串/并、速度、全/半双工、总线拓扑等)

嵌入式_第2张图片

4、汇编

 

【C语言】编译链接的详细过程

程序编译,链接过程

 

 

 

 

 

你可能感兴趣的:(嵌入式/RTOS,秋招面试技术总结)