精华内容
下载资源
问答
  • 一般来说,神经网络的架构可以分为类?   https://www.toutiao.com/a6636224355548267015/   什么是神经网络 神经网络是机器学习中的一种模型,是一种模仿动物神经网络行为特征,进行分布式并行信息处理...

    一般来说,神经网络的架构可以分为哪三类?

     

    https://www.toutiao.com/a6636224355548267015/

     

    什么是神经网络

    神经网络是机器学习中的一种模型,是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。

    一般来说,神经网络的架构可以分为三类:

    前馈神经网络:

    这是实际应用中最常见的神经网络类型。第一层是输入,最后一层是输出。如果有多个隐藏层,我们称之为“深度”神经网络。他们计算出一系列改变样本相似性的变换。各层神经元的活动是前一层活动的非线性函数。

    循环网络:

    循环网络在他们的连接图中定向了循环,这意味着你可以按照箭头回到你开始的地方。他们可以有复杂的动态,使其很难训练。他们更具有生物真实性。

    循环网络的目的使用来处理序列数据。在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能无力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的。

    循环神经网路,即一个序列当前的输出与前面的输出也有关。具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再无连接而是有连接的,并且隐藏层的输入不仅包括输入层的输出还包括上一时刻隐藏层的输出。

    对称连接网络:

    对称连接网络有点像循环网络,但是单元之间的连接是对称的(它们在两个方向上权重相同)。比起循环网络,对称连接网络更容易分析。这个网络中有更多的限制,因为它们遵守能量函数定律。没有隐藏单元的对称连接网络被称为“Hopfield 网络”。有隐藏单元的对称连接的网络被称为玻尔兹曼机。

     

     

     

    展开全文
  • 嵌入式系统三级考试终结版2019.3

    万次阅读 2019-03-28 15:25:59
    嵌入式系统上的软件具有结构精简,代码轻量化,占用存储资源少的特点。...按照软硬件技术的复杂程度进行分类,可以把嵌入式系统分为:高端系统、终端系统和低端系统三大类。 仿真平台指嵌入式系统开发中使用的虚拟...

    总结得很晚,很着急,前面是一些知识点(很偏的可能没有),后面是一部分错题知识点,全部掌握,不能保证优秀,良好还是可以的,加油吧,祝我和大家好运!
    命是弱者的借口,运是强者的谦词!

    嵌入式系统上的软件具有结构精简,代码轻量化,占用存储资源少的特点。
    嵌入式系统和计算机操作系统的共同特征是:引导加载程序、外设驱动程序、操作系统、文件系统、网络协议栈、图形用户界面、数据库
    嵌入式系统应用开发工具的主要目的:提高开发质量,缩短开发周期,降低开发成本

    按照软硬件技术的复杂程度进行分类,可以把嵌入式系统分为:高端系统、终端系统和低端系统三大类。

    仿真平台指嵌入式系统开发中使用的虚拟机管理软件、仿真软件或者指令集模式器
    对应内存容量而言1KB = 1024B,对应外存(磁盘、U盘)等容量而言,1KB=1000B
    OS装载方式:串口、以太网和USB装载
    嵌入式应用程序经过交叉工具链生成映像文件后,需要下载到目标机进行调试。
    调试完毕后映像文件必须有专用工具烧写到ROM中去,这种烧写工具俗称编程器!

    文本根据排版格式可分为:纯文本和丰富文本。windows环境下,txt就是纯文本。相对于线性文本,超文本按着网状结构组织信息。WWW网页是最为常见超文本

    当前速度最快的CPU已经超过10GHz

    嵌套向量中断控制器缩写为NVIC,向量中断控制器缩写为VIC
    GCC是GNU套件的编译链接器,能编译C语言,汇编语言。
    GDB调试下,file命令是装入需要调试的可执行文件,run命令执行当前被调试的程序。
    源文件到可执行文件的步骤:预处理->编译->汇编->连接。

    前向通道 - 输入接口,A/D
    后向通道 - 输出接口,D/A
    AX88796芯片内部寄存器的地址范围:0x10000000 ~ 0x100003FF

    嵌入式系统硬件的逻辑组成
    硬件主体中央处理器和存储器,他们通过IO接口或者IO设备与外部世界联系,并借助总线相互连接
    中央处理器主要由**运算器、控制器、寄存器和高速缓冲区(cache)**组成

    嵌入式系统的特点
    专用型
    隐蔽型
    资源受限
    高可靠性
    软件固化
    实时性

    嵌入式系统的CPU特点
    实时处理
    低功耗
    结构特拓展性
    集成了测试电路
    4、8、16、32位字长

    CPU
    嵌入式系统的CPU主要使用的有DSP、RAM以及FPGA。
    FPGA(Field-Programmable Gate Array)即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。
    DSP介绍
    适用于数字信号处理的微处理器(DSP并非高性能通用处理器,它是一种专用于数字信号处理的微处理器)
    支持单指令多数据(SIMD)并行处理的指令
    显著提高音频、视频等数字信号的数据处理效率
    手机和数码产品均有DSP

    嵌入式开发流程
    需求分析和规格说明 -> 系统设计 -> 构件设计 -> 系统集成与测试
    测试的目的是验证模块/系统的功能和性能,以及时发现错误
    基于嵌入式WEB的应用系统中,构件设计阶段需要设计支持以太网通信的电路,包括以太网控制电路和以太网驱动电路

    嵌入式开发特点
    宿主机 - 目标机的开发架构
    与底层硬件控制程序的关系密切
    软硬件资源受限制
    需要固化程序
    嵌入式系统开发调试工具

    在线仿真器
    JTAG适配器
    示波器
    GPIO

    GPIO引脚一般是多功能复用的,具有0态,1态和高阻态。
    作为输入接口时一般具有缓冲功能,作为输出接口时一般具有锁存功能
    GPIO可以实现并行 IO,SPI、UART、I2C都是串行。

    UART

    UART由发生器、接收器、控制单元以及波特率发生器等组成。可实现全双工通信!
    ARM芯片中的UART收发信息时,可以采用FIFO,也可以采用普通模式
    一般接收和发送缓冲区的FIFO字节数一样的,长度可编程选择4B、8B、16B、64B
    UART传送消息的格式是以起始位开始以停止位结束
    UART传送信息时,一次可传输的数据位可以是5,6,7,8位,由编程决定
    基于UART可组成RS-232接口
    RS232 - 最远15m
    RS485 - 最远1.2k

    ARM实现485总线的功能,需要采用S3C2410芯片内部的UART部件外加转换芯片等来实现。在软件设计时,初始化波特率9600bps,数据格式格式为:8位数据位,无数据检验位,1位停止位。那么1s时间内最多传输960个字节。(注意计算还得加上起始位和停止位)

    CAN即: 控制器局域网,能够实现多主通信

    CAN总线的数据帧由7个不同的域组成,其中域的长度可以是0~8位
    采用CRC校验,RAM芯片内部嵌入CAN控制器

    键盘
    8个GPIO脚最多构成64个按键的键盘

    矩阵键盘通常有行扫描法和反转法读取按键的特征值(还有一种方法叫做中断方式)

    嵌入式处理器内核的分类
    按照字长可以分为:8/16/32/64 位结构
    按照存储可以分为:冯诺依曼和哈佛(程序和数据分开存储)结构
    按照指令集可以分为:CISC、 RISC结构
    CISC(complex instruction set computer 复杂指令集)
    RISC(reduced instruction set computer 精简指令集)

    SOC片上系统
    SOC已成为嵌入式处理器芯片的主流发展趋势
    它是集成电路进入深亚微米时代的产物
    既能把数字电路也能把模拟电路集成到单个芯片上
    包含数字电路、模拟电路以及射频电路
    单个芯片即可完成采集、转换、存储、处理和I/O等多种功能
    SOC有通用SOC芯片和专用SOC芯片之分
    专用SOC芯片按其工艺分为定制芯片和现场可编程芯片两类

    集成电路
    集成电路有小规模(SSI)、中规模(MSI)、大规模(LSI)、超大规模(VLSI)和极大规模(ULSI)组成,嵌入式处理芯片一般属于VLSI和USLI。
    集成电路大多是在硅衬底上制作,硅衬底是单晶硅锭经切割,研磨和抛光而成的圆形薄片。
    集成电路中的电路及电子元件,需要反复交叉氧化、光刻、掺杂和互连等工序才能制成。

    嵌入式最小系统组成
    嵌入式系统一般包括嵌入式处理器、时钟电路、电源电路、复位电路、存储器和调试测试接口。

    JTAG调试技术
    JTAG标准中规定的TAP接口具有5根信号线

    构建一个宿主机 - 目标机的开发环境,若目标机是裸机,那么为了调试和下载软件需要将调试仿真器连接到目标机的JTAG接口!

    JATG是一种嵌入式测试技术,大多数嵌入式CPU、DSP、FPGA器件都支持JTAG
    JTAG允许多个芯片的边界扫描寄存器BSR通过JTAG接口串联在一起,实现对多个器件的测试
    通过JTAG可以实现在线编程功能

    主频时钟
    0.01s基准定时时间选用S3C2410芯片内部的Timer0部件产生。若系统的主频参数PCLK=264MHz,分频器选择16,预分频系数选择为3,那么,Timer0的计数常数为:41250
    计算方法:定时器输入时钟频率 = PCLK/(预分频系数+1)/(分割器值),计数常数 = 定时间间隔/(1/定时器输入时钟频率)
    带宽 = 总线频率 × 数据线宽度 / 8 × 次数 / 周期

    板级升级包(BSP)引导加载程序、初始化程序、设备驱动程序、配置文件
    含有电路板的初始化程序
    所有与特定电路板上硬件相关的功能都集成在板级支持包的库里
    操作系统的上层代码通过板级支持包访问底层硬件

    ARM

    单指令周期和流水线技术是ARM处理器的技术特征。
    ARM都是RISC,但是存储结构有的是哈佛结构,有的是冯诺依曼结构。
    PowerPC、MC68K、MIPS都是RISC,哈佛结构!
    Cortex 系列分为A-R-M ,A系列是面向尖端虚拟内存的操作系统和用户应用,R系列是针对实时系统,M系列是对微控制器。 Cortex - M3系列是哈佛结构。
    ARM内部一般有:UART/I2C/SPI/CAN/USB/Ethernet等多个互连通信组件
    ARM处理器共37个,包括31个通用寄存器(含PC)和6个状态寄存器

    ARM异常
    将CPRS的值保存到将要执行的异常中断对应的SPSR中
    设置CPSR的相应位
    断点地址保存到R14
    PC赋值,转入向量地址

    ADS
    按照存储区域类型划分为3类,RO段,RW段,ZI段,RO段是指代码存储区和常数存储区,具有只读属性
    可执行输出文件有3个生成目标:Debug、Release、DEbugRel
    工程项目按照一定的逻辑来分组管理文件:
    文件映射关系较简单时:使用编译、链接选项来确定输入文件的连接关系
    地址映射关系较复杂时:使用scatter(分散加载)格式的文件来确定输入文件的连接关系

    RVDS
    RVDS开发工具套件中,主要包括工程管理器、编译连接器、调试器和指令集仿真器。调试器支持硬件在线调试和软件仿真调试。

    电源管理模块
    正常模式-正常模式下,电源管理模式为内核及RAM芯片内部所有硬件组成提供时钟源,用户可以通过软件控制暂时不用的内置硬件组件处于关闭状态降低功耗。
    慢速模式
    休眠模式 - 仅断开RAM内核时钟FCLK,CPU处于休眠模式,仍为外围硬件组件提供时钟。
    掉电模式 - 切断内部电源,除非唤醒逻辑有效,否则内核不产生功耗

    硬件抽象层HAL
    操作系统内核提供了访问硬件底层的函数接口
    嵌入式软件中直接访问底层硬件的例程集合
    增加的HAL位于硬件电路板和操作系统内核之间
    嵌入式电路板的最基本软件
    HAL函数是移植操作系统的基础
    HAL隐藏了不同硬件平台的差异性,从而改善了操作系统的可移植性!

    AMBA总线
    ARM的总线结构成为 AMBA -先进微控制器总线结构(一种开放式总线结构)
    从1995的AMBA1.0到目前的AMBA4.0共四个版本!
    ARM7 - AMBA1; ARM11 - AMBA2
    按照AMBA总线规范,基于ARM内核的嵌入式处理芯片采用系统总线和外围总线两层结构的方式构建片上系统
    连接系统总线的**高带宽组件(AHB接口)**主要包括:电源管理和时钟控制器,测试接口(JTAG),外部存储器控制接口,DMA控制器,USB主机,中断控制器。(可以看出大多数为控制器)
    RTC是与外围总线(APB接口)连接的硬件组件

    MMU
    MMU,内存管理单元,它是用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权。
    虚拟地址到物理地址的转换通过查找页表来完成,每次在访问内存时先插TLB,查不到再到内存中查整个页表。

    ARM7 ≠ ARMv7
    RAM7 - 冯诺依曼的结构。 RAM9~RAM11 采用哈佛结构!
    ARMv7是一种构架。ARM7是一种处理器型号ARM7(冯诺依曼结构)是在ARMv4构架上设计出来的处理器RAM11(ARMv6架构)之后便是以Cortex(ARMv7架构)来命名了!

    ARM7没有MMU(内存管理单元),只能叫做MCU(微控制器),不能运行诸如Linux、WinCE(大型嵌入式操作系统)等这些现代的多用户多进程操作系统,因为运行这些系统需要MMU,才能给每个用户进程分配进程自己独立的地址空间。ucOS、ucLinux这些精简实时的RTOS不需要MMU,当然可以在ARM7上运行。

    ARM9、ARM11,是嵌入式CPU(处理器),带有MMU,可以运行诸如Linux等多用户多进程的操作系统,应用场合也不同于ARM7。
    此外,Cortex-M系列还细分为M0、M3、M4和超低功耗的M0+,用户依据成本、性能、功耗等因素来选择芯片。
    Cortex-M系列(ARMv7架构)的指令集只有Thumb-2。
    ARM处理器 ≠ ARM处理器核

    处理器核:在某种架构的基础上具有取指令和执行指令的组件。
    处理器: 以处理器核为中心,加上MMU,中断控制器,浮点运算器,总线接口等就构成了ARM处理器。
    当然了,单独的处理器核也可以作为某一代ARM处理器的。

    ARM常考寄存器
    R13 - SP (堆栈指针)
    R14 - LR(链接寄存器)
    R15 - PC(程序计数器)
    xPSR - (CPSR 和 SPSR)状态寄存器

    SP寄存器
    SP有两个,分别为R13(MSP)和R13(PSP),即主堆栈指针(MSP)和进程堆栈指针(PSP),但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。这些寄存器都是32位的。

    CPSR寄存器
    CPSR(当前程序状态寄存器)在任何处理器模式下被访问。它包含了条件标志位、中断禁止位、当前处理器模式标志以及其他的一些控制和状态位。
    ARM中表示程序状态的寄存器是CPSR,其中状态位T的作用是在ARM状态与Thumb状态间进行切换,当T = 1时处理器处于的状态是Thumb状态
    N为符号标志位 - N=1表示运算结果为负,否则运算结果为正
    F为禁止快读中断为 - F=1表示禁止快速中断控制位,否则允许!
    V为溢出标志位,等于1表示溢出
    Z为全0标志,运算结果为0

    SPSR寄存器
    每一种处理器模式下(看下面的其中运行模式)都有一个专用的物理状态寄存器,称为SPSR(备份程序状态寄存器)
    当特定的异常中断发生时,这个寄存器用于存放当前程序状态寄存器的内容。在异常中断退出时,可以用SPSR来恢复CPSR。
    由于用户模式和系统模式不是异常中断模式,所以他没有SPSR。当用户在用户模式或系统模式访问SPSR,将产生不可预知的后果

    控制寄存器和数据寄存器
    控制寄存器是4个字节,比如端口E的控制寄存器rGPECON = 0x00005555
    数据寄存器是2个字节,比如端口E的数据寄存器rGPEDAT=0x0020
    关于赋值,也写一个小例子
    rGPDCON = ((rGPDCON | 0x00005555) & 0xFFFF5555);//GPD0~GPD7配置为输出模式1先置位,然后再清零。

    ARM微处理器的七种运行模式
    用户模式:user (没有SPSR寄存器):正常程序执行的模式
    系统模式 – SYS (没有SPSR寄存器): 用于运行特权级的操作系统任务
    快速中断模式 – FIQ :用于高速数据传输和通道处理、高速中断!
    外部中断模式 – IRQ :用于通常的中断处理
    管理模式 – SVC :又称特权模式,操作系统使用的一种保护模式
    终止模式 – ABT :用于虚拟存储及存储保护,处理存储器故障
    未定义指令模式 – UND :用于支持通过软件方针硬件的协处理器

    经典RAM的七种异常
    复位RESET
    未定义指令 UND
    软件中断 SWI
    指令预取终止 PABT
    数据访问终止 DABT
    外部中断请求 IRQ
    快速中断FIQ

    IRQ外部中断
    IRQ异常对应的异常向量地址为:0x00000018
    IRQ异常向量地址和下一个异常向量地址之间的间隔为4个字节
    复位异常的异常向量地址是0x00000000。系统上电复位后,将从该地址处执行程序,RAM9的体系结构规定的各异常向量地址间隔通常是4个字节,以此复位异常向量地址处通常存储一条分支指令

    S3C2410必备知识
    S3C2410拥有2个串口,UART0/UART1
    控制组件包括存储器控制器、总线控制器、外部主控器、NAND FLASH(以页为单位进行闪存)
    存储器控制器提供访问外部存储器所需的存储器控制信号,支持大小端模式,地址空间供1GB,8个BANK,每个BANK128MB
    以ARM芯片为信合的嵌入式系统其I/O与存储器采用统一编址的方式,并不像×86那样采用I/O映射编址(独立编址)
    只有BANK0是总线16、32位的访问,其他BANK均可以进行8、16、32位的访问
    GPIO 有GPIOA~H
    哈佛体系结构,数据与程序存储分开
    内部集成ADC

    矩阵按键代码

    #define KEYOUTPUT (*(VOLATILE int8u *)0X56000044)
    #define KEYINPUT (*(VOLATILE int8u *)0X56000044)
    
    INT16U ScanKey()
    {
        INT16U key = 0xFFFF;
        INT16U i;
        INT8U temp=0xFF, output;
        rGPECON = ((rGPECON & 0xFFFFFF00) | 0x00000055); //初始化GPE0~GPE3为输出
        rGPECON = rGPECON & 0xFFFFFF0F; //初始化GPE4~GPE7为输入
    
        //判断键盘中是否有键按下
        for(i=1; ((i<=8) && (i>0)); i<<=1)
        {
            output |= 0xFF;
            output &= (~i);
            KEYOUTPUT = output;
            temp = KEYINPUT;
            if((temp & 0xF0) != 0xF0)//判断列信号是否全部为1
            {
                key = (~i);
                key <<= 8;
                key |= ((temp & 0xF0)|0x0F);
                return key;
            }
        }
        return 0xFFFF;
    }
    

    //key返回判断哪个按键的方法:最高4位和最低四位都是1,
    //即 1111 ---- ---- 1111,然后次高字节是行,再次高是列,
    //比如第2行第3个按键按下, 对应为 1111 1101 1011 1111 - 0xFDBF

    网络

    WLAN通信协议是802.11,传输速率可达到11Mbps,54Mbps,108Mbps。

    IP
    IP地址分为A类、B类、C类三个基本类。另外两类分别为组播地址和备用地址。
    IP地址解决了网络中所有计算机统一编址的问题
    IP数据包是一种独立于各种物理网络的数据包格式
    路由器是实现网络与网络互连的关键设备

    A类
    1.0.0.0 到126.255.255.255
    分配给具有大量主机而局域网络数量较少的大型网络
    由1个字节的网络地址和3个字节主机地址组成
    网络地址的最高位必须是“0”,即第一字段的范围 0127,但是由于全0和全1的地址用作特殊用途,实际可指派的第一个字段范围是1126
    每个IP地址可连16387064台主机,Internet有126个A类地址
    可以用于多目的地址发送,言外之意可以组播

    B类
    128.0.0.0到191.255.255.255
    用于国际性大公司和政府机构
    前两个八位字节指明网络,后两个八位字节指明网络上的主机

    C类
    C类IP地址范围192.0.0.0 ~ 223.255.255.255
    第1、2、3字节为网络地址,第四个字节为主机地址
    C类地址数量较多,使用于局部局域网中,每个网络中最多包含254台计算机
    用于一般小公司 校园网 研究机构
    以太网数据帧(里面不包括IP地址)

    前导码(7个字节) -> 帧起始界定符(1字节) -> 目的MAC地址(6字节) -> 源MAC地址(6字节)-> 类型/长度(2字节) -> 数据(46~1500字节) ->帧校验序列(4字节)
    局域网采用分组交换技术
    发送设备MAC地址 - > 接收设备MAC地址 -> 控制信息 ->有效载荷 -> 校验信息

    路由器多个异构或者同构网络进行互联

    网络层
    集线器来放大信号实现远距离传输
    协议转换器:用于传输层及以上各层的协议转换
    热点 - 正式名称无线接入点,它实际上是一个无线交换机或无线路由器。

    局域网
    按照介质所使用的访问控制方法可分为:以太网,FDDI网和令牌网
    必不可少的部分是集线器与交换机

    指令集
    Thumb指令集是16位的,ARM指令集是32位的,中间有Thumb-2作为桥接
    ARM处理器的三种工作状态
    ARM状态 (指令宽度32)
    Thumb 及 Thumb-2状态
    调试状态

    Thumb状态和ARM状态的切换
    通过BX指令,写数据到操作数寄存器(R0)的最低位。
    R0[0]=1 – 从ARM状态切换到Thumb状态。 R0[0]=0 – 从Thumb状态切换到ARM状态。
    ARM复位后的状态
    ARM处理器复位后的状态都是ARM状态

    BootLoader
    U-BOOT

    Linux中引导程序加载时所支持不同体系结构处理器种类最多的Bootloader 是- U-BOOT。
    全称universal-Boot-Loader
    支持PowerPC、x86、ARM等多种体系结构的处理器
    支持嵌入式Linux、VxWorks、QNX、RTEMS、Windows CE等操作系统
    采用两个阶段完成操作系统的引导加载
    引导加载程序主要完成:加电自检、外设存在自检、内存地址映射、初始化外围设备、内存寻址定位、加载并启动操作系统**
    BootLoader通常分为stage1和stage2两大部分。依赖于CPU的体系结构,比如设备初始化代码通常放在stage1中,且使用汇编语言实现,以达到短小精悍的目的。stage2通常用于C语言实现更复杂的功能,同时代码也具有更好的可读性和可移植性。
    BootLoader的stage1的基本步骤是:基本硬件初始化,为加载stage2准备RAM空间,拷贝stage2的执行代码到RAM空间中,设置栈区指针SP,跳转到stage2的C程序入口点。

    作用
    改变程序大小端排序
    关闭看门狗
    屏蔽中断
    设置各个时钟
    设置从SLEEP或者IDLE启动时的程序
    初始化SDRAM
    设置各模式指向的堆栈
    设置好中断向量表
    判断是从NOR FLASH(行读写,较慢)还是NAND FLASH(页读写)启动,
    将文件拷到SDRAM中

    操作系统
    IOS 的前身是 UNIX-BSD(宏内核架构,但是是微内核操作系统
    内核的概念
    内核提供任务调度、任务间通信与同步、任务管理、时间管理和存储管理。

    典型的单片机程序在程序指针复位后,首先进行堆栈、中断、中断向量、定时器、串行口等接口设置、初始化数据存储区和显示内容,然后就来到了一个监测、等待或空循环,在这个循环中,CPU可以监视外设、响应中断或用户输入。 这段主程序可以看作是一个内核,内核负责系统的初始化和开放、调度其它任务,相当于C语言中的主函数。

    现代操作系统设计中,为减少系统本身的开销,往往将一些与硬件紧密相关的(如中断处理程序、设备驱动程序等)、基本的、公共的、运行频率较高的模块(如时钟管理、进程调度等)以及关键性数据结构独立开来,使之常驻内存,并对他们进行保护。通常把这一部分称之为操作系统的内核。

    Linux
    UCLinux、RTLinux、uC/OS - II是开源嵌入式操作系统
    Linux最初以Unix为原型,以实现POSIX标准作为其目标
    OS服务组件、用户进程、Linux内核、硬件
    系统调用是Linux中用户进程和操作系统之间的重要接口

    Linux和Unix
    其两者源码是完全不相同的,尽管函数和命令的功能处理结果、函数名称和参数十分相同,以及Unix的行命令、驱动程序和应用程序在Linux上能够运行。
    Linux运行效率没有Unix高!

    Linux命令
    arm - linux - gcc交叉编译器来编译应用程序
    要对一个应用程序进行调试排错,应在编译指令中加g参数对它进行编译

    Linux内核主要由5个子系统组成
    进程调度(SCHED)
    内存(任务)管理(MM)
    虚拟文件系统(VFS)
    网络接口(NET)
    进程间通信(IPC)
    进程调度模块负责控制进程对CPU资源的使用,所采取的调度策略是使得各个进程能够平均访问CPU同时保证内核能及时地执行硬件操作。

    内存管理模块的功能之一是屏蔽各种硬件接口内存结构的差异并向上返回一个统一的访问接口
    网络接口模块包含网络接口驱动程序
    支持进程之间的各种通信机制,其通信机制包括:信号、管道、消息队列、信号量、共享内存、套接字(socket)

    微内核和宏内核
    微内核特征

    内核小巧,传统操作系统中的许多部分都被移出内核。
    接口一致,所有进程请求使用统一接口,进程不区分内核模式和用户模式服务。
    各个功能模块之间松散耦合,只完成服务功能,系统管理功能交给一个或多个特权服务程序。
    微内核扩充方便,但是各个功能之间的切换引起的开销很大!
    属于微内核的典型嵌入式操作系统有:Symbian、VxWorks、QNX、uC/OS - II、IOS,而Symbian是普通实时操作系统

    VxWorks收取授权费和版权费。
    VxWokrs用于尖端科技中

    宏内核
    传统操作系统常采用的结构
    应用程序效率高
    切换开销小
    对外来时间反应速度快
    内存大
    拓展性不高,维护困难
    可预测性较低
    可靠性较低
    Android OS是典型的宏内核操作系统
    宏内核又称为单内核!

    Tiny OS
    是开放源代码操作系统,属于深度轻量级的操作系统,专为嵌入式无线传感器网络设计,功耗较低,特别适合传感器这种受内存,功耗限制的设备。
    轻线程,主动消息和组件化编程。

    QNX
    符合POSIX基本标准和实时标准
    微内核操作系统
    内核提供四种服务:进程调度,进程间通信,底层网络通信和中断处理

    uC/OS-II
    抢占式实时操作系统
    抢占式实时操作系统且每个任务都有自用栈
    使用它的栈空间校验函数,可以确定每个任务到底需要多少栈空间
    该系统不包含设备驱动程序,只是一个纯内核
    不支持时间片轮转调度,所以赋给每个任务的优先级是不相同的
    允许每个任务之间有不同的栈空间

    升级版的UC/OS - III是商用操作系统
    II 具有良好的可剪裁性和可移植性
    能够支持的任务数最多是64(保留8个给系统,实际剩下56个)
    最多允许的中断嵌套层数可以达到255层
    软件结构一般具有:应用软件层,API层,内核层和设备驱动层
    该系统能提供周期性时钟信号(时钟节拍),用于实现任务的正确延时和超时确认,节拍率在10~100Hz之间
    用户必须在多任务调度启动以后再使能时钟节拍中断
    在中断返回之前,必须调用退出中断函数 voidIntExit(void)
    互斥信号量可以解决优先级反转的问题
    事件控制块用于对信号的管理
    任务管理中空闲任务是系统创建的第一个任务(空闲任务永远不会处于挂起态,还可能运行态,即使优先级最低,一旦其他任务都被堵塞他就可以执行了!
    中断服务子程序的伪码结构:保存全部CPU寄存器到栈,调用OSIntEnter()或者OSIntNesting变量加1,执行中断服务代码或发出IPC信息通知特定任务去执行中断服务,调用OSIntExit()函数,恢复所有CPU寄存器,执行中断返回指令。

    uC/OS-II 移植到一个 嵌入式系统电路板上正常运行,必须具备的条件
    处理器的C编译器能产生可重入代码,且用C语言就可以打开和关闭中断。
    处理器支持中断,并且能产生定时中断。(通常在10至100Hz之间)。
    处理器支持能够容纳一定量数据(可能几千字节)的硬件栈区。
    uC/OS-II 保护任务之间的共享数据和提供任务之间的通信
    可达到保护目的方法通常有
    利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITCAL来打开和关闭中断。
    利用函数OSSchedLock()和OSSchedUnlock()对任务调度函数上锁和开锁。
    利用信号量、互斥量、邮箱和消息队列进行任务间通信。
    系统启动过程中,Bootloader执行完毕后,调用应用程序主文件(通常是main.c)里的main函数。main函数在执行过程中除了用户函数和硬件初始化函数之外,需要执行下面三个重要函数:OSInit() -> OSTaskCreate() -> OSStart()(注意先后顺序)

    OSInit()函数先建立最初的任务就绪表,然后建立4个空白的数据链表,即:任务控制块链表,事件控制块链表、标志链表、内存控制块链表。

    系统中任务的五种状态
    休眠态(任务停留在内存中,还没有交给内核管理。)
    就绪态(该任务已经准备好,可以运行了,但是由于任务的优先级比正在运行任务的优先级低,还暂时不能运行。)(还有一种情况被更高优先级打断!)
    运行态(任务得到了CPU的控制权正在运行之中)
    挂起态
    被中断态(发生中断执行相应的中断服务,原来在正在运行后的任务暂时停止运行,进入被中断状态)

    一些系统函数
    OSTaskCreate() - 任务创建相关
    OSCtxSw() - 真正实现任务切换的函数
    OSIntExit() - 中断级的调度
    OSTickISR() - 时钟节拍中断服务子程序,与时间管理相关
    OSSched() - 任务前导函数,任务级的调度函数

    判断任务调度的三个条件是:
    中断嵌套层数共享全程变量OSIntNesting = 0,也就是所有的ISR已经执行完毕
    任务调度加锁层数共享全程变量OSLockNesting = 0,也就是调度没有被禁止
    就绪表找到最高优先级比当前任务的优先级高

    OSIntExit() - 中断级的调度函数

    系统事件控制块的相关函数
    OSSemCreate()(信号量创建)
    OSMutexCreate()(创建互斥体)
    OSMboxCreate()(建立一个邮箱)
    OSQCreate()(创建事件控制块)
    就绪任务登记在就绪表中,OSRdyTbl[ ] 是就绪表的位图映像矩阵,每一位代表了一个优先级任务的就绪状态,成为就绪位,该矩阵最多有64位。

    一些系统文件
    OS_CPU_C.C - 创建任务的自用栈空间、定义用户接口的hook原型
    OS_CORE.C - 核心调度代码,包括系统初始化、启动多任务调度开始运行、任务创建管理与调度、TCB初始化、就绪表初始化、ECB初始化、任务事件就绪表、空闲任务
    OS_MEM.C - 内存管理,包括创建分区,获得存储块
    OS_TASK.C - 任务管理,包括改变一个任务的优先级、创建或者删除一个任务,恢复一个被挂起的任务

    uC/OS系统时钟内核的基本功能(通过GLIBC调用通用函数和内核的内部功能)
    任务管理
    时间管理
    内存管理
    任务调度
    任务间通信和同步

    实时操作系统与非实时操作系统
    实时系统

    民航导航系统
    防空预警系统
    电力输送控制系统

    非实时
    视频播放系统
    博客发布系统
    手机交互式城市交通导航系统

    实时操作系统
    RTOS响应中断请求并且完成相应的中断服务子函数的时间非常快!精细衡量这个时间一致性变化的术语是抖动
    中断服务子函数也是可以调用函数然后进行事件处理的,中断服务子程序返回的最后一步执行中断返回指令。
    RTOS特征(主要特征是能够及时响应外部发生的随机任务请求并且能够在规定的时限内完成任务。)(不包括轮转调度)

    异步IO和中断处理能力
    任务切换时间和中断延迟时间确定
    优先级中断和调度
    抢占式调度
    内存锁定
    连续文件
    同步

    RTOS的实时性能主要由三个指标衡量
    响应时间**(包括中断延迟时间和任务切换时间)(任务切换时间又包括人物抢占时间)**
    吞吐量
    生存时间

    响应时间有两个指标 - 中断延迟时间和任务切换时间

    实时系统对时间约束要求的严格性,使可预测性成为实时系统的一项重要性能要求,它是指RTOS能够对外部事件的响应时间和实时任务的执行时间进行判断,以确定被时间触发的实时任务能否在规定的时间内完成。

    一般按照相应时间能将实时系统分为三类:强实时系统,其相应时间一般在ms级或us级;普通实时操作系统一般在s级,弱实时系统一般在数十s级。

    任务时限有两种
    截止时间:任务开始执行时间到任务必须完成的时间间隔。
    任务执行预设:又叫任务最快完成时间,这是在无中断响应情况下的任务最快执行时间。

    硬实时操作系统和软实时操作系统
    任务执行时间超过截止时间系统的总损益就为负,这种实时系统成为硬实时系统而且伴随有严重的后果,比如飞机控制器、核反应堆处理装置。
    软实时操作系统超过时限并不会造成严重的影响比如:DVD播放机。

    存储器
    半导体存储器芯片的存储容量取决于该芯片的地址总线的条数和数据总线的位数。
    存储器带宽与存储器总线的工作频率有关,也与数据线的位数和每个总线周期的传输次数有关!
    系统正在运行的程序的大部分数据和代码存放在主存储器(内存)中
    系统尚未运行的程序的大部分数据和代码存放在外部存储器中
    -

    分类
    按照存取特性分为:RAM和ROM
    按照物理位置分为:片内存储器和片外存储器以及外部存储器
    按照存储信息的类型分为:程序存储区和数据存储器

    RAM
    RAM - 高速读取, DRAM - 高集成度
    RAM 通常又有DRAM和SRAM之分**,SRAM较DRAM电路复杂,但是速度更快**,高速缓冲区(cache)就是典型的SRAMSRAM的复杂决定了它做不大,至多几十K。
    内存条就是DRAM,速度较SRAM慢,但是可以做的很大,比如内存条就是典型的DRAM,其容量就上G了。
    FRAM - 铁电随机存取存储器,MRAM - 磁性随机存取存储器。
    (以上两个随机存储器是非易失性存储器)

    FLASH
    Flash闪存有两大类,或非型(NOR Flash)和与非型(NAND Flash)
    或非以字节为单位进行随机存取,存储在里面的程序可以被CPU执行。与非以页为单位进行存取,速度较前者慢。
    与非门读出程序或数据时,是先将其预存入RAM,然后才被使用的。虽然速度较慢,但是其寿命,容量成本等方面有很大优势,常用的U盘基本都是NAND Flash。

    DDR
    DDR - dual data rate - 双倍数据速率
    DDR2 - 使原来DDR可预取读取2位变成可预取读取4位或8位,把DDR的数据传输速率又提升了两倍或四倍

    USB
    USB2.0 的速度可达到 480Mb/s
    USB3.0的速度可达到 5Gb/s, 即640MB/s
    半双工差分方式通信

    编码
    ASCII

    ASCII共128个字符,96个可打印字符,32个控制字符。
    ASCII是7位编码,但在计算机里用一个字节存放(计算机最基本的存储和处理单位)
    每个字节多出的1位在计算机内部常保持为0,在数据传输中是奇偶校验位。

    汉字编码
    GB2312 – 两字节编码(每个字节最高位默认为1),包含常用的中国汉字和图形符号。
    GB18030 与国际Unicode相兼容。单字节对应ASCII,双字节对应汉字(GB2312在这完全适用,但是比它范围广),其余四字节对应其他字符。

    Unicode
    UTF-8 – 单字节可变长编码,单字节向下兼容ASCII,音节文字对应两字节,CJK汉字(china japan koera 中日韩汉字)对应三字节,其余对应四字节。Linux 常用。
    UTF-16 – 双字节可变长编码,CJK汉字及常用字符两字节,其余四字节。JAVA .NET 常用。

    同步IO和异步IO
    CPU的速度远远快于磁盘、网络等IO。在一个线程中,CPU执行代码的速度极快,然而,一旦遇到IO操作,如读写文件、发送网络数据时,就需要等待IO操作完成,才能继续进行下一步操作。这种情况称为同步IO

    在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了。因为一个IO操作就阻塞了当前线程,导致其他代码无法执行,所以我们必须使用多线程或者多进程来并发执行代码,为多个用户服务。每个用户都会分配一个线程,如果遇到IO导致线程被挂起,其他用户的线程不受影响。

    多线程和多进程的模型虽然解决了并发问题,但是系统不能无上限地增加线程。由于系统切换线程的开销也很大,所以,一旦线程数量过多,CPU的时间就花在线程切换上了,真正运行代码的时间就少了,结果导致性能严重下降。

    另一种解决IO问题的方法是异步IO。当代码需要执行一个耗时的IO操作时,它只发出IO指令,并不等待IO结果,然后就去执行其他代码了。一段时间后,当IO返回结果时,再通知CPU进行处理。

    指令相关

    子程序返回调用程序除了MOV PC, LR。还可以MOV R15, LR
    汇编语言调用一个名为My的子程序的指令为: BL My 子程序返回调用程序的指令为:MOV PC, LR
    Thumb - 2指令集中关外部中断使用的指令是:CPSID I。开外部中断的指令为:CPSIE I
    EQ表示相等,NE表示不等
    RAM汇编程序采用分支指令B
    子程序调用指令BL
    条件转移指令BX
    RAM汇编中没有专门的指令实现循环,一般采用比较指令CMP、ADD、SUB等
    才能产生条件的指令,然后再通过带状态的条件转移指令BX来实现。
    指令后面加个!表示更新基地址寄存器符号
    寄存器间接寻址就是以寄存器中的值作为操作数地址,而操作数本身存放在存储器中。用于间接寻址的寄存器必须用[ ] 括起来
    Test EQU 50 定义 标号 Test的值为50!
    RAM完成有条件无符号加法运算,并更新CPSR中的状态,条件如果是相等,要求指令执行R1+R2,结果放入R3中,则这条指令ADDCEQ R3, R1, R2。如果条件是大于,要求执行R1 - R2,结果放入R3,则该指令是SUBHIS R3, R1, R2

    指令的条件码总结

    EQ - 相等
    NE - 不等
    MI - minus负数
    PL - plus正数或0
    vs - overflow set溢出
    vc - overflow clear未溢出
    GT - greater than带符号数大于
    GE - greater and equal带符号数大于或等于
    LT - lower than带符号数小于
    LE - lower equal带符号数小于或等于
    HI - high无符号数大于
    CS - carry same无符号数大于或等于
    CC - carry clear无符号数小于
    LS - low and same无符号数小于或等于

    常考指令

    LDR 字数据加载指令(存储器到寄存器的数据传送指令)
    LDRB 字节数据加载指令
    LDRH 半字数据加载指令
    STR 字数据存储指令
    STRB 字节数据存储指令
    STRH 半字数据存储指令

    STR R0, [R1] - 将R0中一个字的数据,存入以R1的值为地址的存储器中。
    LDR R0, [R1] - 以R1的值为地址的存储器中的字数据(为32位)读入寄存器R0
    LDRH R0, [R1] -以R1的值为地址的存储器中的半字数据(为16位)读入寄存器R0
    LDRB R0, [R1] -以R1的值为地址的存储器的字节数据(为8位)读入寄存器R0
    注意了,LDR R1, #0x12345678 LDR是加载存储指令,表示存储器到寄存器的数据传送,而#是立即数符号,表示立即数寻址。所以这样写是不正确的!
    ADC R1, R2, R3 表示 R1 = R2+R3+C(C表示进位)(ADD表示加法)(ADC表示)

    置1清0的操作

    常见的操作是:or可实现置1,and可实现清0。比如ORR R0,R0,#00000003 该指令设置R0的0、1位,其余位保持不变。再比如AND R0,R0,#FFFFFFFE实现R0的最低位清零。还有一个是用ARM的指令进行位清0,BIC R1, R1 #0X00000088
    立即数

    汇编语言中中操作数有三种:寄存器操作数、存储器操作数和立即数。
    其中立即数相当于高级语言中的常量(常数),它是直接出现在指令中的数,不用存储在寄存器或存储器中的数,如指令ADD AL,06H中的06H即为立即数。
    大小端存储

    所谓的大端模式就是,低地址存储高位字节。
    所谓的小端模式就是,低地址存储低位字节。

    计算机存储结构
    冯诺依曼,是一种程序指令储存和数据储存在一起的存储器结构
    哈佛结构,是一种将程序指令储存和数据储存分开的存储器结构

    音频图像
    音频

    数字音频的正确处理顺序是:取样 -> 量化 -> 编码
    数字音频的主要参数:取样频率、量化位数、声道数目、使用的压缩编码方法、比特率
    比特率(码率)计算方式:码率 = 取样频率×量化位数×声道数,压缩后的码率和压缩前的码率也就差一个压缩比。
    mp3
    MPEG - 1层
    ③算法进行有损的压缩编码,以8~12倍的比率大幅度降低了声音的数据量
    视频:MPEG-2

    图像
    包括BMP.、TIF、GIF、JPEG、PNG
    数字图像的获取过程分为:扫描、分色、取样
    GIF是互联网上广泛使用的一种图像文件格式,它的颜色数目较少,不超过256色,文件特别小,适合互联网传输
    JPEG是静止图像数据压缩编码的国际标准,特别适合处理各种连续色调的彩色和灰度图像,算法复杂度适中,软硬件皆可实现。

    屏幕
    触摸屏

    电阻式触摸屏(软屏),结构简单价格低
    电容式触摸屏(硬屏),结构复杂价格高
    电容式触摸屏可以实现多点触摸和滑动操作
    般写硬笔字的触摸屏是电阻屏

    LCD显示屏
    LCD显示屏自身不带控制器,没有驱动电路,仅仅是显示器件,价格最低
    LCD显示模块内置LCD显示屏,控制器和驱动模块,有字符型和图形点阵型
    PC机通常使用的是LCD显示器,除具备显示屏外,还包括驱动器,控制器以及外壳,是完整的LCD显示设备
    DVI、VGA以及HDMI是一种接口标准

    其他,部分常见错题

    微波通信:手机通信、卫星通信、无线局域网
    调频广播属于短波以及超短波通信。

    SIMD单指令多数据
    TST是位测试指令,将寄存器的值与立即数按位与。
    JMP是无条件跳转指令
    LDR是存储器到寄存器的数据传送指令
    STR是寄存器到存储器的数据传送指令
    SPI总线系统是一种同步串行外设接口
    OSSempend()等待一个信号量
    ECB事件控制块

    摩尔定律(Moore)
    基于Cortex-Mo的专家处理器为SC100,基于Cortex-M3的专家处理器名为SC300
    Cortex-M3采用3级流水线,Cortex-R4采用8级流水线.
    LDM是加载多个寄存器指令,后缀IA表示在每次执行完加载/存储操作后,R0按字长度增加。
    低压差稳压器(LDO)模块
    直接存储器访问(DMA)
    uC/OS-II利用函数OSSpend等待并获得消息,用函数OSQpost来发送消息

    GNU开发工具套件中包括编译器、【连接器】、调试器、文本编辑器、语法除错等工具。利用GNU中的调试器GDB进行程序调试时,可用命令【watch】来观察被调试程序中的变量值。

    嵌入式系统的调试相对来说比较复杂,调试的目的是发现错误并【定位错误】。因此,通常需借助多种调试工具来进行。调试工具的作用是控制【程序代码】的执行,并使系统中看不见的信息成为可视。

    在μC/OS-II操作系统中,调用任务管理函数【OSTaskSuspend】()可以挂起一个任务;函数【OSSemPend】()用于等待一个信号量

    在μC/OS-II操作系统中,宏【OS_ENTER_CRITICAL】 ()使系统进入临界状态,其主要操作是关闭所有可屏蔽中断,避免其他任务或中断服务程序打断临界区代码的执行。当需要实现对不可分割数据的原子访问时,μC/OS-II也可以调用函数void【OSSchedLock】 (void)锁定任务调度器,取代关中断。

    μC/OS-II支持两种方式的任务调度,分别是【任务】级的任务调度和【中断】级的任务调度,前者一般发生在当前运行态任务因等待某一事件而被阻塞或被挂起时,或是有更高优先级的任务处于就绪状态时。

    在实时系统中,从接收到可屏蔽中断请求信号到操作系统做出响应并转入中断服务程序所需要的最长时间称为【中断延时】时间;系统将控制权从低优先级的任务转移到高优先级任务所花费的时间称为【任务抢占】时间。

    在高端嵌入式系统中,除了操作系统、设备驱动程序和应用软件之外的系统软件称为【中间件】。

    发光二极管和数码管常用三个大写字母简写为【LED】,液晶显示器常用三个大写字母简写为【LCD】。

    I^2C总线只有两条信号线,一条是【数据】线SDA,另一条是【时钟】线SCL,I2C总线的所有操作都通过这两条信号线完成。

    分配一个32位字存储单元,名为Mydata并对其初始化为0x33445566的伪指令为【Mydata DCD 0x33445566】,无条件转移到标号为MLOOP且不进行模式切换的伪指令为【B MLOOP】。B是跳转指令,不带链接;DCD用于分配一片连续的字存储单元并用指定的数据初始化。

    在ARM的指令中,如果无符号数R1>R2,则将R1减去R2,结果放R3中并更新CPSR,用两条指令完成,则分别为【CMP R1,R2 SUBS R3,R1,R2】和【SUBHIS R3,R1,R2 SUBHI R3,R1,R2】。

    指令LDR R2,[R0,R1]!是将寄存器R0的内容自动增加R1,形成操作数的有效地址,从中取得32位操作数存入寄存器R2中,再更新基址寄存器R0的内容。

    ARM Cortex-A是ARM Cortex面向高端应用处理器,此系列中A5、A7、A8、A9、A12、A15和A17字长【32】位,而A50系列中的A53和A57字长为【64】位。

    ARM指令集的代码宽度为【32】位,Thumb指令集代码宽度为【16】位。

    计算机网络由计算机等智能电子设备(网络终端)、数据链路、【通信协议】以及网络软件等组成。网络中的每个网络终端都配一个网卡,每个网卡都有全球唯一的【48】位二进制的MAC地址。

    WWW网页是典型的**【超文本】结构**。Adobe公司开发的一种用于电子文档交换的文件格式名为【PDF】。

    发生中断时CPU提供相应的中断服务,原来正在运行的任务暂时停止运行,进入了被中断态,被中断态的任务是不能直接转入等待态的要先结束被中断态进入运行态。

    采用嵌入式处理器自带的UART可以组成RS-232/RS-485通信接口,RS-232采用负逻辑传输,其接口的信号线采用单端输出方式,逻辑0的电压范围为+3V+15V,逻辑1的电压范围为-15V-3V,而RS-485标准采用差分信号传输方式

    实时时钟(RTC)组件采用单独的供电引脚和时钟源,通过编程可以对RTC内部的年、月、日、星期、时、分、秒寄存器的值进行设置,但分频系数由时钟源决定,无法通过编程改变。

    基于AMBA总线的处理器使用系统总线和外围总线连接高速系统组件和低速外围组件,速度不高的外部接口连接外围总线(APB),包括定时器、并行接口和串行接口等;而LCD控制器和中断控制器等都连接在系统总线上。

    字符的形状有两种描述方法,点阵法和轮廓法。前者描述字符在离散点阵中笔画的占位信息,后者描述字符的轮廓,即把字符的轮廓用一组直线和曲线来勾画,字型库中记录的是每一直线和曲线的端点及控制点的坐标。

    用来描述数字图像的参数主要有图像大小(图像分辨率)、位平面数目、像素深度和颜色模型。

    在μC/OS-II操作系统中,内核对任务的管理通过名为【任务控制块】的数据结构进行。当任务切换时,任务的工作现场被保存到任务的【自用栈】中。
    在μC/OS-II操作系统中,内核对任务的管理通过任务控制块OS_TCB进行;任务切换也称为上下文切换,实际含义是任务的CPU寄存器内容切换。当μC/OS-II内核决定运行别的任务时,正在运行任务的工作现场被保存到任务的自由栈之中。

    在μC/OS-II操作系统中,某任务正在等待键盘输入消息,该任务应处于【挂起】态。若键盘中断服务程序向该任务发送了消息,则该任务转变为【就绪】态。

    BIC是位清零指令 M3中的MPU是用来对存储器进行【保护】 的单元。

    ARM9TDMI-S中的T的含义是支持高密度的 【16】位Thumb指令,D表示支持片上【调试】 。

    像素深度是8位的灰度图像,其不同的亮度等级总数为 【256】 种。
    真彩色图像中R、G、B三分量的像素位数都是8位,图像的像素深度为24位

    其中智能手机之类的嵌入式系统使用操作系统对系统进行控制,属于高端系统,采用32/64位处理器,支持连接网络。

    GCC是针对Linux操作系统环境下应用程序的编译工具,它能将C语言、C++语言、汇编语言编写的源程序以及库文件编译连接成执行文件;它从源文件生成可执行文件的过程是由四个相关联的阶段组成:预处理、编译、汇编、连接

    Linux是能够为多用户提供多任务、多线程功能的大型单内核操作系统;Monta Vista Linux是一种嵌入式操作系统发行版,是Monta Vista Software公司于1999年7月推出的;虚拟文件系统(VFS)是Linux的通用文件系统模型,在系统调用接口和内核所支持的文件系统之间提供了一个交换层;系统调用是Linux中用户进程和操作系统之间的重要接口

    空闲任务OS_TaskIdle是μC/OS-II的系统任务,是操作系统初始化函数创建的第一个任务自创建之后永远不会处于挂起态,因为它占据了最低优先级63,所以只有在其他的任务都因为等待事件的发生而被阻塞的时候才能得到运行。

    μC/OS-II的大部分代码是用标准C语言写的,其每个任务都处在以下5种状态之一的状态,即休眠态、就绪态、运行态、挂起态和被中断态。支持抢占式任务调度,处于运行态的任务一定是当前就绪任务集里的最高优先级任务;当多个任务同时等待同一事件发生时,只有优先级最高的任务得到该事件并进入就绪状态准备执行;允许每个任务拥有自己的自用栈;发生中断时,正在运行的μC/OS-II任务暂停运行,并进入被中断状态。

    USB RS-485 CAN采用差分信号传输方式,具有很强的抗共模干扰能力;选项中仅RS-232不是。

    串行外设(SPI)接口是一种同步串行外设接口,允许嵌入式处理器与各种外围设备以串行方式进行通信、数据交换。一般使用4跳线**:SCK、MISO、MOSI和SSEL**。将数据写到SPI发送缓冲区后,一个时钟信号SCK对应一位数据的发送(MISO)和另一位数据的接收(MOSI);在主机中数据从移位寄存器中自左向右发出送到从机(MOSI),同时从机中的数据自右向左发到主机(MISO),经过8个时钟周期完成1字节的发送。

    指令LDR R0,[R1,#4]是将寄存器R1的内容自动增加4,形成操作数的有效地址,从中取得32位操作数存入寄存器R0中。

    嵌入式处理器的体系结构按指令集可分为两大类:复杂指令集结构(CISC)及精简指令集结构(RISC);按存储机制分为冯·诺依曼结构及哈佛结构;按不同内核系列可分为51、AVR、MSP430、MIPS、PowerPC、MC68K、ARM等。其中,PowerPC、MC68K、MIPS采用RISC、哈佛结构,ARM也采用RISC,多数为哈佛结构。

    局域网采用分组交换技术,发送设备必须把要传输的数据分成小块,即帧,一次只能传输一帧。数据帧中除了包含需要传输的数据(称之为“有效载荷”)之外,还必须包含发送该数据帧的发送设备地址和接收该数据帧的接收设备地址。另外数据帧中还需要附加一些信息随同数据一起进行传输,以供接收设备在收到数据之后验证数据传输是否正确。这些信息包括控制信息和校验信息。

    Linux操作系统中,可执行文件的文件名中没有统一的文件后缀。若用GCC命令生成可执行文件,命令中未指定输出文件名时,则GCC生成一个名为 【a.out】的可执行文件。针对ARM硬件平台的目标机,其GCC的基本命令格式是:【arm_linux_gcc】[options] [filenames]。

    本题考查基于μC/OS-II的系统平台的应用开发。一个应用程序的工程项目中,必须包含启动引导程序,UC/OS-II的库文件,应用程序等。main()函数在执行过程中,除了用户函数和硬件初始化函数外,按以下次序执行3个主要的μC/OS-II函数:操作系统初始化OSInit(),任务创建OSTaskCreate(),任务调度开始OSStart()。

    μC/OS-II操作系统中任务状态即状态切换。运行态指得到了CPU的控制权正在运行之中的任务状态。当处于运行态的任务执行节拍延时函数OSTimeDly()后,该任务将转入挂起态。就绪态任务在执行OSTaskDel()函数后将转入休眠态。

    。代码的**临界区(Critical Section)是指处理时不可分割的代码。为确保临界区代码的执行,在进入临界区之前必须关中断,执行完临界区代码之后要立即开中断。μC/OS-II系统调用宏OS_ENTER_CRITICAL ()**执行关中断操作。

    μC/OS-II系统中主要利用信号量、互斥信号量、邮箱或消息队列进行任务间通信。

    美国加州大学伯克利分校开发的主要用于无线传感器网络的操作系统名为TinyOS

    Linux操作系统遵从GNU计划下的通用公共许可协议,而GNU开发的编程语言编译器称为GCC。

    中断控制器是介于ARM内核与其他硬件之间的一个部件,负责对其他硬件组件的中断请求进行管理和控制,一般采用向量中断(VIC)或嵌套向量中断(NVIC)方式管理中断。

    在ARM Cortex-M3中可实现中断嵌套,中断可以改为比之前的中断服务程序更高的优先级,并且可以在运行时改变优先级状态,使用末尾连锁连续中断需要消耗【3】 个时钟周期,而普通中断需要【32】 个时钟周期。

    ARM7采用冯·诺依曼结构,3级流水线,ARM9采用哈佛结构,5级流水线

    ARM处理器异常中断指令中用于软中断的指令助词符为【SWI】 ,用于断点中断指令助词符为【BKPT】 。

    。目前数字有线电视和卫星电视所传输的数字视频采用的编码格式是【MPEG-2】 ,而在互联网视频应用中最新也是应用最多的视频编码格式是【H.264/MPEG-4 AVC】 。

    使用JTAG进行嵌入式系统的调试,无需目标存储器,也不占用目标机任何I/O端口,运行在宿主机上的调试工具软件通过目标机CPU芯片的JTAG接口以及内嵌的调试电路通常可以完成相关调试工作。

    微内核有以下几个特点:①内核小巧②接口一致③各个功能模块之间松散耦合,只完成服务功能,系统管理功能交给一个或多个特权服务程序。④微内核功能扩充方便,但是各个功能之间的切换而引起的开销比较大。⑤基于客户机/服务器体系结构,在微内核结构的操作系统中,任务间通信机制—消息机制是系统的基础,操作系统的各种功能都以服务器方式实现,向客户机提供服务。

    μC/OS-II、RTLinux、ECOS等是主要的开源嵌入式操作系统。

    可以认为μC/OS-II是嵌入式操作系统领域中的最小内核之一,它只提供提供的基本功能有:①任务调度②任务间通信(Inter-Task Communication, ITC。术语ITC含义与IPC含义相当)③同步④任务管理⑤时间管理⑥内存管理等基本功能。

    在μC/OS-II操作系统中有多种方法可以保护任务间的共享数据并支持任务之间的通信。主要有以下三种:(1)利用宏OS_ENTER_CRITICAL( )和OS_EXIT_CRITICAL( )来关闭中断和打开中断;(2)利用函数OSSchedLock( )和OSSchekUnlock( )对μC/OS-II中的任务调度函数上锁和开锁;(3)利用信号量(OS_EVENT_TYPE_SEM)、互斥信号量(OS_EVENT_TYPE_MUTEX)、邮箱(OS_EVENT_TYPE_MBOX)或消息队列(OS_EVENT_TYPE_Q)进行任务间通信。
    嵌入式Linux的特点是:①开放源代码,不存在黑箱计数;②由于开放源代码,成本低;③内核紧凑,占内存空间最小为140KB;④网络功能强;⑤可移植性强;⑥可裁剪性强;⑦支持多任务;所以成为研发嵌入式软件的重要首选平台。

    S3C2410有GPA、GPB、GPC、GPD、GPE、GPF、GPG和GPH这8个GPIO端口,其中GPA0~GPA22功能单一,仅作为地址线的控制线使用;GPC和GPD作为LCD液晶屏接口引脚。

    通用串行总线USB是一种外部总线接口标准,支持设备的即插即用和热插拨功能;USB总线(1.1和2.0)有4根信号线,采用半双工差分方式,用来传送信号并提供电源;其中D+和D-为差分信号线,传送信号。

    I2C总线只有两条信号线SDA和SCL,当总线上的所有器件都不适用总线时,SCL线和SDA线各自的上拉电阻把电平拉高,使它们均处于高电平。

    嵌入式系统的主存储器是指系统内存,包括内部SRAM和Flash和片外扩展DRAM和Flash。

    AMBA是指先进的微控制器总线体系结构,主要由系统总线和外围总线两部分组成。速度不高的外部接口连接外围总线(APB),包括定时器、并行接口和串行接口等;而电源管理及时钟控制器等都连接在系统总线上。

    **DRAM是动态随机存取存储器,是易失性存储器;**DDR2 SDRAM(双倍数据速率同步DRAM)采用了4位预取技术;EEPROM是一种可电擦除可编程的只读存储器,可以在线改写和擦除信息,无需紫外线照射;NOR Flash和NAND Flash是两种主要的闪存技术。

    ARM体系结构支持7种工作模式,取决于当前程序状态寄存器CPSR的低5位值。用户模式是程序正常执行工作模式,当处理器处于用户模式时,如果没有异常发生不能改变工作模式;系统模式运行特权级的操作系统任务;管理模式是操作系统的保护模式,处理软中断。

    SBC是带借位减法指令

    在ARM的体系结构中,处理器可以工作在3种不同的状态:①ARM状态②Thumb状态及Thumb-2状态③调试状态。其中,除支持Thumb-2的ARM处理器外,其他所有ARM处理器都可以工作在ARM状态,而Cortex-M3只有Thumb-2状态和调试状态。

    嵌入式处理器的体系结构按指令集可分为两大类:复杂指令集结构(CISC)及精简指令集结构(RISC);按存储机制分为冯·诺依曼结构及哈佛结构;按不同内核系列可分为51、AVR、MSP430、MIPS、PowerPC、MC68K、ARM等。**其中,PowerPC、MC68K、MIPS采用RISC、哈佛结构,**ARM也采用RISC,多数为哈佛结构。

    图像数据量=图像水平分辨率×图像垂直分辨率×像素深度/8
    像素深度=颜色数x8

    **按照采样定理,取样频率不应低于声音信号最高频率的两倍才不产生失真;
    波形声音的码率=取样频率×量化位数×声道数(单位:b/s);
    定时器计数脉冲周期=1/(PCLK/(预分频值+1)/分频系数)。**对配置寄存器以及控制寄存器的设置即按照寄存器格式对相应位进行赋值。

    软件平台的构建步骤通常是:首先移植启动引导程序(Bootloader),然后完成Linux内核的移植,随后还需构建根文件系统。基于ARM9核的处理器,启动引导程序代码的存储单元首址应该是0x00000000,它对应复位异常向量。各异常向量之间相差4个字节。因此,需要在各异常向量处设计一条无条件转移指令

    开发基于Linux操作系统上的应用程序,可使用GCC工具来编译和连接。若仅希望对应用程序进行编译而不进行连接,需要在GCC命令中加入参数【-c】。若希望编译连接后生成一个用于调试的符号表,需要在GCC命令中加入参数【-g】。

    嵌入式系统的开发过程,可划分为4个阶段,即:需求分析与规格说明、【系统设计】、构件设计、系统集成与测试。

    μC/OS-II的任务由三部分构成:程序代码,也即没有返回值的C函数;任务【堆栈】,用于保存任务的工作环境;【任务控制块】,用于保存任务状态和属性。

    Android系统采用堆层式软件架构,分为四层,从低层到高层依次是Linux内核、【核心库】、应用程序框架(Application Framework)和【应用程序】。

    嵌入式操作系统的引导加载方式可以分为两类:嵌入式系统正常工作时使用的启动方式是从非易失存储介质中引导和加载操作系统代码,称为【启动】加载模式;而在调试或维护更新阶段使用的系统启动方式则通过通信端口从调试主机上下载操作系统映像,称为【下载】模式。

    在对S3C2410的PWM输出操作中,TCNTBn决定PWM信号的周期,TCMPBn决定PWM信号的占空比。假设TCNTBn=100,TCMPBn=60,则该PWM信号的周期为【100】个定时器输入时钟周期,一个PWM信号周期内的低电平宽度为【40】个定时器输入时钟周期。
    PWM用于脉冲宽度的调制,当定时达到后将产生特定波形。本题主要考查PWM周期设定计算。所谓占空比就是脉冲宽度与PWM周期之比,脉冲宽度即在一个周期内输出高电平的时间。

    有一个Flash存储器芯片容量为16MB,数据线有8条,则该存储器的地址线条数为【24】条;另有一个SRAM芯片有22条地址线,8条数据线,其容量为【32】Mbit。

    声明一个全局标号Reset_Handler以便其它文件引用,该伪指令为【EXTERN Reset_Handler】,引用一个在其它文件中的标号SystemInit的伪指令为【IMPORT SystemInit】。
    本题考查ARM的数据定义伪指令。全局标号的声明用的是EXTERN,引用其他文件中的标号用IMPORT。

    在ARM的指令中,如果R1与R2不相等,则将R1与R2进行逻辑与操作,结果放R3中,并要求更新程序寄存器的状态位,用两条指令完成,则分别为【CMP R1,R2 TEQ R1,R2】和【ANDNES R3,R1,R2】。

    在ARM指令系统中,利用移位操作符将R1的数据逻辑右移2位后,存入R0中,相应的指令为【MOV R2,R1,LSR#2】,若R1=0x00080010,则R0=【0x00020004】。

    ARM处理器把执行纯32位指令代码的指令集称为【ARM】指令集,把执行16位指令代码的指令集称为【Thumb】指令集。

    WiFi和Bluetooth是两种短距离无线通信技术,其中最早的IEEE.802.11b(2.4GHz频段)采用【调频】扩频技术,Bluetooth后来被IEEE作为【个人】无线区域网协议**(IEEE 802.15)的基础。无线局域网采用的协议主要是IEEE802.11a,俗称WiFi。其中最早的IEEE.802.11b(2.4GHz频段)采用调频扩频技术,传输速度可根据环境而调整。Bluetooth最早是由瑞典爱立信公司提出的,后来被IEEE作为个人无线区域网协议(IEEE 802.15)的基础。**

    在有线通信中,双绞线的特点是成本【低】、易受外部高频电磁波干扰,误码率较【高】,传输距离有限,主要应用于固定电话回路和计算机局域网等。

    字符的形状有两种描述方法,其中下图所示的描述方法为【点阵】法,也即描述字符笔画的占位信息;另一种描述方法在字型库中记录的是每一直线和曲线的端点及控制点的坐标,称为【轮廓】法。

    指令集模拟器(ISS)是在宿主机上模拟应用程序在目标机上运行行为的一个软件工具,其操作界面与通用机的集成开发环境类似。

    eCos是一种免费和开源的实时操作系统,用C/C++编码,是可定制的操作系统。

    μC/OS-II与大型操作系统不同,基本不包含设备驱动程序,只是一个纯内核。其驱动程序属于底层,需要系统开发商自行开发。

    S3C2410属于中高档32位嵌入式处理器,其存储器控制组件中包括存储器控制器、外部主控器、NAND Flash控制器等,其中存储器控制器提供访问片外存储器芯片所需的控制信号,支持大/小端模式,地址空间共1GB;S3C2410片内具有分离的指令Cache和数据Cache。

    **存储器管理单元(MMU)是许多高性能处理器所必需的重要部件之一,而存储器保护单元(MPU)**是对存储器进行保护的可选组件,提供了简单替代MMU的方法来管理存储器。

    NVIC称之为内嵌向量中断控制器,支持嵌套和向量中断。内部没有NVIC的ARM处理器是ARM9,
    ARM公司把从ARM7到ARM11为内核的系列处理器称为经典ARM处理器。
    UTF-16采用的是双字节可变长编码。

    SPI是一种同步串行外设接口,允许嵌入式处理器与各种外围设备以串行方式进行通信、数据交换。

    展开全文
  • 在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。 (内核:2.4.37)


    在文件系统中,有三大缓冲为了提升效率:inode缓冲区、dentry缓冲区、块缓冲。

    (内核:2.4.37)


    二、块buffer缓冲区

    0、整体来说,Linux 文件缓冲区分为page cache和buffer cache,每一个 page cache 包含若干 buffer cache。

    》 内存管理系统和 VFS 只与 page cache 交互,内存管理系统负责维护每项 page cache 的分配和回收,同时在使用“内存映射”方式访问时负责建立映射。

    》 VFS 负责 page cache 与用户空间的数据交换。

    》 而具体文件系统则一般只与 buffer cache 交互,它们负责在存储设备和 buffer cache 之间交换数据,具体的文件系统直接操作的就是disk部分,而具体的怎么被包装被用户使用是VFS的责任(VFS将buffer cache包装成page给用户)。

    》 每一个page有N个buffer cache,struct buffer_head结构体中一个字段b_this_page就是将一个page中的buffer cache连接起来的结构

         看一下这个结构:/include/linux/mm.h,对于struct buffer_head下面再看。

         看到下面167行代码就懂了~

    typedef struct page {
    156         struct list_head list;          /* ->mapping has some page lists. */
    157         struct address_space *mapping;  /* The inode (or ...) we belong to. */
    158         unsigned long index;            /* Our offset within mapping. */
    159         struct page *next_hash;         /* Next page sharing our hash bucket in
    160                                            the pagecache hash table. */
    161         atomic_t count;                 /* Usage count, see below. */
    162         unsigned long flags;            /* atomic flags, some possibly
    163                                            updated asynchronously */
    164         struct list_head lru;           /* Pageout list, eg. active_list;
    165                                            protected by pagemap_lru_lock !! */
    166         struct page **pprev_hash;       /* Complement to *next_hash. */
    167         struct buffer_head * buffers;   /* Buffer maps us to a disk block. */
    168 
    169         /*
    170          * On machines where all RAM is mapped into kernel address space,
    171          * we can simply calculate the virtual address. On machines with
    172          * highmem some memory is mapped into kernel virtual memory
    173          * dynamically, so we need a place to store that address.
    174          * Note that this field could be 16 bits on x86 ... ;)
    175          *
    176          * Architectures with slow multiplication can define
    177          * WANT_PAGE_VIRTUAL in asm/page.h
    178          */
    179 #if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
    180         void *virtual;                  /* Kernel virtual address (NULL if
    181                                            not kmapped, ie. highmem) */
    182 #endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
    183 } mem_map_t;


    关系图如下:

                       


    1、对于具体的Linux文件系统,会以block(磁盘块)的形式组织文件,为了减少对物理块设备的访问,在文件以块的形式调入内存后,使用块高速缓存进行管理。每个缓冲区由两部分组成,第一部分称为缓冲区首部,用数据结构buffer_head表示,第二部分是真正的存储的数据。由于缓冲区首部不与数据区域相连,数据区域独立存储。因而在缓冲区首部中,有一个指向数据的指针和一个缓冲区长度的字段。

       Ps:内核同样有几种不同的链表来管理buffer cache,在fs/buffer.c中定义:

       static struct buffer_head **hash_table;

       static struct buffer_head *lru_list[NR_LIST];

       static struct buffer_head * unused_list;

         下面我们具体看看这个结构体struct buffer_head,这个版本中这个结构体在fs.h中,后面的一些版本,在buffer_head.h中。

    246 struct buffer_head {
    247         /* First cache line: */
    248         struct buffer_head *b_next;     /* Hash queue list */
    249         unsigned long b_blocknr;        /* block number */
    250         unsigned short b_size;          /* block size */
    251         unsigned short b_list;          /* List that this buffer appears */
    252         kdev_t b_dev;                   /* device (B_FREE = free) */
    253 
    254         atomic_t b_count;               /* users using this block */
    255         kdev_t b_rdev;                  /* Real device */
    256         unsigned long b_state;          /* buffer state bitmap (see above) */
    257         unsigned long b_flushtime;      /* Time when (dirty) buffer should be written */
    258 
    259         struct buffer_head *b_next_free;/* lru/free list linkage */
    260         struct buffer_head *b_prev_free;/* doubly linked list of buffers */
    261         struct buffer_head *b_this_page;/* circular list of buffers in one page */
    262         struct buffer_head *b_reqnext;  /* request queue */
    263 
    264         struct buffer_head **b_pprev;   /* doubly linked list of hash-queue */
    265         char * b_data;                  /* pointer to data block */
    266         struct page *b_page;            /* the page this bh is mapped to */
    267         void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */
    268         void *b_private;                /* reserved for b_end_io */
    269 
    270         unsigned long b_rsector;        /* Real buffer location on disk */
    271         wait_queue_head_t b_wait;
    272 
    273         struct list_head     b_inode_buffers;   /* doubly linked list of inode dirty buffers */
    274 };
    解释一些上面的字段:

    b_next:用于链接到块缓冲区的hash表

    b_blocknr:本block的块号

    b_size:block的大小

    b_list:表示当前的这个buffer在那个链表中

    b_dev:虚拟设备标识

    b_count:引用计数(几个人在使用这个buffer)

    b_rdev:真实设备标识

    b_state:状态位图,如下:

    212 /* bh state bits */
    213 enum bh_state_bits {
    214         BH_Uptodate,    /* 如果缓冲区包含有效数据则置1 */
    215         BH_Dirty,       /* 如果buffer脏(存在数据被修改情况),那么置1 */
    216         BH_Lock,        /* 如果缓冲区被锁定,那么就置1 */
    217         BH_Req,         /* 如果缓冲区无效就置0 */
    218         BH_Mapped,      /* 如果缓冲区有一个磁盘映射就置1 */
    219         BH_New,         /* 如果缓冲区是新的,而且没有被写出去,那么置1 */
    220         BH_Async,       /* 如果缓冲区是进行end_buffer_io_async I/O 同步则置1 */
    221         BH_Wait_IO,     /* 如果要将这个buffer写回,那么置1 */
    222         BH_Launder,     /* 如果需要重置这个buffer,那么置1 */
    223         BH_Attached,    /* 1 if b_inode_buffers is linked into a list */
    224         BH_JBD,         /* 如果和 journal_head 关联置1 */
    225         BH_Sync,        /* 如果buffer是同步读取置1 */
    226         BH_Delay,       /* 如果buffer空间是延迟分配置1 */
    227 
    228         BH_PrivateStart,/* not a state bit, but the first bit available
    229                          * for private allocation by other entities
    230                          */
    231 };
    232
    b_flushtime:脏buffer需要被写入的时间

    b_next_free:指向lru链表中next元素

    b_prev_free:指向链表上一个元素

    b_this_page:连接到同一个page中的那个链表

    b_reqnext:请求队列

    b_pprev:hash队列双向链表
    data:指向数据块的指针

    b_page:这个buffer映射的页面

    b_end_io:IO结束时候执行函数

    b_private:保留

    b_rsector:缓冲区在磁盘上的实际位置

    b_inode_buffers:inode脏缓冲区循环链表


    3、关于VFS怎么去管理几个buffer cache的链表,如下:

    hash表:用于管理包含有效数据的buffer,在定位buffer的时候很快捷。哈希索引值由数据块号以及其所在的设备标识号计算(散列)得到。

    关于这段hash代码如下:

    <span style="font-size:14px;">539 /* After several hours of tedious analysis, the following hash
    540  * function won.  Do not mess with it... -DaveM
    541  */
    542 #define _hashfn(dev,block)      \
    543         ((((dev)<<(bh_hash_shift - 6)) ^ ((dev)<<(bh_hash_shift - 9))) ^ \
    544          (((block)<<(bh_hash_shift - 6)) ^ ((block) >> 13) ^ \
    545           ((block) << (bh_hash_shift - 12))))</span>
    下面简单的看一下流程:

    当我们在一个具有的文件系统中,当我们需要读取一块数据的时候,需要调用bread函数(面包?ヾ(。`Д´。),应该是buffer read的缩写吧。。。)。

    如下:

    1181 /**
    1182  *      bread() - reads a specified block and returns the bh
    1183  *      @block: number of block        块号
    1184  *      @size: size (in bytes) to read 需要读取的size
    1185  * 
    1186  *      Reads a specified block, and returns buffer head that
    1187  *      contains it. It returns NULL if the block was unreadable.  返回一个包含这个block的buffer
    1188  */ 
    1189 struct buffer_head * bread(kdev_t dev, int block, int size)
    1190 {
    1191         struct buffer_head * bh;
    1192 
    1193         bh = getblk(dev, block, size);    /* 找到这个buffer */
    1194         if (buffer_uptodate(bh))  /* 判断是否存在有效数据,如果存在那么直接返回即可 */
    1195                 return bh;
    1196         set_bit(BH_Sync, &bh->b_state); /* 如果不存在有效数据,将这个buffer设置成同步状态 */
    1197         ll_rw_block(READ, 1, &bh); /* 如果没有,那么需要从磁盘中读取这个block到buffer中,这个是一个底层的读取操作 */
    1198         wait_on_buffer(bh);  /* 等待buffer的锁打开 */
    1199         if (buffer_uptodate(bh)) /* 理论上这个时候应该是存在有效数据的了,直接返回就可以 */
    1200                 return bh;
    1201         brelse(bh);
    1202         return NULL;
    1203 }
    对于上面函数的分析,基本上分成两个步骤,

    第一:通过dev号+block号找到相应的buffer,使用函数getblk,如下:

    1013 struct buffer_head * getblk(kdev_t dev, int block, int size)
    1014 {
    1015         for (;;) {
    1016                 struct buffer_head * bh;
    1017 
    1018                 bh = get_hash_table(dev, block, size);   /* 关键函数,得到hash表中的buffer */
    1019                 if (bh) {
    1020                         touch_buffer(bh);
    1021                         return bh;     /* 返回这个buffer */
    1022                 }
    1023                 /* 如果没有找到对应的buffer,那么试着去增加一个buffer,就是使用下面的grow_buffers函数 */
    1024                 if (!grow_buffers(dev, block, size))
    1025                         free_more_memory();
    1026         }
    1027 }

    简单看一下这个查找buffer函数:get_hash_table

    628 struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
    629 {
    630         struct buffer_head *bh, **p = &hash(dev, block);   /* 首先通过hash值得到对应的位置,这个函数h很easy */
    631 /* 其实就是 #define hash(dev,block) hash_table[(_hashfn(HASHDEV(dev),block) & bh_hash_mask)]。hashfn函数上面已经说过了,就是通过hash值得到buffer*/
    632         read_lock(&hash_table_lock);
    633 
    634         for (;;) {           /* 下面就是判断这个得到的buffer数组中有没有我们需要的buffer */
    635                 bh = *p;
    636                 if (!bh)
    637                         break;
    638                 p = &bh->b_next;
    639                 if (bh->b_blocknr != block)
    640                         continue;
    641                 if (bh->b_size != size)
    642                         continue;
    643                 if (bh->b_dev != dev)
    644                         continue;
    645                 get_bh(bh);       /* 如果有那么直接执行这个函数,这个函数很easy,其实就是增加一个使用计数器而已: atomic_inc(&(bh)->b_count);*/
    646                 break;
    647         }
    648 
    649         read_unlock(&hash_table_lock);
    650         return bh;
    651 }

    如果没找到对应的buffer,那么使用grow_buffers函数增加一个新的buffer,看函数:

    2596 /*
    2597  * Try to increase the number of buffers available: the size argument
    2598  * is used to determine what kind of buffers we want.
    2599  */
    2600 static int grow_buffers(kdev_t dev, unsigned long block, int size)
    2601 {
    2602         struct page * page;
    2603         struct block_device *bdev;
    2604         unsigned long index;
    2605         int sizebits;
    2606 
    2607         /* Size must be multiple of hard sectorsize */
    2608         if (size & (get_hardsect_size(dev)-1))
    2609                 BUG();
    2610         /* Size must be within 512 bytes and PAGE_SIZE */
    2611         if (size < 512 || size > PAGE_SIZE)
    2612                 BUG();
    2613 
    2614         sizebits = -1;
    2615         do {
    2616                 sizebits++;
    2617         } while ((size << sizebits) < PAGE_SIZE);
    2618 
    2619         index = block >> sizebits;
    2620         block = index << sizebits;
    2621 
    2622         bdev = bdget(kdev_t_to_nr(dev));
    2623         if (!bdev) {
    2624                 printk("No block device for %s\n", kdevname(dev));
    2625                 BUG();
    2626         }
    2627 
    2628         /* Create a page with the proper size buffers.. */
    2629         page = grow_dev_page(bdev, index, size);
    2630 
    2631         /* This is "wrong" - talk to Al Viro */
    2632         atomic_dec(&bdev->bd_count);
    2633         if (!page)
    2634                 return 0;
    2635 
    2636         /* Hash in the buffers on the hash list */
    2637         hash_page_buffers(page, dev, block, size);
    2638         UnlockPage(page);
    2639         page_cache_release(page);
    2640 
    2641         /* We hashed up this page, so increment buffermem */
    2642         atomic_inc(&buffermem_pages);
    2643         return 1;
    2644 }
    2645 
    这个函数就是增加一个新的buffer,首先由grow_dev_page创建一个缓冲区包含这个block,然后将这个buffer链接到这个全局的hash缓冲区中使用函数hash_page_buffers。具体的代码很简单,不单看了。

    第二:如果没有找到需要的buffer,那么执行底层读取函数ll_rw_block将数据从磁盘去读进来,这个函数在/source/drivers/block/ll_rw_blk.c中,具体的代码不看了。


    OK,至此,寻找一个我们需要的buffer就结束了。


    LRU链表

    对于每一种不同缓冲区都会使用一个LRU来管理未使用的有效缓冲区

    Ps:缓冲区类型如下:

    1152 #define BUF_CLEAN       0
    1153 #define BUF_LOCKED      1       /* Buffers scheduled for write */
    1154 #define BUF_DIRTY       2       /* Dirty buffers, not yet scheduled for write */
    分别是:未使用的干净的缓冲区;正在等待写入的缓冲区;脏缓冲区,还没有被写回磁盘。

    这个三种链表怎么得到的呢,看代码也知道是吻合的,看LRU的声明:static struct buffer_head *lru_list[NR_LIST];

    再看:#define NR_LIST         3,OK


    当我们需要寻找一块buffer的时候,如果发现buffer在缓冲区中,且在LRU链表中,那么从LRU表中删除。

    结合上面的一个hash链表,基本过程就是:

    首先呢在hash表中寻找,如果找到,那就OK,如果没有找到,那么需要分配新的buffer,如果分到,那么加载数据进来,继续...如果没有足够的空间分配,那么, 需要将LRU中一个取出(LRU链首元素),先看是否置了“脏”位,如已置,则将它的内容写回磁盘。然后清空内容,将它分配给新的数据块。

    在缓冲区使用完了后,将它的b_count域减1,如果b_count变为0,则将它放在某个LRU链尾,表示该缓冲区已可以重新利用。


    unused_list 用于辅助就不多说了~~~


    展开全文
  • 超硬核!操作系统学霸笔记,考试复习面试全靠它

    万次阅读 多人点赞 2021-03-22 18:43:49
    之后会发布基于基础知识的大部分算法的模拟代码合集,敬请关注。

    之后会发布基于基础知识的大部分算法的模拟代码合集,敬请关注。

    进程基础

    进程的基本概念

    • 程序顺序执行的特征:

      1)顺序性:处理机严格按照程序所规定的顺序执行,每一步操作必须在下一步操作开始前执行

      2)封闭性:程序在封闭的环境下运行,程序独占资源,资源的状态由程序决定,程序一旦开始执行,外界环境不会影响程序的执行结果。

      3)可再现性:只要程序的初始条件和环境相同,程序的执行结果就相同。

    • 程序的并发执行的特征:(顺序执行会浪费资源)

      1)间断性:程序共享系统的资源,以及为完成同一个任务共同合作,并发执行的程序之间相互制约,(不是运行完一个在运行另一个)

      2)失去封闭性:各程序共享系统资源,资源的状态由各程序所决定。

      3)不可再现性:由于失去了封闭性,(即初始的环境状态和条件相同,程序的执行结果却可能不同),该特征超级垃圾,必须想办法避免。

    • 进程的概念:

      具有独立功能的程序在某一个数据集合上的执行过程,它是系统进行资源分配和调度的一个独立单位。

    • 进程的特征:

      • 结构特征:

        PCB(进程控制块),与进程共存亡,用于记录进程的基本情况和活动过程,一般常驻内存
        程序段(一般为需要的时候动态调入内存),描述要完成的功能
        数据段(一般为需要的时候动态调入内存),操作的对象即工作区
      • 动态性:进程最基本的特征,进程不是静态的,而是动态的,它由创建而产生,由调度(这里主要指进程调度,而不是作业调度)而执行,由撤销而消亡

      • 并发性:指多个进程实体存于内存中,且能在同一时间段内执行,(这里同操作系统的并发性)

      • 独立性:进程实体是一个能独立运行,独立获得资源和独立接收调度的基本单位

      • 异步性:同操作系统的异步性

    • 进程的三种基本状态:

      • 就绪状态:进程已经分配到除了CPU之外的所有资源,只要获得CPU便可以立刻执行,处于就绪状态的进程维持一个就绪队列。
      • 执行状态:已经获得CPU,正在执行的进程。(单处理机系统中,同一时刻只能有一个进程处于执行状态,多处理机系统中,可以同时有多个进程处于执行态)
      • 阻塞状态/等待状态:在执行的过程中由于发生某些事件(I/O请求,申请缓存等),暂时无法执行的进程,是由于进程本身引起的阻塞。处于阻塞状态的进程可以维持一个阻塞队列。
      • 进程是自己阻塞自己的,但是阻塞的进程需要其他进程将其唤醒
    • 三种基本状态的转换:

     

    ​ 就绪—>执行:进程调度,获得CPU资源

    ​ 执行—>就绪:在分时操作系统中时间片花完

    ​ 执行—>阻塞:I/O请求,申请缓存等,自己被迫进入阻塞状态

    ​ 阻塞—>就绪:I/O完成,造成阻塞的原因得到解决(又变成只差CPU的状态)

    • 进程的创建状态和终止状态

      创建状态:进程成为就绪状态之前的状态

      终止状态:当一个进程到达了自然结束点,或者遇到无法客服的困难,或者被操作系统所终结等的时候,就进入了终止状态。

    • 挂起操作及引入的原因:

      1)进程被挂起之后处于静止状态。

      2)引入的原因:

      • 终端用户的需要:当终端用户想要暂停自己程序的运行的时候
      • 父进程请求:当父进程想要挂起某个子进程的时候
      • 负荷调节的需要:当实时系统中的工作负荷较重,系统可以将某些不重要的进程挂起,保证程序的正常运行。
      • 操作系统的需要:操作系统有事需要将某些进程挂起,已检查运行过程中资源的使用情况

      3)引入挂起操作后,进程的状态转换:

       

      (1)阻塞态可以通过释放变为就绪态。活动阻塞释放变为活动就绪,静止阻塞释放变为静止就绪。

      (2)活动态和静止态可以进行相互转换,活动到静止称为挂起,静止到活动可以称为激活。活动态和静止态最本质的区别为活动态在内存中,静止态暂时调出内存,进入外存

      (3由执行态可以直接变为静止就绪态,即时间片用完,直接调离内存

      (4)静止态(外存)必须通过激活变为非静止态(调入内存)才能够参与进程的三台转换。

      4)进程挂起之后不是原封不动的将进程移出内存,而是会先将一些必要的信息写入外存。再释放PCB

    • 进程管理中的数据结构

      • 操作系统中用于管理控制的数据结构:内存表,设备表,文件表,进程表(程序控制快PCB)

      • 进程控制块PCB的作用:

        1)作为独立运行基本单位的标志

        2)能实现间断性的运行方式

        3)提供进程管理所需要的全部信息

        4)提供进程调度所需要的全部信息

        5)实现与其他进程的同步和通信

      • 进程控制块中的信息:

        进程标识符:唯一表示一个进程,有两种:

        1)外部标识符:方便用户对进程的访问,通常有数字和字母组成

        2)内部标识符:方便系统对进程的访问,每一个进程有一个唯一的数字标识符。

        处理机状态:(主要指的是处理机中寄存器的状态)

        1)通用寄存器:又称为用户寄存器,用户的程序可以访问,用于暂存信息,一般为8~32个

        2)指令计数器:存放了将要访问的下一条指令的地址。

        3)程序状态字(PSW​):含有状态信息,条件码,执行方式(指在系统还是用户状态下执行),中断屏蔽标志(允不允许在执行的过程中被打断)

        4)用户栈指针:每个用户进程都有系统栈,用于存放过程和系统调用参数及调用地址。

        进程调度信息

        1)进程状态:指明了进程的当前状态

        2)进程优先级:即一个整数,用于描述进程使用CPU的优先级,数字越大,优先级越高

        3)其他信息:与采用的进程调度算法有关

        4)事件:指进程由执行状态变为阻塞状态所等待发生的事件。

        进程控制信息

        1)程序和数据的地址:由于程序段和数据段并不是常驻内存的,而是使用的时候才调入,因此需要保存其地址

        2)进程同步和通信机制:

        3)资源清单:一张清单列出了该进程在运行期间所需的全部资源(除了CPU资源),另一张列出了分配到该进程的资源的清单。

        4)链接指针:给出了本进程(PCB)所在队列中的下一个进程的PCB的首地址。

      • 进程控制块的组织方式:

        线性方式:不重要

        链接方式:类似静态链表,把具有同一状态的PCB用其中的链接字链接成一个队列

       

       

      注:进程资源的分配并不是在该进程执行之前将该进程所需的资源全部分配给他,而是在其执行的过程中进行动态的分配。

    进程与程序的区别与关系

    • 进程与程序的区别:
      • 进程是一个动态的概念(有 “ 生命 ” ),程序是静态的概念。
      • 进程可以具有并行性(在多处理器的系统中),但是程序没有
      • 进程是竞争系统资源的基本单位
    • 进程与程序的关系:
      • 一个程序对应多个进程,一个进程又可以为多个程序服务。

    进程控制

    1.基本知识

    • 进程控制是进程管理中最基本的功能,主要包括进程的创建,进程的终止和运行中的进程的状态转换等功能。进程控制一般是由OS的内核中的原语来实现的。

    2.进程的创建

    • 进程的层次结构

    • 进程图

    • 引起进程创建的事件

      1)用户登录:在分时系统中,用户成功登录,系统将为该用户分配新的进程

      2)作业调度:在多道批处理系统中,作业调度程序将某些作业调度内存,并且为他们创建进程

      3)提供服务:运行中的用户程序提出某种请求

      4)应用请求:由用户进程自己创建,帮助自己完成特定的任务

    • ==进程的创建过程:==OS调用进程创建原语Create创建一个新进程

      1)申请空白PCB:新进程获得一个唯一的数字标识符(对于操作系统)

      2)为新进程分配器运行所需的资源:包括物理资源和逻辑资源

      3)初始化进程控制块PCB:

      (1)初始化标识符信息:系统分配的标识符信息装入PCB

      (2)初始化处理机状态信息:主要为一些寄存器

      (3)初始化处理机控制信息:一般初始化为就绪状态

      (4)如果进程就绪队列允许,将进程插入就绪队列

    3.进程的终止

    • 引起进程终止的事件:

      1)正常结束

      2)异常结束:1)越界错误(访问自己范围外的),2)保护错误(访问自己无权利访问的)3)非法指令:试图运行不存在的指令,4)特权指令;5)运行超时;6)等待超时;7)算术运算错;8)I/O故障

      3)外界的干预:1)操作员或者操作系统干预;2)父进程的请求(父进程的权利大于子进程)3)父进程的终止:当父进程终止时,其所有子进程也应当终止。

    • ==进程终止的过程:==OS调用进程终止原语

      1)根据要终止的进程的标识符,搜索出该进程的PCB,从中获得该进程所处的状态

      2)如果该进程正处于执行状态,立刻终止该进程,并且置调度标志为真,表示在该进程结束后应该进行重新调度(即不要让CPU空闲)

      3)若该进程有子孙进程,让其所有子孙进程都终止。

      4)被终止进程所拥有的所有资源归还给父进程或者操作系统

      5)将终止进程的PCB从所在队列中移除,等待其他程序来收集信息。

    4.进程的阻塞与唤醒

    • 引起进程阻塞和唤醒的事件:阻塞和唤醒是相对应的

      1)向系统请求共享资源失败

      2)等待某种操作的完成

      3)新数据尚未到达

      4)等待新任务的到达

    • 进程阻塞的过程:进程通过调用阻塞原语block==将自己==阻塞

      1)进入block后立即停止执行

      2)保存现场

      3)将进程控制块中的现行状态改为阻塞,并将PCB插入阻塞队列

      4)转调度程序,进行重新调度

    • 进程唤醒的过程:当阻塞的进程所期待的事件发生时,有关进程(不是本身)调用唤醒原语wakeup,将等待该事件的进程唤醒。唤醒之后进入就绪队列。

      1)将被阻塞的进程从等待该事件的阻塞队列中移除

      2)将PCB的现行状态由阻塞改为就绪

      3)然后再将该PCB插入就绪队列中

      4)转进程调度或者返回

    • block原语和wakeup原语是一对作用刚好相反的原语,必须成对使用。

    5.进程的挂起与激活

    • 进程的挂起过程:当出现了引起进程挂起的事件之后,OS利用挂起原语将指定的进程挂起(即调出内存)

      首先检查进程的状态(不同的状态采取不同的处理方式),若该进程正处于活动就绪状态,将其改为静止就绪态;若该进程处于活动阻塞状态,将该进程改为静止阻塞状态;若该进程处于执行状态,将其改为静止就绪状态,调度程序重新进行调度。

    • 进程的激活过程:

      1)首先将进程从外存调入内存,

      2)检查进程所处的状态,如果进程处于静止就绪,将其改为活动就绪,如果处于静止阻塞,将其改为活动阻塞

      3)检查进程的优先级,如果优先级高,可以进行抢占当前运行进程的资源

    4.进程同步

    1.进程同步的基本概念

    • 进程同步的目的:1)按照一定的规则共享系统资源;2)对多个相关进程在执行次序上进行协调,是程序具有可再现性。

    • 两种形式的制约关系:

      1)间接相互制约关系:多个进程在并发执行时,由于共享系统的临界资源而相互制约,如磁带机,打印机,表格等。(互斥)

      2)直接相互制约关系:多个进程为完成同一任务而相互合作(同步)

    • **临界资源:**一次仅允许一个进程使用的共享资源。例如打印机,磁带机,表格等。

    • 互斥和同步的概念:

      1)互斥:并发的多个进程由于竞争同一资源而产生的相互排斥的关系

      2)同步:进程间共同完成一项任务时直接发生相互作用的关系

    • 临界区:每个进程中访问临界资源的那段代码

    /*一个访问临界资源的循环进程*/
    while(true)
    {
        进入区://对欲访问的临界资源进行检查,查看其是否正被访问,如果此刻临界资源未被访问,进程便可以进入临界区对临界资源进行访问,并设置它正被访问的标志,如果此刻临界资源正被访问,则不能进入临界区。即后边的wait()操作
        临界区://执行临界资源的那段代码
        退出区://将临界区正被访问的标志恢复为未被访问的标志,signal()操作
        剩余区://除上述三个区之外的代码叫做剩余区
    }
    • 同步机制应遵循的原则:

      1)空闲让进

      2)忙则等待

      3)有限等待:不能一直等

      4)让权等待:进程不能进入临界区,就应当释放==处理机==,让权指让出处理机

    2.硬件同步机制

    3.信号量机制:Dijkstra提出

    • 信号量:

      • 是一种数据结构
      • 值与相应资源的使用情况有关
      • 仅与P,V操作有关,P,V代表两种原子操作,P为等候原语wait(S),V为释放原语signal(S)。
      • wait操作即在申请资源,signal操作是释放资源
      • wait操作其实就是进入临界区之前的进入区,signal操作是从临界区出来之后的退出区
      • 原子操作的特点,操作一开始执行,半中间不可以打断,原语即为原子操作。
    • 整型信号量

      • 概念:Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S。
      /*等候原语*/
      wait(S){
          while(S <= 0);  //当S<=0的时候便一直处于等待状态,直到获得相应的资源,不符合让权等待的原则      
          S--;     //获得资源后,资源的数目减一,S表示该类资源可用的数目      
      }
      
      /*释放原语*/
      signal(S){
          S++;      //释放资源后,资源的数目加一     
      }
      • 优缺点:

        优点:实现简单

        缺点:违背了同步机制中的让权等待原则,浪费资源(只要S<=0,就会等待)

    • **记录型信号量:**当前用的最多的

      • 特点:采用了记录型的数据结构
      /*记录型数据结构*/
      typedef struct{
          int value;      //>=0的时候,表示系统中可用资源的数量,<0的时候其绝对值表示因为该资源而阻塞的进程的数目
          struct process_control_block *list;    //维持阻塞队列的指针
      }semaphore;
      
      /*等待原语*/
      wait(semaphopre *S){
          S->value--;    //一个进程过来,首先将S->value--;
          if(S->value < 0){     //<0表示资源已经用光,将该进程加入阻塞队列
              block(S->list);
          }
      }
      
      /*释放原语*/
      signal(semaphore *S){
          S->value++;      //释放资源,S->value++;
          if(S->value <= 0){      //S->value++之后,还<=0,直接唤醒一个阻塞的进程,唤醒的进程拥有了该资源的使用权(不需要再次执行P操作),然后进入就绪队列。如果>0,直接将资源释放即可
              wakeup(S->list);
          }
      }
      • wait操作:每次都相当于进程请求一个单位的该类资源

        signal操作:每次都相当于释放一个单位资源

      • 当S->value的初值为1的时候,表示只允许一个进程访问临界资源,信号量转化为互斥型信号量

      • 优点:通过维持阻塞队列的指针,使得满足了让权等待的原则,弥补了整型信号量的缺点

      • **缺点:**只适用于对单一资源的管理,如果一个进程需要请求多类资源的时候,很容易产生死锁。

    • AND型信号量:解决记录型信号量会发生的死锁的问题

      • 当一个进程需要两个或者更多的共享资源来完成一个目标的时候,多个进程之间可能会发生阻塞(刚开始前半部分资源占有了,但是后半部分资源无法获得,自己再阻塞自己,即发生了死锁)
      • AND的解决思想:将一个进程运行过程中所需要的全部资源一次性都分给他,待进程使用完之后,在一起进行释放。(即一起申请,一起释放)
      /*等候原语:全分配*/
      Swait(S1, S2, …, Sn)
       {
          While(TRUE)
          {
              //多类资源同时满足的时候才进行分配,先判断再分配。
          	if (S1 >=1 and … and Sn>=1 ){
                	for( i=1 ;i<=n; i++) Si - -;
      			break;
      		}
              else{
                  Place the process in the waiting queue associated with the first Si found with Si <1,and set the progress count of this process to the beginning of Swait operation	(将即将阻塞的进程挂到第一个不能满足他的资源的阻塞队列,然后设置该进程的起始地址为Swait操作的开始)
              }
          }
      }
      
      /*释放原语:全释放*/
      Ssignal(S1, S2, …, Sn){
      	while(TRUE){    
      		for (i=1; i<=n; i++) {
                  Si++ ;
                  Remove all the process waiting in the queue associated with Si into the ready queue(将因为该资源得不到满足而阻塞的所有进程都从阻塞队列释放进入就绪队列,重新进行排队)
        		 }
      	}
      }

      注意:

      1)在分配资源的时候首先判断是否所有资源均全部满足相应的条件,满足才进行分配。

      2)释放的时候是将因为该资源得不到满足而阻塞的所有进程都从阻塞队列释放进入就绪队列,重新进行排队,因为OS需要根据调度算法重新选取新的进程占据CPU

    • 信号量集

    Swait(S1, t1, d1; …; Sn, tn, dn)
        if (S1>= t1 and … and Sn>= tn) then
            for i:=1 to n do
               Si:= Si - di ;
            endfor
        else
           Place the executing process in the waiting queue of the first Si with Si < ti and set its program counter to the beginning of the Swait Operation
        endif

    注意:

    1)继承了AND型信号量的思想,先判断是否所有所需资源均满足条件。满足才进行分配。

    2)引入了下限值的概念。Si表示可用的资源的数量;ti表示想要分配资源成功至少需要的该资源的数目(ti(下限值)包括两部分,一部分是系统执行该进程所需,另一部分是该进程所请求的,因此一般大于di);di表示该进程所请求的该类资源的数目。

    4.信号量的应用

    1、利用信号量实现进程互斥

    semaphore  mutex =1;
        begin
        parbegin
            process 1: begin
                            repeat
                                wait(mutex);
                                critical section
                                signal(mutex);
                                remainder section
                            until false;
                        end
            process 2: begin
                            repeat
                                wait(mutex);
                                critical section
                                signal(mutex);
                                remainder section
                            until false; 
                        end
        parend        
        end

    注意:

    1)利用信号量实现进程互斥地访问某种资源。首先应将mutex设为1

    2)wait操作和signal操作必须成对地出现,如果缺少wait操作可能会造成系统的混乱;如果缺少signal操作,那么该资源永远不会得到释放,因该资源而被阻塞的进程也将永远不会被唤醒。

    2、利用信号量实现前驱关系图(进程同步)

    如下图:

    semaphore  a, b, c, d, e, f, g = 0, 0, 0, 0, 0, 0, 0;
        begin
            parbegin
                begin  S1; signal(a); signal(b); end;
                begin  wait(a); S2; signal(c); signal(d); end;
                begin  wait(b); S3; signal(e); end;
                begin  wait(c); S4; signal(f); end;
                begin  wait(d); S5; signal(g); end;
                begin  wait(e); wait(f); wait(g); S6; end;
            parend
        end

    注意:

    1)信号量的初值必须被设置为0,必须等某个进程之前的进程完之后,释放资源,后边的进程才能够执行。

     

    经典的进程同步问题

    普通版:一类进程作为生产者,生产产品,生产的产品放入一个缓冲区,消费者从缓冲区中取出产品,需要保证生产者不可以向满的缓冲区中添加产品,消费者不可以从空的缓冲区中取出产品。同一时刻只可以有一个生产者生产产品或者消费者消费产品。

    升级版可以实现同一个时刻既有生产者生产产品,又有消费者消费产品。但是绝对不可以同一时刻多个生产者生产产品或者多个消费者消费产品。同时使用count记录缓冲区中产品的数量。

    • 生产者消费者问题

      1)生产者进程和消费者进程都以异步方式运行, 但它们之间必须保持同步。

      2)可利用互斥信号量$mutex$实现诸进程对缓冲池的互斥使用(不可以同时既向缓冲区中放入数据,又从缓冲区中拿出数据);利用资源信号量empty和full分别表示缓冲池中空缓冲池和满缓冲池的数量。 假定这些生产者和消费者相互等效

      /*
      in表示放入数据的地址,out表示取出数据的地址
      buffer[n]:表示大小为n的缓冲池(由多个缓冲区组成) 
      mutex,mutex1,mutex2:互斥型信号量,初值为1
      empty,full:资源型信号量,empty表示空缓冲区的数量,full表示满缓冲区的数量
      item:表示一个数据项
      */
      Int in=0,out=0;  
      Item buffer[n];   
      Semaphore mutex1=1,mutex2 = 1,empty=n,full=0;  
      
      //生产者
      Void producer(){ 
       	do{
      		生产一个产品放入nextp;
              
              /*
               * 进入区
               * 先申请资源信号量,在申请互斥信号量
               * mutex1控制同一个时间段内只能有一个生产者生产产品
               */
      		wait(empty);
      		wait(mutex1);
              
              /*临界区*/
      		buffer[in]=nextp;
      		in=(in+1) % n;
              
              /*退出区*/
      		signal(mutex1);
      		signal(full);
              
              /*对计数器count的互斥访问*/
              wait(mutex);
              count++;
              signal(mutex);
      	}while(TRUE)
      }
      
      //消费者
      Void consumer(){ 
          do{
             /*进入区*/
      	   wait(full);
      	   wait(mutex2);     //消费者对缓冲区的互斥访问
             
             /*临界区*/
      	   nextc =buffer[out];          //只有一份
      	   out =(out+1) mod n;
              
             /*退出区*/
      	   signal(mutex2);
      	   signal(empty);
              
              /*对计数器count的互斥访问*/
              wait(mutex);
              count--;
              signal(mutex);
      	   消费 nextc中的产品;                        
      	}while(TRUE)
      }
      
      
      Void main(){
      	cobegin
      	    proceducer();
       	    consumer();
      	coend
      }

      注意:

      1)每个程序的互斥操作wait()和signal()必须成对的出现。

      2)输入进程不可以向满的缓冲池中输入数据,计算进程不可以从空的缓冲池中取数据

      3)在每个程序中的多个wait操作顺序不能颠倒,必须先执行对资源信号量的wait操作,在进行对互斥信号量的wait操作,否则可能引起进程死锁。

      4)可以使用三个互斥信号量mutex、mutex1、mutex2实现同一时刻既有生产者生产,又有消费者消费。

    • 读者—写着问题

      该问题涉计两类进程,第一类进程是读进程Reader,另一类进程是写进程Writer,多个读进程可以同时读一个文件(共享资源),多个写的进程不可以同时写一个文件(对写互斥),并且读的时候不能写,写的时候不能读(对读互斥)。

      1)问题核心:保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。

      2)只要求读文件的进程称为“Reader进程”,其它进程则称为“Writer进程”。

      3)允许多个进程同时读一个共享对象,但不允许一个Writer进程和其他Reader进程或Writer进程同时访问共享对象(共享对象并不是临界资源,因为他允许多个进程对其访问)

      /*
      记录型信号量解决读者—写者问题
      
      rmutex:读进程对Readcount的互斥
      wmutex:writer对reader和writer的互斥
      readcount:表示正在读的进程数目,只有当readcount=0的时候才需要申请wmutex权限,大于0的时候不需要
      */
      
      semaphore rmutex=1, wmutex =1;
      int readcount =0;
      Void Reader(){
      	do{
      		wait(rmutex);          //防止多个reader进程对readcount的访问
      		if (Readcount==0){    //如果readcount不等于0,表示有进程正在进行读操作,绝对没有写操作
      			wait(wmutex);
      		}
      		Readcount ++;
      		signal(rmutex);
      		…
      		读;
      		…
      		wait(rmutex);
      		Readcount - -;
      		if (Readcount==0){      //只有等于0的时候才需要释放资源,使得写进程可以工作
      			signal(wmutex);
      		}
      		signal(rmutex);
      	}while(TRUE);
      }
      Void writer(){
          do{
              wait(wmutex);      //申请写权限的资源
              写;
              signal(wmutex);
          }while(TRUE);
      }
      
      Void main(){
          cobegin
             reader();  writer();
      	Coend
      }

      利用信号量集的机制实现读者-写者问题

      int RN;
      semaphore L = RN;             //表示读者的数量
      mx = 1;						//对写者进行互斥的访问
      
      void Reader(){
          while(true){
              Swait(L, 1, 1);         //申请一个读者进程
              Swait(mx, 1, 0);       //判断当前是否有写者进程在写,该出相当于一个开关
              
              operation...
                  
              Ssignal(L, 1);
          }
      }
      
      void Writer(){
          while(true){
              //此处首先申请一个mx,如果当前系统中无写者进程,则该语句必定执行成功,Reader进程中的
              //Swait(mx, 1, 0)便处于关闭状态,只需要等系统中的读进程执行完毕,(L, RN,0)执行成
              //功,打开开关即可。
              Swait(mx, 1, 1; L, RN, 0);
              
              operation...;
              
              //释放一个写进程
              Ssignal(mx, 1);
          }
      }
      
      void main(){
          cobegin
              Reader();
          	Writer();
          coend;
      }

       

    • 哲学家的进餐问题

      五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在桌子上有五只碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。

      /*
      记录型信号量解决问题
      */
      //每一只筷子均为临界资源
      semaphore chopstick[5]={1,1,1,1,1};
      //所有的信号量均被初始化为1,第i位哲学家的活动可描述为:
      do{
      	wait(chopstick[i]);          //拿左手的筷子
      	wait(chopstick[(i+1) mod 5] );      //拿右手的筷子
      	…
      	eat;
      	…
      	signal(chopstick[i]);    //放左手
      	signal(chopstick[(i +1)mod 5]);       //放右手
      	…
      	think;
      }while(TRUE);

      存在的问题:假如五位哲学家同时饥饿而各自拿起左边的筷子时,就会使五个信号量chopstick均为0,当他们再试图去拿右边的筷子时,都将因无筷子可拿而无限等待。进入死锁状态。

      解决办法:

      **1)**至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕后释放出他用过的两只筷子,从而使更多的哲学家能够进餐。

      semaphore chopstick[5]={1,1,1,1,1};
      semaphore count=4;
      void philosopher(int i)
      {
          while(true)
          {
              think();
              wait(count); //请求进入房间进餐
              wait(chopstick[i]); //请求左手边的筷子
              wait(chopstick[(i+1)%5]); //请求右手边的筷子
              eat();
              signal(chopstick[(i+1)%5]); //释放右手边的筷子
              signal(chopstick[i]); //释放左手边的筷子
              signal(count); //退出房间释放信号量
          }
      }

      **2)**仅当哲学家的左右两只筷子均可用时,才允许他拿起筷子进餐。

      /*
      使用AND型信号量解决,本质当同时拥有两只筷子的时候才允许拿起筷子进餐
      */
      semaphore chopstick[5]={1,1,1,1,1};
      Philosopher i
      do{
      	think;
      	Swait(chopstick[(i+1)mod 5],chopstick[i ]);     //同时分配两只筷子
      	eat;
      	Ssignal(chopstick[(i+1)mod 5], chopstick[i ] );     //同时放下两只筷子  
      }while(TRUE)

      **3)**规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;偶数号哲学家则相反。

      semaphore chopstick[5]={1,1,1,1,1};
      //第i 位哲学家的活动可描述为:
      do{
          //奇数位哲学家先拿左手的筷子
      	if  i mod 2=1 {
      		wait(chopstick[ i ]);
      		wait(chopstick[ ( i +1) mod 5] )
      	}
          //偶数位哲学家先拿右手边的筷子
      	else
      	{
      		wait(chopstick[ ( i +1) mod 5] );
      		wait(chopstick[ i ])
      	}
      	eat;
      	signal(chopstick[ i ]);
      	signal(chopstick[(i +1)mod 5]);
      	…
      	think;
      }while(TRUE)

    处理机调度

    1. 调度层次
      1. 高级调度(作业调度)
      2. 中级调度(进程调度)
      3. 低级调度
    2. 作业调度
      1. FCSF先来先服务,作业等待时间得长短。比较有利于长作业(进程),而不利于短作业(进程)。
      2. SJF短作业优先,作业的运行时间。
        1. 优点:能有效的降低作业的平均等待事件,提高系统吞吐量。
        2. 缺点:对长作业不利;该算法完全未考虑作业的紧迫程度,因而不能保证紧迫性作业(进程)会被及时处理;由于作业(进程)的长短含主观因素,不一定能真正做到短作业优先。

      1. 高响应比优先  

    优先权=等待时间+要求服务时间/要求服务时间

      1. RR轮转调度算法,时间片的确定要适中
      2. 多级反馈队列
      3. EDF最早截至时间优先

    下图中有两个周期性任务,任务A的周期时间为20ms,每个周期的处理时间为10ms;任务B的周期时间为50ms,每个周期的处理时间为25ms

      1. LLF最低松弛度优先

    松弛度=必须完成时间-其本身的运行时间-当前时间

    进程切换条件:有任务完成;有任务松弛度降到0。

    1. 死锁
      1. 定义:是指多个进程在运行过程中因为争夺资源而造成的一种僵局,当进程处于这种状态时,若无外力作用,他们都将无法再向前推进
      2. 原因:竞争资源(不可抢占资源,可消耗资源),进程间推进顺序非法。
      3. 产生死锁得必要条件:互斥条件、请求和保持条件、不可抢占(不可剥夺)条件、环路等待条件
      4. 处理死锁的基本方法:
        1. 预防死锁:破坏产生死锁得必要条件,其中破坏互斥条件是最不实际的
          1. 破坏“请求和保持”条件:系统规定所有进程在开始运行之前,都必须一次性的申请其在整个运行过程所需的全部资源
          2. 破坏“不剥夺”条件
          3. 破坏“环路等待”条件:所有进程对资源的请求必须严格按照资源序号递增的次序提出
        2. 预防死锁:银行家算法、安全性算法
        3. 检测死锁:资源分配图,死锁定理
        4. 解除死锁:剥夺资源(从其他进程剥夺足够数量的资源给死锁进程以解除死锁状态。),撤销进程(最简单的是让全部进程都死掉;温和一点的是按照某种顺序逐个撤销进程,直至有足够的资源可用,使死锁状态消除为止。)
    2. 银行家算法
      1. 安全状态

      1. 银行家算法

    T0时刻的安全性:用安全性算法对T0时刻的资源分配情况进行分析,存在着一个安全序列{P1,P3,P4,P2,P0},故系统是安全的

    P1发出资源请求向量Request1(1,0,2),系统按银行家算法检查:

    (1)Request1(1,0,2)<=Need1(1,2,2)

    (2)Request1(1,0,2)<=Available1(3,3,2)

    (3)系统先假定可为P1分配资源,并修改向量Available,Allocation1,Need1

    (4)再利用安全性算法检查此时系统是否安全。如下表:

    由安全性检查得知,能找到一个安全序列{P1,P3,P4,P0,P2},因此,系统是安全的,可以立即将P1所申请的资源分配给它。

    死锁定理:S状态为死锁状态的充分条件是当且仅当S状态的资源分配图是不可完全简化的。<死锁定理>

     

    存储器

    重定位

    程序的装入

    1. 绝对装入方式
    2. 可重定位的装入方式(静态)
    3. 动态运行时装入方式(动态)重定位寄存器

    内存的分配方式

    1. 连续的分配方式
    2. 离散的分配方式

    连续的分配方式

    1. 单一连续分配:一道程序在内存中,内存浪费严重
    2. 固定分区分配:程序变多缺点:会产生内碎片
    3. 动态分区分配(重点)不能消除外碎片  思想:按需分配
    4. 可重定位的分区分配
      1. 在动态分区分配方式上增加一个紧凑(拼接碎片)功能
      2. 以动态运行时装入方式为前提

    动态分区分配算法​

    首次适应算法FF

        FF算法要求空闲分区表以地址递增的次序排列。在分配内存时,从表首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲分区表中。若从头到尾不存在满足要求的分区,则分配失败。

    优点:优先利用内存低址部分的内存空间

    缺点:低址部分不断划分,产生小碎片(内存碎块、内      存碎片、零头);每次查找从低址部分开始,增      加了查找的开销

    循环首次适应算法NF

    在分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业。

    优点:使内存空闲分区分布均匀,减少查找的开销

    缺点:缺乏大的空闲分区

    最佳适应算法BF

    所谓“最佳”是指每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作业,避免“大材小用”。要求将所有的空闲分区按其容量以从小到大的顺序形成一空闲分区链。

        缺点:产生许多难以利用的小空闲区

    离散的分配方式

    分页存储管理方式

    (可能在最后一页产生内碎片)进程分页,内存分块(页和块等大小) 

    页表

     

     

     

    页式地址映射

    (逻辑地址转换城物理地址)

     

     

     

     

    地址转换机构(页表在内存,页表寄存器快表。页表很庞大时采取两级或多级页表)

    有快表有页表,先查快表;没有快表查页表

     

     

     

    分段存储管理方式

    (不可能有内碎片产生,外碎片不可避免)进程分段,各段在内存。段与段之间离散分配,某一段在内存中连续分配
    计算:给定逻辑地址合成物理地址段表

     

    段页式存储管理方式

    进程分段,段内分页,内存分块

      1. 分页和分段的主要区别

    相似点:采用离散分配方式,通过地址映射机构实现地       址变换

    不同点:页是信息的物理单位,分页是为了满足系统的    需要;段是信息的逻辑单位,含有一组意义相对完    整的信息,分段是为了满足用户的需要。

    页的大小固定且由系统确定,由系统把逻辑地址分为页号和页内地址,由机器硬件实现;段的长度不固定,取决于用户程序,编译程序对源程序编译时根据信息的性质划分。

    分页的作业地址空间是一维的;分段的作业地址空间是二维的。

    输入输出系统

    I/O设备:输入输出和存储功能的设备

     

    I/O设备的分类

    按传输的速度:

    低速设备(如键盘、鼠标、语音输入输出设备)  中速设备(如行式打印机、激光打印机等)

    高速设备(如磁带机、磁盘机、光盘机等)。

     

    设备按信息交换的单位分类

    块设备:用于存储信息。对于信息的存取总是以数据块为单位。典型例子是磁盘。该类设备基本特征是传输速率较高,另一特征是可寻址。

    字符设备:用于数据的输入和输出。基本单位是字符。如交互式终端、打印机等。其基本特征是传输速率较低,另一特征是不可寻址。

     

    设备按其共享属性分类

    独占设备:指在一段时间内只允许一个用户、进程访问的设备,即临界资源。应互斥的访问之。

    共享设备:指在一段时间内允许多个进程同时访问的设备。对每一时刻而言仍然是一个进程访问。如磁盘。

    虚拟设备:指通过虚拟技术将一台独占设备变换为若干台逻辑设备,供若干个用户(进程)同时使用。

     

    设备按其使用特性分类:

    存储设备、输入\输出设备

     

    I/O通道

    其主要目的是为了建立独立的I/O操作,去解放CPU。在设置通道后,CPU只需向通道发送一条I/O指令。通道完成任务后向CPU发中断信号。

    控制功能:CPU与设备控制器

    数据传输:内存与外设

    I/O控制方式

    1. 程序I/O方式,使用轮询的可编程I/O方式。CPU浪费
    2. 终端驱动I/O方式,使用中断的可编程I/O方式。CPU用较短的时间进行中断处理。
    3. 直接存储器访问方式(MDA),以数据块为单位,高效。缺点:不连续的数据块,不能一次处理
    4. I/O通道控制方式,通道时硬件,配合着通道程序

    设备分配

    1. 前提:大中型计算机
    2. DS:设备控制表、控制器控制表、通道控制表、系统设备表
    3. 独占设备分配步骤:分配设备、分配控制器、分配通道

    SPOOLing技术(假脱机)

    定义

    为缓和CPU的高速性与I/O设备低速性间的矛盾而引入了脱机输入、脱机输出技术。该技术是利用专门的外围控制机,将低速设备上的数据传送到高速磁盘上;或者相反。这样就可以在主机的直接控制下实现脱机输入输出。此时外围操作与CPU对数据的处理同时进行,我们把这种在联机情况下实现的同时外围操作称为SPOOLing(Simultaneaus Periphernal Operating On—Line),或称为假脱机操作。

     

    组成

    1. 输入井和输出井。是磁盘上开辟的两个大存储空间。输入井模拟脱机输入的磁盘设备,输出井模拟脱机输出时的磁盘。
    2. 输入缓冲区和输出缓冲区。在内存中开辟两个缓冲区,输入缓冲区暂存由输入设备送来的数据,后送输入井;输出缓冲区暂存从输出井送来的数据,后送输出设备。
    3. 输入进程和输出进程。利用两个进程模拟脱机I/O时的外围处理机。
    4. 井管理程序。用于控制作业与磁盘井之间信息的交换。

    特点

    1. 提高了I/O的速度。利用输入输出井模拟成脱机输入输出,缓和了CPU和I/O设备速度不匹配的矛盾。
    2. 将独占设备改造为共享设备。并没有为进程分配设备,而是为进程分配一存储区和建立一张I/O请求表。
    3. 实现了虚拟设备功能。多个进程同时使用一台独占设备,虚拟成了多台设备。
      1. 打印机是独占设备,通过虚拟技术实现“共享”的模拟
    • 缓冲区管理
    1. 引入
      1. 缓和CPU与I/O设备间速度不匹配矛盾。
      2. 减少对CPU的中断频率,放宽对CPU中断响应时间的限制
      3. 提高CPU和I/O设备之间的并行性。

    方法

    1. 单缓冲(效率低)
    2. 双缓冲区(效率比较高,当输入输出速度不匹配时效率受影响)
    3. 循环缓冲区(解决输入和输出速度相差甚远的影响)
    4. 缓冲池(解决多进程缓冲过程中内存利用率的问题)

    磁盘管理

    9个进程先后提出读盘请求访问的磁道号为:55;58;39;18;90;160 150 38 184目前磁头停留在100道。

     

    先来先服务(FCFS)

    1. 优点:公平、简单
    2. 缺点:未对寻道进行优化

         

     

    最短寻道时间优先(SSTF)

    1. 优点:寻道优化
    2. 缺点:可能导致某些进程发生“饥饿”。

          

     

    扫描SCAN算法

    1. 优点:较好的寻道性能
    2. 缺点:“不巧”的进程严重推迟

            

     

    循环扫描算法CSCAN

    1. 优点:进程的延迟变小了

     

    FSCAN算法本算法是N-Step-SCAN算法的简化。

     

    文件管理

    展开全文
  • Android消息循环机制

    万次阅读 2016-06-19 01:56:37
    转载请注明出处:...实际上应用程序启动的时候,会创建一个UI线程,然后该线程关联一个消息队列,相关操作封装一个个消息放入队列中,主线程会不断循环从队
  • 循环神经网络教程-第一部分 RNN介绍

    千次阅读 2016-12-29 15:11:02
    循环神经网络教程-第一部分 RNN介绍循环神经网络(RNNs)是非常流行的模型,它在许多NLP任务上都表现出了巨大的潜力。虽然它很流行,但是详细介绍RNNs以及如何实现RNNs的文章却很少。这篇教程旨在解决上述问题,教程...
  • 本文目录Python语言设计编写的成绩管理系统基本要求具体要求合理的创建标题,有助于目录的生成分析要求实现功能如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建...
  • 相信大部分人在做这些题的时候,因为书中没有给答案,而去网上找参考答案,比如那些高阅读量的博客和git。当然,我也是这样,但他们的答案中还是有好多错误,比如3.59他们几乎都没讲清楚提示中的公式怎么来的,3.60...
  • 一代、二代、三代测序技术原理与比较

    万次阅读 多人点赞 2017-11-10 14:08:02
    从1977年第一代DNA测序技术(Sanger法)1,发展至今十多年时间,测序技术已取得了相当的发展,从第一代到第代乃至第四代,测序读长从长到短,再从短到长。虽然就当前形势看来第二代短读长测序技术在全球测序...
  • 传统DNN或者CNN无法对时间序列上的变化进行建模,即当前的预测只跟当前的输入样本...循环神经网络RNN包含循环的网络,可以记录信息的持久化信息,特别适合应用在跟时间序列相关的场合。   RNN之父Jürgen
  • 计算机级嵌入式系统知识点考查(易错)

    千次阅读 多人点赞 2020-09-09 12:52:19
    1、目前32位嵌入式处理器主要采用的是ARM内核处理器,是由英国一家专门从事RISC...4、按向量地址从小到排列的顺序是:复位RESET、未定义指令UND、软件中断SWI、指令预取中止PABT、数据访问中止DABT、外部中断请求
  • 而现实环境中大部分项目可能会使用ZooKeeper,那是因为集群不够大,并且基本不会遇到用做注册中心的机器一半以上都挂了的情况。所以实际上也没什么大问题。 Hystrix原理(待查) 通过维护一个自己的线程池,当线程池...
  • 写给忙人看的操作系统

    万次阅读 多人点赞 2020-02-28 12:34:12
    现代计算机系统由一个或多个处理器、主存、打印机、键盘、鼠标、显示器、网络接口以及各种输入/输出设备构成。 然而,程序员不会直接和这些硬件打交道,而且每位程序员不可能会掌握所有计算机系统的细节,这样我们...
  • 操作系统知识点整理(完整版)

    万次阅读 多人点赞 2017-12-26 22:34:05
    1)一个完整的计算机系统是由硬件系统和软件系统大部分组成 2)计算机软件是指程序和与程序相关的文档的集合 3)按功能可把软件分为系统软件”和“应用软件”两部分 系统软件:操作系统语言处理程序,数据库管理...
  • 《计算机操作系统》总结(内存管理)

    千次阅读 多人点赞 2015-09-23 21:15:47
    内存管理 包括内存管理和虚拟内存管理。 内存管理包括内存管理概念、交换与覆盖、连续分配管理方式和非连续分配管理方式(分页管理方式、...内存管理(Memory Management)是操作系统设计中最重要和最复杂的内容之一。虽
  • 层架构

    万次阅读 多人点赞 2014-04-27 15:16:27
    首先要知道层不是一项实际的技术、他是一中设计软件的思想、这种思想就是把软件分为三层、或者说个类、分别是表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)、分层的目的是为了高内聚,低耦合、便于更改...
  • 的方面来说,Android系统的启动可以分为两个部分:第一部分是Linux核心的启动,第二部分是android系统的启动。第一部分主要包括系统引导,核心和驱动程序等,由于它们不属于本篇要讲的内容,这里就不再讨论。在...
  • 计算机级嵌入式综合题解密+部分总结

    千次阅读 多人点赞 2019-09-15 11:08:44
    2019年9月21日计算机级嵌入式考试即要开战!都要加油呀!! 今天这篇文章主要指针对...看下面的分析之前可以先看一下这篇文章:计算机级嵌入式系统考试之矩阵键盘 以第套试题为例:按键原理图如下图所示 ...
  • 论语音识别三大关键技术

    万次阅读 多人点赞 2018-05-04 07:47:07
    论语音识别三大关键技术 李万鸿 语音识别已经成为人工智能应用的一个重点,通过语音控制设备简单方便,在各个领域兴起了研究应用的热潮。数据、算法及芯片是语音识别技术的3个关键,大量优质的数据、精准快速的算法...
  • 循环神经网络

    万次阅读 2019-05-25 17:53:21
    今天突然发现百度词条对循环神经网络的解释全面的令人感动,尤其是提到了ESN和LSM这类水库计算模型 链接:...
  • 章 存储管理 1.在图3-3中基址和界限寄存器含有相同的值16384,这是巧合,还是它们总是相等?如果这只是巧合,为什么在这个例子里它们是相等的? 答:这是一个巧合。基址寄存器的值为16384是因为程序恰好在...
  • 游戏开发入门()图形渲染

    万次阅读 多人点赞 2018-01-17 22:15:34
    视频链接:游戏开发入门()图形渲染(3节课 时常:约2小时20分钟) 视频链接:一堂课学会shader——渲染拓展课程(3节课 时常:约1小时20分钟) 笔记与总结(请先学习视频内容): 游戏开发入门()图形...
  • 算法系列之十五:循环和递归在算法中的应用

    万次阅读 多人点赞 2012-05-20 23:11:36
    一、递归和循环的关系 1、 递归的定义 顺序执行、循环和跳转是冯·诺依曼计算机体系中程序设计语言的三大基本控制结构,这种控制结构构成了千姿百态的算法,程序,乃至整个软件世界。递归也算是一种程序控制结构...
  • 深入分析Node.js事件循环与消息队列

    千次阅读 多人点赞 2018-08-03 00:05:44
    框架代码以及用户代码即我们编写的应用程序代码、npm包、nodejs内置的js模块等,我们日常工作中的大部分时间都是编写这个层面的代码。 2.2 binding代码 binding代码或者三方插件(js 或 C/C++ 代码)...
  • 时间 2017-06-27 15:57:39 机器之心 原文 ... 主题 LSTM ...在 LSTM 循环神经网络面临长序列输入时,我们应该怎样应对?Jason Brownlee 给了我们 6 种解决方案。 长短期记忆(LSTM)循
  • Web系统大规模并发处理

    千次阅读 2017-01-23 22:11:57
    一、规模并发带来的挑战  ...一个秒杀或者抢购页面,通常分为2个部分,一个是静态的HTML等内容,另一个就是参与秒杀的Web后台请求接口。 通常静态HTML等内容,是通过CDN的部署,一般压力不大,核心瓶颈实
  • 这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,...作者分析该病毒一个月,一方面觉得自己技术菜,另一方面深知系统安全需要坚持,继续加油。希望文章对您有所帮助~
  • 操作系统题库(选择题部分,带解析)

    万次阅读 多人点赞 2018-06-22 10:59:52
    操作系统题库汇总一、 选择题1.下面的(B)不是文件的存储结构。A.索引文件 B.记录式文件 C.串联文件 D.连续文件顺序文件:包括连续文件和串联文件顺序文件:记录按在其文件的中的逻辑顺序依次存入储存介质而...
  • 信息系统分析与设计课程心得

    万次阅读 2017-02-28 13:41:39
    信息系统分析与设计课程心得此博客为信息系统分析与设计课程的学习心得记录。一、绪论1概念1.1信息要了解信息系统,首先要了解信息的概念。信息是我们理解世界的重要概念,我对它的定义是:信息是对客观事物及其相互...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 217,328
精华内容 86,931
关键字:

循环系统分为三大部分