中断——S5PV210的中断体系简介

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

参考博客

s5pv210的中断体系 - biaohc - 博客园

我的RTOS 之一 --S5PV210 异常向量表基址和软中断测试_liujia2100的博客-CSDN博客

从0开始学ARM-异常及中断处理、异常向量表、swi_一口Linux的技术博客_51CTO博客

一、异常及中断的简介

1、异常的介绍

在ARM体系结构中,存在以下7种异常情况。

异常情况描述
FIQ快速中断
IRQ一般的中断
保留……
Data Abort如果一个预取指令试图存取一个非法的内存单元,这时异常产生
Prefetch Abort当一个指令被从内存中预取时,由于某种原因而失败,如果它能到达执行状态这个异常才会产生
Software Interrupt当一个软中断指令被执行完的时候执行
Undefined Instruction当流水线中的某个非法指令到达执行状态时执行
Reset上电时执行

(1)复位异常(Reset)
当CPU刚上电时或按下reset重启键之后,会进入该异常。该异常在管理模式下处理。

(2)未定义指令异常(Undefined Instruction)
在流水线技术里的译码阶段,如果当前指令不能被识别为有效指令,则产生未定义指令异常。该异常在未定义异常模式下处理。

(3)软件中断指令异常(Software Interrupt)
该异常是应用程序自己调用时产生的,用于用户程序申请访问硬件资源时。

例如:printf()打印函数,要将用户数据打印到显示器上,用户程序要想实现打印必须申请使用显示器,而用户程序又没有外设硬件的使用权,只能通过使用软件中断指令切换到内核态,通过操作系统内核代码来访问外设硬件,内核态是工作在特权模式下,操作系统在特权模式下完成将用户数据打印到显示器上。

这样做是为了保护操作系统的安全和硬件资源的合理使用。该异常在管理模式下处理。

(4)预取指令中止异常(Prefetch Abort)
该异常发生在CPU流水线取指阶段,如果目标指令地址是非法地址进入该异常。该异常在中止异常模式下处理。

(5)数据中止访问异常(Data Abort)
该异常发生在要访问数据地址不存在或者为非法地址时。该异常在中止异常模式下处理。

(6)一般中断请求异常(IRQ)、快速中断请求异常(FRQ)

CPU与外部设备相对独立,CPU对全部设备进行管理和资源调度处理,CPU要想知道外部设备的运行状态,可以让CPU定时查看外部设备的特定寄存器(轮询),或者在需要CPU干涉处理时让外部设备打断CPU(中断),让CPU来处理外部设备的请求。

显然第二种方式更合理,可以让CPU专心工作,这里的“打断”操作就叫做中断请求。

根据请求的紧急情况,中断请求分一般中断和快速中断。绝大部分外设使用一般中断请求。快速中断具有最高中断优先级和最小的中断延迟,通常用于处理高速数据传输及通道的中数据恢复处理,如DMA等。

2、中断的介绍

从上面关于“异常”的描述可知,中断属于异常的一种,分为“快速中断”和“一般中断”。

中断主要用来解决宏观上的并行需求。微观上的并行,指的是真正的并行,即使精确到每一秒甚至每一刻,多个事情还是在同时进行。宏观上的并行,并不等于微观上的并行,有时候宏观上是并行的,微观上是串行的。

单核CPU无法实现微观上的并行,但是通过中断机制,可以实现宏观的并行。

衡量一个操作系统的实时性的指标,包括最短响应中断时间、单位时间内响应中断次数。

3、异常向量表

3.1 异常向量表的定义

CPU事先定义了一些特定地址作为特定异常的入口地址。异常发生时,CPU会根据实际情况把PC的值设置为这些特定地址中的某一个,则CPU接下来会取出并执行这个地址所对应的存储单元里的指令。这指令一般是跳转指令,以跳转到专门处理某个异常的子程序。这些特定异常及其入口地址的对应关键系,就称为异常向量表。

比如定义0x00000000这个地址为复位异常向量地址,当发生复位异常时,CPU会自动跳转到0x00000000地址去执行指令;比如定义0x30000008这个地址为外部中断对应的异常向量地址,当发生外部中断时,CPU会自动跳转到0x30000008地址去执行指令。

所有架构(比如51单片机、PIC单片机)的CPU的中断,都是通过异常向量表实现的,但是不同CPU异常向量表的构造(比如有哪些异常向量、这些异常向量的相对位置)和异常向量表的基地址往往不同。复杂的ARM还可以软件设置异常向量表的基地址。

一个常见的异常向量表设置如下:

相对于基地址的偏移量异常情况
0x1CFIQ
0x18IRQ
0x14保留
0x10Data Abort
0x0CPrefetch Abort
0x08Software Interrupt
0x04Undefined Instruction
0x00Reset

3.2 异常向量表的优先级

优先Reset→Data abort→FIQ→IRQ→Prefetch abort→Undefined instruction / SWI。

3.3 s5pv210的异常向量表

上面所列的常见异常向量表,也是s5pv210的异常向量表,不过要注意以下几点内容。

(1)s5pv210 的异常向量表的基地址

系统刚启动时,SDRAM 还没有初始化,程序都在SRAM中运行,因此s5pv210在SRAM中设置了异常向量表,以供暂时性使用。如下图所示,S5PV210在SRAM中设置的异常向量表的起始地址为0xD003_7400。


(2)s5pv210 的异常向量表的修改

s5pv210 的异常向量表可以修改,以适应操作系统的需求。具体见参考博文二。

二、S5PV210的中断处理流程

1、中断处理的2个阶段

第一个阶段是异常向量表跳转,第二个阶段是进入异常处理程序。

2、中断处理的第一阶段

第一个阶段依赖于CPU设计时提供的异常向量表机制。

主要任务是从异常发生到响应异常并且保存现场,然后跳转到真正的异常处理程序处。

3、中断处理的第二阶段

第二个阶段,主要任务是识别哪个中断源发生了中断,然后调用相应的中断处理程序。

(1)S3C2440的第二阶段处理过程

怎么找到具体是哪个中断?

S3C2440的中断控制器中有一个32位的寄存器,寄存器的每一个位对应一个中断源。为了解决支持更多的中断源,2440又设计了一个子中断机制。在一级中断寄存器中有一些中断共用一个bit位,比如AC97和WDT。对于共用中断,用子中断来区分哪一个发生中断。

怎么找到对应的ISR?

首先给每个中断做了个编号,进入isr_handler之后先通过查阅中断源寄存器和子中断寄存器(中哪一位为1)确定中断的编号,然后用这个编号去isr数组(isr数组是中断初始化时事先设定好的,就是把各个中断的isr的函数名组成一个数组,用中断对应的编号作为索引来查询这个数组)中查阅得到isr地址。

评价好不好?

上面第一个过程中使用子中断搞成2级的很麻烦;第二个过程中计算中断编号也耗费时间,而中断处理的时间是很宝贵的。系统有一个性能指标,叫实时性。实时性就是中断发生到响应的时间,这个时间越短越好。

(2)S5PV210的第二阶段处理过程

怎么找到具体是哪个中断?

S5PV210因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。理论上210最多支持128个中断,实际支持不足128个,因为有些位是空的。S5PV210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个中断源寄存器的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。

怎么找到对应的isr?

S5PV210中支持的中断源很多,如果使用2440的那一套来寻找isr的地址,实时性就不好了。S5PV210提供了很多寄存器来解决每个中断源对应isr的寻找问题。当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,我们软件只要去这个寄存器中执行函数就行了。

(3)总结对比

第一阶段2440和210几乎完全相同,实际上几乎所有的CPU在第一阶段都是相同的。

第二阶段不同。各个SoC根据自身对实时性的要求、中断源的多少,各自发明了寻找中断编号、寻找对应isr地址的方式。

三、S5PV210的中断控制器

这里所说的中断控制器,是指与中断有关的寄存器所组成的集合。

1、 中断使能与禁止寄存器:VICnINTENABLE、VICnINTENCLEAR

(1)VICnINTENABLE 和 VICnINTENCLEAR寄存器,分别负责中断使能与中断禁止。

(2)n=0,1,2,3,对应着四个寄存器,每个寄存器都是32bit,每个bit对应一个中断源是否使能 。 

  • VIC0INTENABLE  VIC0INTCLEAR
  • VIC1INTENABLE  VIC1INTCLEAR
  • VIC2INTENABLE  VIC2INTCLEAR
  • VIC3INTENABLE  VIC3INTCLEAR

如果想启用某个中断,则需要在此中断编号所对应的VICnINTENABLE寄存器的相应的位上写1;如果想禁止某个中断源,则需要在VICnINTENCLEAR寄存器的相应的位写1。

注意,有些CPU可以在同一个寄存器位进行中断使能和禁止的设置,写1使能写0禁止(或者反过来);而有些CPU的中断使能和禁止分开为2个寄存器,要使能中断就写使能寄存器,要禁止中断就写禁止寄存器,这里就是这种情况。

(3)代码示例

//使能中断
//传参intnum表示要启动的某个具体的中断源,中断号在int.h中定义,是物理中断号
void intc_enable(unsigned long intnum)
{unsigned long temp;// 确定intnum在哪个寄存器的哪一位// <32就是0~31,必然在VIC0if(intnum<32){temp = VIC0INTENABLE;temp |= (1<<intnum);		VIC0INTENABLE = temp;}else if(intnum<64){temp = VIC1INTENABLE;temp |= (1<<(intnum-32));VIC1INTENABLE = temp;}else if(intnum<96){temp = VIC2INTENABLE;temp |= (1<<(intnum-64));VIC2INTENABLE = temp;}else if(intnum<NUM_ALL){temp = VIC3INTENABLE;temp |= (1<<(intnum-96));VIC3INTENABLE = temp;}// NUM_ALL : enable all interruptelse{VIC0INTENABLE = 0xFFFFFFFF;VIC1INTENABLE = 0xFFFFFFFF;VIC2INTENABLE = 0xFFFFFFFF;VIC3INTENABLE = 0xFFFFFFFF;}
}

 2、中断模式选择寄存器:VICnINTSELECT

(1)VICnINTSELECT寄存器,用来设置各个中断的模式为IRQ还是FIQ。一般都设置成IRQ。

(2)n=0,1,2,3,对应着四个寄存器,可以设置各个中断的模式。

  • VIC0INTSELECT
  • VIC1INTSELECT
  • VIC2INTSELECT
  • VIC3INTSELECT

(3)IRQ和FIQ的区别

s5pv210支持2种中断,IRQ和FIQ,IRQ是普通中断,FIQ是快速中断。快速中断提供一种更快响应处理的中断通道,用于对实时性要求很高的中断源。CPU提供了一些机制保证FIQ可以被快速处理,从而保证实时性。但是只能有一个中断源被设置为FIQ,其他都是IRQ。

(4)FIQ比IRQ快的原因

FIQ模式有专用的r8~r12,因此中断服务程序可以直接使用r8-r12而不用保存,这就能节省时间。

另外,异常向量表中FIQ是最后一个异常向量入口,因此FIQ模式的中断服务程序不需要跳转,可以直接写在原地,这样就比其他异常少跳转一次,节省一些时间。

(5)代码示例

// 清除需要处理的中断的中断处理函数的地址
void intc_clearvectaddr(void)
{// VICxADDR:当前正在处理的中断的中断处理函数的地址(即isr的入口地址)VIC0ADDR = 0;VIC1ADDR = 0;VIC2ADDR = 0;VIC3ADDR = 0;
}// 初始化中断控制器
void intc_init(void)
{// 禁止所有中断// 为什么在中断初始化之初要禁止所有中断?// 因为中断一旦打开,因为外部或者硬件自己的原因产生中断后一定就会寻找isr// 而我们可能认为自己用不到这个中断就没有提供isr,这时它自动拿到的就是乱码// 则程序很可能跑飞,所以不用的中断一定要关掉。// 一般的做法是先全部关掉,然后再逐一打开自己感兴趣的中断。一旦打开就必须// 给这个中断提供相应的isr并绑定好。VIC0INTENCLEAR = 0xffffffff;VIC1INTENCLEAR = 0xffffffff;VIC2INTENCLEAR = 0xffffffff;VIC3INTENCLEAR = 0xffffffff;// 这里把所有的中断源的中断类型设置为IRQ;其实可以具体到设置每一个中断的中断模式 VIC0INTSELECT = 0x0;VIC1INTSELECT = 0x0;VIC2INTSELECT = 0x0;VIC3INTSELECT = 0x0;// 清VICxADDRintc_clearvectaddr();
}

3、 中断状态寄存器:VICnIRQSTATUS、VICnFIQSTATUS

(1)当发生中断时,硬件会自动将该寄存器的对应位设置为1,以表示发生了中断发。软件在处理中断第二阶段的第一阶段,就是通过查询这个寄存器来得到中断编号的。

(2)n=0,1,2,3,对应着四个寄存器,每个寄存器的每个位表征否发生中断。

  • VIC0IRQSTATUS
  • VIC1IRQSTATUS
  • VIC2IRQSTATUS
  • VIC3IRQSTATUS

(3)代码示例

// 通过读取VICnIRQSTATUS寄存器,判断其中哪个有一位为1,来得知哪个VIC发生中断了
unsigned long intc_getvicirqstatus(unsigned long ucontroller)
{if(ucontroller == 0)return	VIC0IRQSTATUS;else if(ucontroller == 1)return 	VIC1IRQSTATUS;else if(ucontroller == 2)return 	VIC2IRQSTATUS;else if(ucontroller == 3)return 	VIC3IRQSTATUS;else{}return 0;
}// 真正的中断处理程序。意思就是说这里只考虑中断处理,不考虑保护/恢复现场
void irq_handler(void)
{//printf("irq_handler.\n");// SoC支持很多个(在低端CPU例如2440中有30多个,在210中有100多个)中断// 这么多中断irq在第一个阶段走的是一条路,都会进入到irq_handler来// 我们在irq_handler中要去区分究竟是哪个中断发生了,然后再去调用该中断// 对应的isr。// 虽然硬件已经自动帮我们把isr放入了VICnADDRESS中,但是因为有4个,所以我们必须// 先去软件的检查出来到底哪个VIC中断了,也就是说isr到底在哪个VICnADDRESS寄存器中unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};int i=0;void (*isr)(void) = NULL;for(i=0; i<4; i++){// 发生一个中断时,4个VIC中有3个是全0,1个的其中一位不是0if(intc_getvicirqstatus(i) != 0){isr = (void (*)(void)) vicaddr[i];break;}}(*isr)();		// 通过函数指针来调用函数
}

4、中断优先级设置寄存器:VICnVECTPRIORITYm

(1)中断优先级设置寄存器,可以设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。

(2)n=0,1,2,3;m=0,1,…,31

  • VIC0VECTPRIORITY0,VIC0VECTPRIORITY1,…,VIC0VECTPRIORITY31
  • VIC1VECTPRIORITY0,VIC1VECTPRIORITY1,…,VIC1VECTPRIORITY31
  • VIC2VECTPRIORITY0,VIC2VECTPRIORITY1,…,VIC2VECTPRIORITY31
  • VIC3VECTPRIORITY0,VIC3VECTPRIORITY1,…,VIC3VECTPRIORITY31

5、存放中断处理函数首地址的寄存器:VICnVECTADDRm

(1)这些寄存器用来存放(各个中断所对应的)中断处理函数的首地址。

(2)每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的中断处理函数的首地址直接放入这个中断所对应的VECTADDR寄存器即可。

(3)n=0,1,2,3;m=0,1,…,31

  • VIC0VECTADDR0,VIC0VECTADDR1,…,VIC0VECTADDR31
  • VIC1VECTADDR0,VIC1VECTADDR1,…,VIC1VECTADDR31
  • VIC2VECTADDR0,VIC2VECTADDR1,…,VIC2VECTADDR31
  • VIC3VECTADDR0,VIC3VECTADDR1,…,VIC3VECTADDR31

(4)代码示例

// 绑定我们写的isr到VICnVECTADDR寄存器
// 绑定过之后我们就把isr地址交给硬件了,剩下的我们不用管了,硬件自己会处理
// 等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。
// 参数:intnum是int.h定义的物理中断号,handler是函数指针,就是我们写的isr// VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个
// 数组(这个数组就是一个函数指针数组)的首地址,然后具体计算每一个中断的时候
// 只需要首地址+偏移量即可。
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{//VIC0if(intnum<32){*( (volatile unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;}//VIC1else if(intnum<64){*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;}//VIC2else if(intnum<96){*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;}//VIC3else{*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;}return;
}

6、VICnADDRESS寄存器

(1)当发生中断时,硬件自动识别中断编号,并且自动找到这个中断所对应的VECTADDR寄存器,然后把寄存器的内容复制到VICADDRESS中,以供后续使用。这样的设计避免了软件查找中断源和中断处理函数,节省了时间,提高了s5pv210的中断响应速度。

(2)代码示例

// 真正的中断处理程序。意思就是说这里只考虑中断处理,不考虑保护/恢复现场
void irq_handler(void)
{//printf("irq_handler.\n");// SoC支持很多个(在低端CPU例如2440中有30多个,在210中有100多个)中断// 这么多中断irq在第一个阶段走的是一条路,都会进入到irq_handler来// 我们在irq_handler中要去区分究竟是哪个中断发生了,然后再去调用该中断// 对应的isr。(函数指针)// 虽然硬件已经自动帮我们把isr放入了VICnADDR中,但是因为有4个,所以我们必须// 先去软件的检查出来到底哪个VIC中断了,也就是说isr到底在哪个VICADDR寄存器中unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};int i=0;void (*isr)(void) = NULL;for(i=0; i<4; i++){// 发生一个中断时,4个VIC中有3个是全0,1个的其中一位不是0if(intc_getvicirqstatus(i) != 0){isr = (void (*)(void)) vicaddr[i];break;}}(*isr)();		// 通过函数指针来调用函数
}

7、总结

以上介绍的寄存器中,能表征中断流程的寄存器有:

(1)VICnIRQSTATUS(4个)

  • VIC0IRQSTATUS
  • VIC1IRQSTATUS
  • VIC2IRQSTATUS
  • VIC3IRQSTATUS

(2)VICnVECTADDRm寄存器(4*32=128个)

  • VIC0VECTADDR0VIC0VECTADDR1,……VIC0VECTADDR31
  • VIC1VECTADDR0VIC1VECTADDR1,……VIC1VECTADDR31
  • VIC2VECTADDR0VIC2VECTADDR1,……VIC2VECTADDR31
  • VIC3VECTADDR0VIC3VECTADDR1,……VIC3VECTADDR31

(3) VICnADDRESS寄存器(4个)

  • VIC0ADDRESS
  • VIC1ADDRESS
  • VIC2ADDRESS
  • VIC3ADDRESS

它们之间的关系如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中断——S5PV210的中断案例

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 s5pv210——中断 - biaohc - 博客园 S5PV210的中断体系简介_天糊土的博客-CSDN博客 一、S5PV210的中断流程 第一部分是我们为中断响应而做的预备工作。 1、初始化中断控制器 比如先关闭所…

按键——S5PV210的按键简介(轮询方式+中断方式)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 s5pv210——按键 - biaohc - 博客园 一、按键的简介 1、按键的物理特性 按钮没有被按下时&#xff0c;内部是断开的。按钮被按下时&#xff0c;内部保持接通状态&#xff1b;放手后由于弹…

HAproxy + Keepalive实现LDAP代理服务

HAproxy Keepalive实现LDAP代理服务因为公司的各种高自研发的系统非常多&#xff0c;这些系统又全部是在使用LDAP做认证&#xff0c;目前我们有几台DC控制器来分担这些ldap请求&#xff0c;用户通过访问ldap.xxxx.com这个域名来连接ldap服务器&#xff0c;我们通过DNS轮询的方…

中断——S5PV210的中断源

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 前言 s5pv210中因为支持的中断源很多&#xff0c;因此直接设计了4个中断寄存器&#xff0c;每个32位&#xff0c;每位对应一个中断源。理论上210最多支持128个中断&#xff0c;实际支持不足128个&a…

排序与查找

为什么80%的码农都做不了架构师&#xff1f;>>> sort.h #ifndef SORT_H_INCLUDED #define SORT_H_INCLUDEDvoid bubble_sort(int a[], int len);void select_sort(int a[], int len);#endif // SORT_H_INCLUDED sort.cpp #include "sort.h"void bubble_s…

LCD——S5PV210的LCD的理论与操作

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 s5pv210 LCD编程原理 - biaohc - 博客园 一、关于LCD的简介 1、LCD简介 &#xff08;1&#xff09;什么是LCD LCD&#xff08;Liquid Crystal Display&#xff09;俗称液晶。液晶是一种材…

分析三星提供的sd_fusing文件夹(用来制作SD卡启动镜像)

以下内容源于网络资源的学习与整理&#xff0c;如有其侵权请告知删除。 参考博客 uboot分析&#xff1a;SD卡镜像制作脚本分析 - 走看看 如何烧写u-boot到SD卡 S5PV210 Uboot开发与移植01&#xff1a;Uboot概述&#xff08;推荐&#xff09; 一、sd_fusing文件夹简介 1、文件…

Linux系统管理----LVM逻辑卷和磁盘配额作业习题

1&#xff0e;为主机增加80G SCSI 接口硬盘 2&#xff0e;划分三个各20G的主分区 [rootlocalhost chen]# fdisk /dev/sdb 命令(输入 m 获取帮助)&#xff1a;n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): Using default r…

外存——S5PV210的外部存储器(nandflash与inand的介绍)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 关于iNand ,oneNand,moviNAND的区别——大家一起来扫盲 - 嵌入式系统 总结 本文首先介绍了目前主流的外存设备有哪些。 然后介绍了NandFlash芯片的接口、结构、常见操作&#xff0c;以及…

uboot中关于LCD的代码分析

以下内容源于朱有鹏《物联网大讲坛》课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 1、在uboot-jiuding/board.c中&#xff0c;init_sequence中的display_banner中的open_backlight函数中&#xff0c;给GPF3_5输出高电平。 注释掉这一句uboot的LCD显示照样正常的&am…

寒假自助游之济南

以前很少去旅行&#xff0c;主要原因是孩子年龄比较小&#xff0c;再就是经济方面的考虑。如今孩子渐渐长大了&#xff0c;行路与读万卷书同等重要&#xff0c;遂决定以后无论寒暑假都应陪孩子到处走一走。我不喜欢那种走马观花式的跟团游&#xff0c;因而自助游便是最佳选择。…

与fastboot相关的知识

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 一、fastboot的基本知识 1、什么是fastboot &#xff08;1&#xff09;fastboot是android使用的一种刷机方法。 android系统设计了2种刷机方式&#xff1a;fastboot和recovery。 &#xf…

Android中Activity启动模式详解

在Android中每个界面都是一个Activity&#xff0c;切换界面操作其实是多个不同Activity之间的实例化操作。在Android中Activity的启动模式决定了Activity的启动运行方式。 Android总Activity的启动模式分为四种&#xff1a; Activity启动模式设置&#xff1a; <activity and…

第一次软工作业展示——潘学

第一次软工作业完成啦&#xff01; 回首这个作业的完成过程&#xff0c;我是很有收获。这个作业有几个难点&#xff1a;1、在给定目录下读取TXT文件的内容&#xff1b;2、从读到的内容中分析出单词&#xff1b;3、统计单词的出现频率并输出。 我之前只学习过C和java&#xff0c…

uboot源码——命令体系

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 参考资料&#xff1a;http://www.cnblogs.com/biaohc/p/6394710.html 一、uboot命令体系基础 1、使用uboot命令 uboot启动后进入命令行环境&#xff0c;在此输入命令按回车结束&#xff0…

XMPP文件传输(XEP-0096协议说明)

XMPP XEP-0096协议是XMPP中的文件传输协议。 关于文件传输&#xff0c;在xmpp协议中有不少协议可以实现&#xff0c;而XEP-0096协议是其中非常简单的一个协议。由于邮件被删&#xff0c;我的代码demo丢失&#xff0c;因此只能在这里给大家讲一下其中的逻辑实现&#xff0…

uboot源码——环境变量

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 参考资料&#xff1a;http://www.cnblogs.com/biaohc/p/6398515.html。 一、uboot的环境变量基础 1、环境变量的作用 在不改变源码、不用重新编译的情况下&#xff0c;可以通过设置环境变量…

Linq To Sql进阶系列 -目录导航

博客园CLR基础研究团队|CLR团队精品系列|C# 3.0专题 [Linq To Sql进阶系列] 目录导航 1 Linq To Sql进阶系列&#xff08;一&#xff09;-从映射讲起 本系列&#xff0c;或多或少&#xff0c;直接或间接依赖入门系列知识。但&#xff0c;依然追求独立成章。因本文作者水平有限&…

uboot源码——mmc驱动分析

以下内容源于朱有鹏《物联网大讲坛》课程的学习&#xff0c;以及博客http://www.cnblogs.com/biaohc/p/6409197.html的学习整理&#xff0c;如有侵权&#xff0c;请告知删除。 一、uboot与linux驱动 1、uboot是裸机程序 狭义的驱动的概念&#xff1a;操作系统中用来具体操控硬…