Cortext-M3系统:异常(3)

news2024/11/23 9:00:17

1、异常

        异常响应系统是再M3内核水平上的,支持众多的系统异常和外部中断。1-15为系统异常,大于16为外部中断。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。优先级数值越小,优先级越高。CM3支持中断嵌套,高优先级可以抢占低优先级,有三个系统异常:复位、NMI以及hardfault有固定的优先级,均为负值。

        注:所有可以打断当前程序执行流的行为都可以称为“异常”,中断也可以理解为一种异常。在本文及后续的博客中,异常和中断二词若没有特殊说明,均为一个意思——可以打断当前程序执行流的行为。对于M3内核来说,异常属于内核里面的行为,如除数为0,跟内核保持“同步”,而中断则是片上的各种外设等产生的信号,对M3内核来说属于“外面”,跟内核“异步”。

内部异常

外部中断

        在NVIC的中断控制及状态寄存器中,有一个VECTACTIVE位段;另外,还有一个特殊功能寄存器IPSR。在它们二者的里面,都记录了当前正服务的异常,给出了它的编号。

        如果一个发生的异常不能被即刻响应,就称它被“悬起”(pending)。不过,少数fault异常是不允许被悬起的。一个异常被悬起的原因,可能是系统当前正在执行一个更高优先级异常的服务 例程,或者因相关掩蔽位的设置导致该异常被除能。对于每个异常源,在被悬起的情况下,都会有一个对应的“悬起状态寄存器”保存其异常请求。待到该异常能够响应时,执行其服务例程。

2、优先级的定义

在CM3中,优先级对于异常来说很关键的,它会决定一个异常是否能被掩蔽,以及在未掩蔽的情况下何时可以响应。优先级的数值越小,则优先级越高。CM3支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常。有3个系统异常:复位,NMI以及硬fault,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常。所有其它异常的优先级则都是可编程的,但不能被编程为负数。

原则上,CM3支持3个固定的高优先级和多达256级的可编程优先级,并且支持128级抢占。但是,绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数会更少,如8级,16级,32级等。它们在设计时会裁掉表达优先级的几个低端有效位,以减少优先级的级数,可见,不管使用多少位来表达优先级,都是以MSB对齐的。

如果使用更多的位来表达优先级,则可以使用的值也更多,同时需要的门也更多——带来更多的成本和功耗。CM3允许的最少使用位数为3个位,亦即至少要支持8级优先级。通过让优先级以MSB对齐,可以简化程序的跨器件移植。比如,如果一个程序早先在支持4位优先级的器件上运行,在移植到只支持3位优先级的器件后,其功能不受影响。但若是对齐到LSB,则会使MSB丢失,导致数值大于7的低优先级一下子升高了,甚至会发生“优先级反转”:使它高于小于等于7的优先级。

抢占优先级与子优先级

        为了使抢占机能变得更可控,CM3还把256级优先级按位分成高低两段,分别称为抢占优先级和子优先级。抢占优先级有时亦称为“组优先级”,或者“主优先级”。NVIC中有一个寄存器是“应用程序中断及复位控制寄存器”(内容见表7.5),它里面有一个位段名为“优先级组”。该位段的值对每一个优先级可配置的异常都有影响——把其优先级分为2个位段:MSB所在的位段(左边的)对应抢占优先级,而LSB所在的位段(右边的)对应子优先级。

        抢占优先级决定了抢占行为:当系统正在响应某异常L时,如果来了抢占优先级更高的异常H,则H可以抢占L。子优先级则处理“内务”:当抢占优先级相同的异常有不止一个悬起时,就最先响应子优先级最高的异常。这种优先级分组做出了如下规定:子优先级至少是1个位。因此抢占优先级最多是7个位,这就造成了最多只有128级抢占的现象。但是CM3允许从比特7处分组,此时所有的位都表达子优先级,没有任何位表达抢占优先级,因而所有优先级可编程的异常之间就不会发生抢占——相当于在它们之中除能了CM3的中断嵌套机制。

         虽然优先级分组的功能很强大,但是粗心地更改会使它变得很暴力,尤其是在设计硬实时系统的时候,这简直就是在玩火——常常会改变系统的响应特性。导致某些关键任务有可能得不到及时响应,凶多吉少的意外随时可能猛烈发作。其实在绝大多数情况下,优先级的分组都要预先经过计算论证,并且在开机初始化时一次性地设置好,以后就再也不动它了。只有在绝对需要且绝对有把握时,才小心地更改,并且要经过尽可能充分的测试。另外,优先级组所在的寄存器AIRCR也基本上是“一次成型”,只是需要手工产生复位时才写里面相应的位。

3、向量表

        当发生了异常并且要响应它时,CM3需要定位其服务例程的入口地址。这些入口地址存储在所谓的“(异常)向量表”中。缺省情况下,CM3认为该表位于零地址处,且各向量占用4字节。因此每个表项占用4字节。上电后的向量表如图所示,这也是bin文件开始的几个字节内容,有兴趣的可以使用bin文件查看器看看M3单片机生成的bin文件内容(bin文件由hex文件转化而来,hex文件相比较bin文件多了一些跟地址相关的内容,stm32单片机的第一个字是栈指针,一般为0x20000000,第二个字就是pc指针)。

        因为地址0处应该存储引导代码,所以它通常映射到Flash或者是ROM器件,并且它们的值不得在运行时改变。然而,为了支持动态重分发中断,CM3允许向量表重定位——从其它地址处开始定位各异常向量。这些地址对应的区域可以是代码区,但更多是在RAM区。在RAM区就可以修改向量的入口地址了。为了实现这个功能,NVIC中有一个寄存器,称为“向量表偏移量寄存器”(在地址0xE000_ED08处),通过修改它的值就能重定位向量表。但必须注意的是:向量表的起始地址是有要求的:必须先求出系统中共有多少个向量,再把这个数字向上“圆整”到2的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一共有32个中断,则共有32+16(系统异常)=48个向量,向上圆整到2的整次幂后值为64,因此向量表重定位的地址必须能被64*4=256整除,从而合法的起始地址可以是:0x0, 0x100, 0x200等。

        如果需要动态地更改向量表,则对于任何器件来说,向量表的起始处都必须包含以下向量:主堆栈指针(MSP)的初始值、复位向量、NMI、硬fault服务例程。 ​ 后两者也是必需的,因为有可能在引导过程中发生这两种异常。可以在SRAM中开出一块空间用于存储向量表。在引导期间先填写好各向量,然后在引导完成后,就可以启用内存中的新向量表,从而实现向量可动态调整的能力。

4、中断输入及悬起行为

        本节讨论的中断的输入和悬起行为,也适用于NMI。只是对于NMI来说,除了一些特殊情况之外,将会立即无条件执行其服务例程。这些特殊情况包括:当前已经在执行NMI服务例程CPU被调试器喊停(halted)CPU被一些严重的系统错误锁定(Lock up)。则新的NMI请求也将悬起。中断悬起示意图如图。

         当中断输入脚被置为有效(asser)t后,该中断就被悬起。即使后来中断源撤消了中断请求,已经被标记成悬起的中断也被记录下来。到了系统中它的优先级最高的时候,就会得到响应。但是,如果在某个中断得到响应之前,其悬起状态被清除了(例如,在PRIMASK或FAULTMASK置位的时候软件清除了悬起状态标志),则中断被取消。

        当某中断的服务例程开始执行时,就称此中断进入了“活跃”状态,并且其悬起位会被硬件自动清除,如图7.10所示。在一个中断活跃后,直到其服务例程执行完毕,并且返回(亦称为中断退出)后,才能对该中断的新请求予以响应(单实例)。当然,新请求在得到响应时,亦是由硬件自动清零其悬起标志位。中断服务例程也可以在执行过程中把自己对应的中断重新悬起,使用时要注意避免进入“死循环”。

        如果中断源咬住请求信号不放,该中断就会在其上次服务例程返回后再次被置为悬起状态。

        另一方面,如果某个中断在得到响应之前,其请求信号以若干的脉冲的方式呈现,则被视为只有一次中断请求,多出的请求脉冲全部错失——这是中断请求太快,以致于超出处理器反应限度的情况。

        如果在服务例程执行时,中断请求释放了,但是在服务例程返回前又重新被置为有效,则CM3会记住此动作,重新悬起该中断。

5、Fault类异常

        有若干个系统异常专用于fault处理。CM3中的Faults可分为以下几类:总线faults、存储器管理faults、用法faults、硬fault。

5.1 总线faults

        当AHB接口上正在传送数据时,如果回复了一个错误信号(error response),则会产生总线faults,产生的场合可以是:

        取指,通常被称作“预取流产”(prefetch abort)

        数据读/写,通常被称作“数据流产”(data abort)

        在CM3中,执行如下动作时,如果地址有误,亦会触发总线异常: ​ 中断处理起始阶段的堆栈PUSH动作。此时若发生总线fault,则称为“入栈错误” ​ 中断处理收尾阶段的堆栈POP动作。此时若发生总线fault,则称为“出栈错误” ​ 在处理器启动中断服务序列(sequence)后读取向量时。这是一种极度罕见的特殊情况,被归类为硬fault。

        AHB回复的错误信号会触发总线fault,诱因可以是: ​

        企图访问无效的存储器region。常见于访问的地址没有相对应的存储器。 ​

        设备还没有作好传送数据的准备。比如,在尚未初始化SDRAM控制器的时候试图访问SDRAM。 ​

        在企图启动一次数据传送时,传送的尺寸不能为目标设备所支持。例如,某设备只接受字型数据,却试图送给它字节型数据。 ​

        因为某些原因,设备不能接受数据传送。例如,某些设备只有在特权级下才允许访问,可当前却是用户级。

        当上述这些总线faults发生时(取向量的除外),只要没有同级或更高优先级的异常正在服务,且没有被掩蔽,就会执行总线fault的服务例程。如果在检测到总线fault时还检测到了更高优先级的异常,则先处理后者,而总线fault被标记成悬起。最后,如果总线fault被除能,或者总线fault是被某同级或更高优先级异常的服务例程引发的,则总线fault被迫成为“硬伤”——上访成硬fault,使得最后执行的是硬fault的服务例程(如果当前没有执行NMI服务例程,则立即执行硬fault服务例程)。如果在硬fault服务例程的执行中又产生了总线fault ,内核将进入锁定状态(逼死内核算了)。

        那么,发生了总线fault后,我们将如何找出该fault的事故原因呢?在这里,NVIC提供了若干个fault状态寄存器,其中一个名为“总线fault状态寄存器”(BFSR)的。通过它,总线fault服务例程可以确定产生fault的场合:是在数据访问时,在取指时,还是在中断的堆栈操作时。

        使能总线fault服务例程,需要在NVIC的“系统Handler控制及状态寄存器”中置位BUSFAULTENA位。要注意的是:在使能之前,总线fault服务例程的入口地址必须已经在向量表中配置好。

        NVIC提供了若干个fault状态寄存器,其中一个名为“总线fault状态寄存器”(BFSR)的。通过它,总线fault服务例程可以确定产生fault的场合:是在数据访问时,在取指时,还是在中断的堆栈操作时。

        对于精确的总线fault(后有说明),肇事指令的地址被压在堆栈中。如果BFSR中的BFARVALID位为1,还可以找出是在访问哪块存储器时产生该总线fault的——该存储器的地址被放到“总线fault地址寄存器(BFAR)”中。然而,如果是不精确的总线fault,就无从定位了。因为在发生fault时,处理器已经在执行肇事指令后,不知又流逝了多少个周期了。

精确的总线fault vs 不精确的总线fault

        由数据访问产生的总线fault,可以进一步被归类为精确总线fault和不精确总线fault。在不精确的总线faults中,导致此fault的指令早已完成了。例如,缓冲区写入。启动缓冲区写入的指令不知何时已经执行了,但是写到中途时触发了总线fault。此时,肇事指令早已“逃逸”——在若干个时钟周期就执行过了,而且不能确定是具体几个周期之前,CM3也不会记录这期间的程序跳转动作。因此无法确认“肇事者”,故而该fault是不精确的。精确的总线fault则不同,它是被最后一个完成的操作触发的。例如,一个存储器读取导致的fault总是精确的,因为该指令必须等全部读完时才算执行完成。这样,任何在读取过程中发生的fault总能落在该指令的头上。

        BFSR寄存器如下所示:它是一个8位的寄存器,并且可以使用字传送和字节传送来读取它。如果以字方式访问,地址是0xE000_ED28,并且第2个字节有效;如果以字节方式访问,则地址直接就是0xE000_ED29,如图所示。   

      

5.2 存储器管理faults

        存储器管理faults多与MPU有关,其诱因常常是某次访问触犯了MPU设置的保护规范。另外,某些非法访问,例如,在不可执行的存储器区域试图取指,也会触发一个MemManage fault,而且在这种场合下,即使没有MPU也会触发MemMange fault。MemManage faults的常见诱因如下所示:

        访问了所有MPUregions覆盖范围之外的地址 ​

        访问了没有存储器与之对应的空地址 ​

        往只读region写数据 ​

        用户级下访问了只允许在特权级下访问的地址

        在MemManage fault发生后,如果其服务例程是使能的,则执行服务例程。如果同时还发生了其它高优先级异常,则优先处理这些高优先级的异常,MemManage异常被悬起。如果MemMange fault是被同级或高优先级异常的服务例程引发的,或者MemManage fault被除能,则和总线fault一样:上访成硬fault,最终执行的是硬fault的服务例程。如果硬fault服务例程或NMI服务例程的执行也导致了MemManage fault,那就不要办了(乌鸦哥)——内核将被锁定。

        和总线fault一样,MemManage fault必须被使能才能正常响应。MemManage fault在NVIC“系统handler控制及状态寄存器”中的使能位是MEMFAULTENA。如果把向量表置于RAM中,应优先建立好MemManage fault服务例程的入口地址。

        为了调查MemManage fault的案发现场,NVIC中有一个“存储器管理fault状态寄存器(MFSR)”,它指出导致MemManage fault的原因。如果是因为一个数据访问违例(DACCVIOL位)或是一个取指访问违例(IACCVIOL位),则违例指令的地址已经被压入栈中。如果还有MMARVALID位被置位,则还能进一步查出引发此fault时访问的地址——读取NVIC“存储器管理地址寄存器(MMAR)”的值。 ​

        MFSR寄存器如下所示。它是一个8位的寄存器,并且可以使用字传送和字节传送来读取它。不管使用哪种访问方式,地址都是0xE000_ED28。只不过如果按字访问,就只有第1个字节有意义。如图所示。

5.3 用法faults

        用法faults发生的场合可以是:

        执行了协处理器指令。Cortex-M3本身并不支持协处理器,但是通过fault异常机制,可以建立一套“软件模拟”的机制,来执行一段程序模拟协处理器的功能,从而可以方便地在其它Cortex处理器间移植。 ​

        执行了未定义的指令。同上一点的道理,亦可以软件模拟未定义指令的功能。 ​

         尝试进入ARM状态。因为CM3不支持ARM状态,所以用法fault会在切换时产生。软件可以利用此机制来测试某处理器是否支持ARM状态。 ​

        无效的中断返回(LR中包含了无效/错误的值) ​

        使用多重加载/存储指令时,地址没有对齐。

        另外,如果需要严格要求程序的质量,还可以让CM3在遇到除数为零的时候,以及遇到未对齐访问的时候也产生用法fault。在NVIC中有两个控制位分别与它们对应。通过设置这两个控制位,就可以激活它们。

        在使能了用法fault后,如果在用法fault发生的时候,已经悬起了更高优先级的异常,则用法fault被悬起。如果某异常服务例程在执行过程中引发了用法fault,并且该异常的优先级不低于用法fault的优先级;或者用法fault被除能,则和总线fault与MemManage fault一样,用法fault上访成硬fault,最终执行的是硬fault的服务例程。如果硬fault服务例程或NMI服务例程的执行竟然也引发了用法fault,内核又将被锁定(内核:真难)。

        可见,和总线fault与MemManage fault一样,用法fault必须被使能才能正常响应。用法fault在NVIC“系统handler控制及状态寄存器”中的使能位是USGFAULTENA。如果把向量表置于RAM中,应优先建立好用法fault服务例程的入口地址(应先建立好fault类异常服务例程的入口地址,再建立其它异常服务例程的入口地址)。

        为了调查用法fault的案发现场,NVIC中有一个“用法fault状态寄存器(UFSR)”,它指出导致用法fault的原因。在服务例程中,导致用法fault的指令地址被压入堆栈中。

何时会意外地试图切入ARM状态

        导致用法fault的最常见原因就是试图切入ARM状态。只要在加载PC时使用了LSB为零的数(也就是偶数),就被视作试图切入ARM状态,包括:

                执行“BX Rn”指令时,Rn的LSB=0

                异常向量表中入口地址的LSB=0

                POP{…,PC}时,弹出的数值LSB=0,这常常是入栈的值被手工改坏造成的

        在上述原因导致了用法fault后,UFSR中的INVSTATE位(INValid STATE)会置位。

        UFSR的定义如图所示。它占用了2个字节,可以被按半字访问或是按字访问。按字访问时的地址是0xE000_ED28,高半字有效;按半字访问时的地址是0xE000_ED2A。和其它的FAULT状态寄存器一样,它里面的位可以通过写1来清零。

 5.4 硬fault

        硬fault是上文讨论的总线fault、存储器管理fault以及用法fault上访的结果。如果这些fault的服务例程无法执行,它们就会成为“硬伤”——上访(escalation)成硬fault。另外,在取向量(异常处理时对异常向量表的读取)时产生的总线fault也按硬fault处理。在NVIC中有一个硬fault状态寄存器(HFSR),它指出产生硬fault的原因。如果不是由于取向量造成的,则硬fault服务例程必须检查其它的fault状态寄存器,以最终决定是谁上访的。硬fault状态寄存器如图。

5.5 应对faults

        在软件开发过程中,我们可以根据各种fault状态寄存器的值来判定程序错误,并且改正它们。下面就给出一些应付fault的常用方法。

        然而,在一个实时系统中,情况则大不相同。发生了Faults后,如果不加以处理常会危及系统的运行。因此在找出了导致fault的原因后,软件必须决定下一步该怎么办。如果系统中运行了一个RTOS,通常是终结肇事的任务。在其它情况,系统也许必须要复位。在不同的目标应用中,对fault恢复的要求也不同。总的来说,采取适当的策略有利于软件更健壮——当然最好还是防患于未然。下面就给出一些应付fault的常用方法。

        复位。这也是最后一招。通过设置NVIC“应用程序中断及复位控制寄存器”中的VECTRESET位,将只复位处理器内核而不复位其它片上设施。取决于芯片的复位设计,有些CM3芯片可以使用该寄存器的SYSRESETREQ位来复位。这种只限于内核中的复位不会殃及其它的系统部件。 ​ 恢复:在一些场合下,还是有希望解决产生fault的问题的。例如,如果程序尝试访问了协处理器,可以通过一个协处理器的软件模拟器来解决此问题——当然是以牺牲性能为代价的,要不然还要硬件加速干啥。 ​ 中止相关任务:如果系统运行了一个RTOS,则相关的任务可以被终结或者重新开始。

        各个fault状态寄存器(FSRs)都保持住它们的状态,直到手工清除。Fault服务例程在处理了相应的fault后不要忘记清除这些状态,否则如果下次又有新的fault发生,服务例程在检视fault源时,又将看到早先已经处理的fault遗留下来的状态标志。

        芯片厂商也可以再添加自己的FSR,以表示其它fault情况。

6、SVC和PendSV

        SVC和PendSV跟操作系统有比较密切的关系,不了解OS的可能会看着有点吃力。

        SVC(系统服务调用,亦简称系统调用)和PendSV(可悬起系统调用),它们多用在上了操作系统的软件开发中。SVC用于产生系统函数的调用请求。例如,操作系统通常不让用户程序直接访问硬件,而是通过提供一些系统服务函数,让用户程序使用SVC发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件。因此,当用户程序想要控制特定的硬件时,它就要产生一个SVC异常,然后操作系统提供的SVC异常服务例程得到执行,它再调用相关的操作系统函数,后者完成用户程序请求的服务。

        这种“提出要求——得到满足”的方式,很好、很强大。首先,它使用户程序从控制硬件的繁文缛节中解脱出来,而是由OS负责控制具体的硬件。第二,OS的代码可以经过充分的测试,从而能使系统更加健壮和可靠。第三,它使用户程序无需在特权级下执行,用户程序无需承担因误操作而瘫痪整个系统的风险。第四,通过SVC的机制,还让用户程序变得与硬件无关,因此在开发应用程序时无需了解硬件的操作细节,从而简化了开发的难度和繁琐度,并且使应用程序跨硬件平台移植成为可能。开发应用程序唯一需要知道的就是操作系统提供的应用编程接(API),并且在了解了各个请求代号和参数表后,就可以使用SVC来提出要求了(事实上,为使用方便,操作系统往往会提供一层封皮,以使系统调用的形式看起来和普通的函数调用一致。各封皮函数会正确使用SVC指令来执行系统调用)。其实,严格地讲,操作硬件的工作是由设备驱动程序完成的,只是对应用程序来说,它们也相当于操作系统的一部分,如图所示。

        SVC异常通过执行”SVC”指令来产生。该指令需要一个立即数,充当系统调用代号。SVC异常服务例程稍后会提取出此代号,从而获知本次调用的具体要求,再调用相应的服务函数。例如,

    SVC  0x3;调用3号系统服务

         在SVC服务例程执行后,上次执行的SVC指令地址可以根据自动入栈的返回地址计算出。找到了SVC指令后,就可以读取该SVC指令的机器码,从机器码中取出立即数,就获知了请求执行的功能代号。如果用户程序使用的是PSP,服务例程还需要先执行MRS Rn, PSP指令来获取应用程序的堆栈指针。通过分析LR的值,可以获知在SVC指令执行时,正在使用哪个堆栈。

        由CM3的中断优先级模型可知,我们不能在SVC服务例程中嵌套使用SVC指令(事实上这样做也没意义),因为同优先级的异常不能抢占自身。这种作法会产生一个用法fault。同理,在NMI服务例程中也不得使用SVC,否则将触发硬fault。

        另一个相关的异常是PendSV(可悬起的系统调用),它和SVC协同使用。一方面,SVC异常是必须在执行SVC指令后立即得到响应的(对于SVC异常来说,若因优先级不比当前正处理的高,或是其它原因使之无法立即响应,将上访成硬fault),应用程序执行SVC时都是希望所需的请求立即得到响应。另一方面,PendSV则不同,它是可以像普通的中断一样被悬起的(不像SVC那样会上访)。OS可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。悬起PendSV的方法是:手工往NVIC的PendSV悬起寄存器中写1。悬起后,如果优先级不够高,则将缓期等待执行。

        PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。例如,一个系统中有两个就绪的任务,上下文切换被触发的场合可以是:

        执行一个系统调用 ​

        系统滴答定时器(SYSTICK)中断,(轮转调度中需要)

        若在产生SysTick异常时正在响应一个中断,则SysTick异常会抢占其ISR。在这种情况下,OS是不能执行上下文切换的,否则将使中断请求被延迟,而且在真实系统中延迟时间还往往不可预知——任何有一丁点实时要求的系统都决不能容忍这种事。因此,在CM3中也是严禁没商量——如果OS在某中断活跃时尝试切入线程模式,将触犯用法fault异常。

        PendSV异常会自动延迟上下文切换的请求,直到其它的ISR都完成了处理后才放行。为实现这个机制,需要把PendSV编程为最低优先级的异常。如果OS检测到某IRQ正在活动并且被SysTick抢占,它将悬起一个PendSV异常,以便缓期执行上下文切换。

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

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

相关文章

网络嗅探与ARP欺骗

目录 一、网络嗅探概述 1.1 网络嗅探的概念 1.1.2 一把双刃剑 1.1.3 特点 1.2 网络嗅探的原理 1.2.1 网络嗅探的条件 1.2.2 网卡的工作模式 1.2.3 局域网的传输技术 1.3 网络嗅探的前提 1.3.1 网卡设置为混杂模式 1.3.2 同处在一个广播式局域网内 1.4 嗅探工具的使…

4.23 TCP状态转换 4.24半关闭、端口复用

4.23 TCP状态转换 2MSL(Maximum Segment Lifetime) 主动断开连接的一方,最后进入一个TIME_WAIT状态,这个状态会持续:2msl msl:官方建议:2分钟,实际是30s 当 TCP 连接主动关闭方接收到被动关闭方发送的 FIN…

【kubernetes】部署kube-apiserver与kubectl

前言:二进制部署kubernetes集群在企业应用中扮演着非常重要的角色。无论是集群升级,还是证书设置有效期都非常方便,也是从事云原生相关工作从入门到精通不得不迈过的坎。通过本系列文章,你将从虚拟机准备开始,到使用二进制方式从零到一搭建起安全稳定的高可用kubernetes集…

Flutter 组件集录 | RawMagnifier 组件 - 拿起你的八倍镜

theme: cyanosis 1. 前言 今天看 Flutter 源码,偶然发现 Magnifier 组件,这单词不就是 放大镜 嘛! 再结合新版 Flutter 中输入文本的放大镜效果,直觉告诉我这玩意应该可以放大任何组件。如下所示,背景是一张图片,使用 …

0013-TIPS-pawnyable : Race-Condition

原文 Linux Kernel PWN | 040204 Pawnyable之竞态条件 Holstein v4: Race Condition 题目下载 漏洞代码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/uaccess.h> #i…

使用 Vite + Vue3 + Element-Plus + Pinia + Ts 搭建 Vue3 项目

使用 Vite Vue3 Element-Plus Pinia Ts 搭建 Vue3 项目 使用Vite搭建配置Router配置 Element-Plus配置sass配置Pinia配置解析 符号&#xff0c;并找到对应的路径TypeScript忽略类型检查 使用Vite搭建 Vite 需要 Node.js 版本 14.18&#xff0c;16。然而&#xff0c;有些模…

chatgpt赋能python:Python指定小数点位数的完整指南

Python指定小数点位数的完整指南 Python是一种高级编程语言&#xff0c;广泛用于科学、统计和数学计算。在许多情况下&#xff0c;我们需要对浮点数进行更精确的计算。Python 中保留小数位数的能力很强&#xff0c;本文将向您介绍如何在 Python 中指定小数点后的位数。 为什么…

购买服务器/安装宝塔

1、服务器的选择 本人知道并了解一丢丢的就这四个平台&#xff1a; 1、阿里云 2、腾讯云 3、硅云 4、亚马逊 个人觉得阿里云是YYDS&#xff0c;啥都挺方便的&#xff0c;唯一不足就是有点小贵&#xff0c;但是新用户第一次购买还是很优惠的。 腾讯云有的云服务器是真的便宜&am…

【Batch_size 与 梯度 之间的关系】

chatGPT 回答 梯度更新与批大小&#xff08;batch size&#xff09;之间有密切的关系。批大小是指在训练过程中一次迭代所使用的样本数量。 在深度学习中&#xff0c;梯度下降是一种常用的优化算法&#xff0c;用于更新模型参数以最小化损失函数。梯度是损失函数对于模型参数…

Gradio Flagging模块解析与实践

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

基于html+css的图展示135

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

大数据大作业(课程设计)

题目&#xff1a;信息爬取字数统计及可视化 内容及要求&#xff1a; 配置Hadoop平台&#xff1b;利用爬虫技术爬取任一门户网站新闻栏目一定时间段内的新闻信息&#xff0c;保存为一个或多个文件并上传到Hadoop平台以本人学号命名的文件夹下&#xff1b;利用MapReduce框架编程完…

CSS3-显示模式

显示模式 1 块级显示 2 行内显示 3 行内块显示 4 元素显示模式转换 5 拓展 1 块级显示 属性&#xff1a;display:block 显示特点&#xff1a; 1 独占一行&#xff08;一行只能显示一个&#xff09; 2 宽度默认是父元素的宽度&#xff0c;高度默认由内容撑开 3 可以设置宽高 代表…

Cortext-M3系统:异常系统(5)

1、使用中断 在CM3中&#xff0c;NVIC为我们搞定了使用中断时的很多例行任务&#xff0c;如优先级检查、入栈/出栈、取向量等。不过在NVIC能行使职能之前&#xff0c;还需要我们做好如下的初始化工作&#xff1a;建立堆栈、建立向量表、分配各中断的优先级、使能中断。 1.1 建…

node笔记_读取目录的文件

文章目录 ⭐前言⭐fs.readdirSync&#x1f496; 读取目录 不加withFileTypes&#x1f496; 读取目录 加withFileTypes&#x1f496; 读取目录时 判断元素文件还是目录 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node读取目录文件 往期文章 node_wind…

【java】Jconsole 开启远程连接遇到的一些坑

文章目录 背景一、JMX二、配置远程连接2.1、Java 程序启动2.2、tomcat 启动2.3、无法远程问题排查2.4、解决方案 三、关闭 tomcat 报错3.1、问题分析3.2、问题解决 总结 背景 最近在学习 JVM&#xff0c;其中涉及到性能、内存等指标分析需要使用工具分享&#xff0c;Java 提供…

dvwa靶场通关(六)

第六关&#xff1a;Insecure CAPTCHA&#xff08;不安全的验证码&#xff09; 不安全的验证码&#xff1f;不是这个意思&#xff0c;而是指验证码验证可以被绕过。怎么绕&#xff1f;一般都是验证码的验证和最终修改的验证分离&#xff0c;导致了中间过程&#xff08;验证码的…

io.netty学习(八)零拷贝原理

目录 零拷贝 传统I/O操作存在的性能问题 零拷贝技术原理 虚拟内存 mmap/write 方式 sendfile 方式 带有 scatter/gather 的 sendfile方式 splice 方式 总结 io.netty学习使用汇总 零拷贝 零拷贝&#xff08;Zero-Copy&#xff09;是一种 I/O 操作优化技术&#xff0c…

总结906

学习目标&#xff1a; 月目标&#xff1a;6月&#xff08;线性代数强化9讲&#xff0c;背诵15篇短文&#xff0c;考研核心词过三遍&#xff09; 周目标&#xff1a;线性代数强化3讲&#xff0c;英语背3篇文章并回诵&#xff0c;检测 每日规划 今日已做&#xff1a; 1.回环背诵…

chatgpt赋能python:Python捕捉按键:探索基础和应用

Python捕捉按键&#xff1a;探索基础和应用 Python作为高级编程语言&#xff0c;可以用于各种任务&#xff0c;例如数据分析、机器学习、图形用户界面等等。其中&#xff0c;捕捉用户键盘输入是一个常见的任务&#xff0c;它可以用于实现简单的游戏、命令行应用和用户交互&…