Cortex-M系列中断和异常(一)

2023-05-16

文章目录

  • 1. 中断与异常
    • 1.1 异常的类型
    • 1.2 异常及中断的管理
      • 1.2.1 中断的一般使用方法
    • 1.3 优先级的定义
    • 1.4 向量表和向量表的重定义
      • 1.4.1 向量表重定向的应用场景
    • 1.5 中断输入和挂起行为
      • 1.5.1 中断请求的类型


1. 中断与异常

    什么是中断?什么是异常?其实他们是同一个东西,只是来源不同叫法不同。有系统内部引起的异常就叫异常,而由外设或外部引脚引起的异常就叫做中断,中断也是一种异常。提到异常和中断不得不提中断向量控制器NVIC,它是一个硬件结构,它会接收很多中断源产生的请求,根据中断编号执行对应的函数,具体的结构图如下:
[外链图片转存失败(img-7W9q6sTn-1568885073007)(F97A1AA04DC04578B2910DC5AFFAB61A)]
    Cortex-M3和Cortex-M4的NVIC最多支持240个IRQ(中断请求)、一个不可屏蔽中断(NMI),一个systick(系统节拍)定时器中断以及多个系统异常。多数IRQ由定时器、I/O端口和通信接口(如UART、I2C)等外设产生。NMI通常由看门狗定时器或掉电检测器等外设产生,其余的异常则是来气处理器内核,中断还可以利用软件生成。

1.1 异常的类型

    Cortex-M架构支持多种异常和外部中断,编号1~15为系统异常,16及以上的则为中断输入。包括中断在内的大多数的异常的优先级都是可编程的,一些系统异常具有固定的优先级。(中断编号和中断优先级不是同一个概念,注意区分;异常的枚举值和异常编号也不是一个概念)

系统异常列表:
在这里插入图片描述
外部中断列表:
在这里插入图片描述
    中断编号(如中断#0)表示NVIC的中断输入,对于识别是哪一个中断有重要意义,例如:当前正在运行的异常的编号数值位于特殊寄存器-中断程序状态寄存器(IPSR)中,或者NVIC中一个名为中断控制状态寄存器中。如果使用CMSIS-Core来编程,中断编号由枚举来定义,从数值0开始(代表中断 #0),系统异常的编号为负数,具体的定义如下:
在这里插入图片描述
中断编号和相关的枚举是根据具体的芯片而定的,他们一般位于微控制器供应商提供的头文件中,一个名为IRQn的typedef段中。

1.2 异常及中断的管理

    异常及中断的管理都是通过寄存器来控制的,相关寄存器主要有NVIC和系统控制块(SCB system control block),而实际上SCB也是NVIC的一部分,只是CMSIS-Core将其定义在了单独的结构体中。NVIC和SCB位于系统控制空间(SCS system control space),地址从0xE000E000开始,大小为4KB。SCS空间中还有systick定制器,存储器保护单元MPU以及调试的寄存器。该地址区的寄存器基本上都只能由运行在特权访问等级的代码访问。唯一的例外是-软件触发中断寄存器(STIR)。中断操作一般可以使用CMSIS-Core提供的函数:函数列表如下:
在这里插入图片描述

1.2.1 中断的一般使用方法

    复位后所有的中断都处于禁止状态,且默认优先级都为0。在使用任何一个中断之前,(1)设置中断优先级(2)使能外设中的可以触发中断的中断产生控制(3)使能NVIC的中断。
    中断服务程序(ISR)需要写入启动代码中的中断向量表里面,ISR的名字要与启动代码中向量表使用的名字一样,启动代码由芯片供应商来提供。

1.3 优先级的定义

    无论是异常还是有中断都是有优先级的,优先级的大小决定了中断的执行顺序和能够嵌套(优先级数值越小,优先级越高),抢占优先级高的能够打断抢占优先级的的中断,这就是所谓的中断嵌套。有一些异常时有固定优先级的不能够被编程,例如:复位、NMI和HardFault具有固定的负数优先级,其他可编程优先级的范围为0~255(8个bit)。

    可编程优先级的实际数量由芯片设计厂商直接决定,其实多数的Cortex-M3和Cortex-M4支持的有限级较少,如8(3个bit),16(4个bit),32(5个bit)等。这是因为大量的优先级会增加NVIC的复杂度,而且会增加功耗降低的速度。优先级数量的减少是通过去除优先级配置寄存器的最低位(LSB)实现的。中断优先级的个数由优先级寄存器控制,宽度为3~8bits,若设计中只有了三个bit,优先级配置寄存器如下图。(STM32使用4个bits,我们公司的BLE蓝牙芯片也是4个bits)如果是用3个bit来实现,有限级的值可以为0x00(高优先级), 0x02, 0x04, 0x60,0x80, 0xa0, 0xc0, 0xe0具体的优先级等级配置如下。
在这里插入图片描述
在这里插入图片描述
    之所以移除优先级寄存器的最低位LSB而不是最高位MSB,因为这样处理的话,在不同Cortex-M设备之间移植起来更方便。从上图可以看出,3位和4位宽度的优先级寄存器有重合的优先级,因此3位上写的代码可以不需要改动就一直到4位上。

    这8位的优先级寄存器配置寄存器,又被分成了两组,一组是抢占式优先级,另一组是子优先级。分组是利用系统控制块(SCB)中一个名为优先级分组的配置寄存器,具体的分组情况如下图:
[外链图片转存失败(img-kX4u3qTY-1568885073017)(BFE921C31939444AA5D264B58B8C8429)]
    配置优先级分组可以用CMSIS-Core提供的函数接口,具体的函数接口如下:
在这里插入图片描述
    在处理器已经运行一个中断处理时能否产生另一个中断,是由该中断的抢占优先级决定的。子优先级只会用在具有相同抢占优先级的情况,具有更高优先级的异常(即优先级数值越小)会被优先处理。由于优先级的分组存在,抢占优先级最多有7个bit,因此有128个等级,若优先级分组配置为7,所有具有可编程优先级的异常则会处于相同的等级,这些异常之间就不会发生抢占。但是hardfault、NMI和复位则是例外,因为他们的优先级分别为-1,-2,-3,它们可以抢占这些异常。
    若配置优先级寄存器的宽度为3,就会有2个bit的抢占优先级,6个bit的子优先级,因为配置优先级寄存器只有三位,所以只会有1个bit的子优先级,具体的优先级数值如下:
在这里插入图片描述
    STM32使用4个bit作为优先级配置寄存器,分组用的是NVIC_PRIORITYGROUP_4,写入分组寄存器的值是3,因此STM32是没有子优先级的,4个bit全部为抢占式优先级,是可以进行中断嵌套的。

    // stm32f7xx_hal_cortex.h
    #define NVIC_PRIORITYGROUP_0         ((uint32_t)0x00000007) /*!< 0 bits for pre-emption priority
                                                                     4 bits for subpriority */
    #define NVIC_PRIORITYGROUP_1         ((uint32_t)0x00000006) /*!< 1 bits for pre-emption priority
                                                                     3 bits for subpriority */
    #define NVIC_PRIORITYGROUP_2         ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority
                                                                     2 bits for subpriority */
    #define NVIC_PRIORITYGROUP_3         ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority
                                                                     1 bits for subpriority */
    #define NVIC_PRIORITYGROUP_4         ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority
                                                                     0 bits for subpriority */
                                                                     
    // stm32f7xx_hal_cortex.c                                                              
    /** 
      * @brief  Sets the priority grouping field (preemption priority and subpriority)
      *         using the required unlock sequence.
      * @param  PriorityGroup: The priority grouping bits length. 
      *         This parameter can be one of the following values:
      *         @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority
      *                                    4 bits for subpriority
      *         @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority
      *                                    3 bits for subpriority
      *         @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority
      *                                    2 bits for subpriority
      *         @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority
      *                                    1 bits for subpriority
      *         @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority
      *                                    0 bits for subpriority
      * @note   When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. 
      *         The pending IRQ priority will be managed only by the subpriority. 
      * @retval None
      */
    void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
    {
      /* Check the parameters */
      assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
      
      /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
      NVIC_SetPriorityGrouping(PriorityGroup);
    }
    
    // core_cm7.h
    /** \brief  Set Priority Grouping
    
      The function sets the priority grouping field using the required unlock sequence.
      The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
      Only values from 0..7 are used.
      In case of a conflict between priority grouping and available
      priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
    
        \param [in]      PriorityGroup  Priority grouping field.
     */
    __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
    {
      uint32_t reg_value;
      uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */
    
      reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
      reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk));             /* clear bits to change               */
      reg_value  =  (reg_value                                   |
                    ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                    (PriorityGroupTmp << 8)                       );              /* Insert write key and priorty group */
      SCB->AIRCR =  reg_value;
    }
    
    // stm32f7xx_hal.c
    /**
      * @brief  This function is used to initialize the HAL Library; it must be the first 
      *         instruction to be executed in the main program (before to call any other
      *         HAL function), it performs the following:
      *           Configure the Flash prefetch, and instruction cache through ART accelerator.
      *           Configures the SysTick to generate an interrupt each 1 millisecond,
      *           which is clocked by the HSI (at this stage, the clock is not yet
      *           configured and thus the system is running from the internal HSI at 16 MHz).
      *           Set NVIC Group Priority to 4.
      *           Calls the HAL_MspInit() callback function defined in user file 
      *           "stm32f7xx_hal_msp.c" to do the global low level hardware initialization 
      *            
      * @note   SysTick is used as time base for the HAL_Delay() function, the application
      *         need to ensure that the SysTick time base is always set to 1 millisecond
      *         to have correct HAL operation.
      * @retval HAL status
      */
    HAL_StatusTypeDef HAL_Init(void)
    {
      /* Configure Flash prefetch and Instruction cache through ART accelerator */ 
    #if (ART_ACCLERATOR_ENABLE != 0)
       __HAL_FLASH_ART_ENABLE();
    #endif /* ART_ACCLERATOR_ENABLE */
    
      /* Set Interrupt Group Priority */
      HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); // 分组配置
    
      /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
      HAL_InitTick(TICK_INT_PRIORITY);
      
      /* Init the low level hardware */
      HAL_MspInit();
      
      /* Return function status */
      return HAL_OK;
    }

1.4 向量表和向量表的重定义

    当Cortex-M处理器接受了某异常请求后,处理器需要确定该异常处理的起始地址(如果是中断的话就要知道中断的入口函数)。起始地址的信息都存储在向量表中,向量表默认从地址0开始,向量地址则为异常编号*4,向量一般都在芯片供应商的启动文件中,即.s文件,向量表示例如下:
[外链图片转存失败(img-xK9Bslqs-1568885073022)(C88DCB5418F74179959B3072321D8094)]
    向量表的起始项就是MSP主堆栈指针的初始值,这种设计是很有必要的,因为NMI等异常可能紧接着就是复位,而且此时还没有进行任何初始化操作。一般来说起始地址0x00000000处应该为负责启动的存储器,它可以为Flash或者ROM设备,而且运行期间是不能对其进行修改的。不过有些应用可能需要运行时修改或重新定义向量表,因此Cortex-M3和Cortex-M4提供了向量表重定向的功能。这个功能通过一个名为向量表偏移寄存器(VTOR)的可编程寄存器来实现,VTOR的复位值为0,默认使用存储器的起始地址定义为向量表。若使用CISIS的设备驱动库进行应用编程,可以通过SCB->VTOR访问寄存器,要将向量表重新定义到SRAM区域,可以通过以下代码来实现:

// SRAM的起始地址为0x20000000
// _DMB _DSB等屏障指令一般都是根据架构的要求 特定语句后面就要跟着这样的屏障指令

#define HW32_REG(ADDRESS)  (*((volatile unsigned long*)(ADDRESS)))
#define VTOR_NEW_ADDR      0x20000000

int i; // 循环变量 指针地址
// 在设置VTOR前首先将向量表复制到SRAM中
for(i=0; i < 48; i++)
{
    HW32_REG(VTOR_NEW_ADDR + (i << 2)) = HW32_REG((i << 2));
}
_DMB(); // 数据存储器屏障,确保到存储器的写操作结束
SCB -> VTOR = VTOR_NEW_ADDR; // VTOR这个寄存器里面时刻存放的都是要使用的向量表
_DSB(); // 数据同步屏障,确保接下来的所有指令都使用新配置

    VTOR寄存器如下图,在使用VTOR时,需要将向量表大小扩展为下一个2的整数次方,且新向量表的及地址必须要对其这个数值。例如向量表大小为(32(中断)+ 16(系统异常)* 4(每个向量32bit,四个字节) = 192(0x0c))。192比128大因此需要2的8次方=256字节,因此向量表的地址可被设置为0x00000000, 0x00000200, 0x00000400(必须是向量表大小的整数倍)等。由于中断的最小数量为1,最小的向量表对齐为128字节,因此,VTOR的最低7bit保留,且被强制置为0。
[外链图片转存失败(img-wCzkzgUj-1568885073023)(A95570F295714BE489098483029BCE17)]

1.4.1 向量表重定向的应用场景

    向量表的重定向一般用于以下三种情形:
(1)具有Boot loader的设备
    有些微控制器具有多个程序存储器,比如启动ROM和用户flash存储器。芯片生产商一般会将启动代码boot loader预先写到启动ROM中,这样在微控制器启动时,启动ROM中的Boot loader就会首先执行,而且在跳转到用户flash的应用程序之前,会将0x00000000地址处的向量表复制到用户flash的起始地址去,同时VTOR会被设置为指向用户flash存储器的开始处,因此会使用用户flash中的向量表。具体的实现流程如下图所示:
[外链图片转存失败(img-UHqp5PWf-1568885073024)(A84E7560D6894BAE92D144CE0925A65C)]
(2)应用程序加载到RAM
    有些情况,应用程序可能会被从外部设备记载到RAM中执行,它可能会位于SD卡中,或者有的通过网络传输,这种情况下,存储在片上存储器中用于启动的程序需要初始化一些硬件、复制位于外部设备中的应用程序到RAM,然后更新VTOR后执行存储在外部的程序。具体的实现流程如下:
在这里插入图片描述
(3)动态修改向量表
    有些情况下,ROM中可能会有一个中断的多个处理实例,可能需要在应用的不同阶段在它们之间进行切换。在这种情况下,可以将向量表从程序存储器复制到SRAM中,并且设置VTOR指向SRAM中的向量表。由于SRAM中的内容可在任意时间修改,因此可以轻易地在应用的不同阶段修改中断向量。

注:向量表最少也要提供MSP的初始值以及用于系统启动的复位向量。另外,对于一些应用,若设备在启动时有触发NMI的可能,也许还需要加入NMI和hardfault向量。

1.5 中断输入和挂起行为

    每个中断是有多个属性的,(1)每个中断都是可以被禁止(默认)或者使能的,通过中断控制寄存器;(2)每个中断都是可以被挂起(Pending状态等待执行中断函数)或者解除挂起;(3)每个中断都可以处于活跃(正在处理)或非活跃状态(活跃状态位是只读的);中断被响应并能执行中断函数的条件是:挂起状态职位同时中断使能,且中断优先级比当前的优先级高。

1.5.1 中断请求的类型

    NVIC支持两种外设的中断请求,(1)脉冲中断请求;(2)高电平中断请求;这是不需要配置的,默认两种都能够响应。

    脉冲中断请求,脉冲宽度至少要一个时钟周期;而对于高电平中断请求,在ISR中的清除Pending位之前,始终保持着高电平的状态。尽管外部中请求在I/O引脚的电平可能是低有效,NVIC收到的请求信号仍然为高有效。无论是哪一种方式的中断请求来了之后,都会在挂起状态寄存器上置位。

    中断的挂起状态被存储在NVIC的可编程寄存器里面,当NVIC的中断输入被确认后,它就会触发该中断的挂起状态,即在挂起状态寄存器的相应bit位置位,即使此时中断请求取消了,挂起状态仍然为高,中断请求仍会被执行。挂起状态的意思就是中断在等待处理器处理的状态。

    处理中断的时间点有分为两种情况:(1)中断刚挂起即Pending住,处理器就直接处理,然后把Pending位清掉。(2)若处理器正在处理一个更高优先级或同等优先级的中断,或中断被某个中断屏蔽器给屏蔽掉了(屏蔽中断后如果中断来了仍然会有pending位挂起),那么在其他中断处理结束前或中断屏蔽清除前,挂起请求会一直保持。
    下面重点讲解几个典型的中断请求过程:
[外链图片转存失败(img-AJjas2hV-1568885073026)(DEA8862090134DEFA28EA572D8CFAC2C)]
    如上图7.14所示,当中断正在被处理时它会处于活跃状态,在中断的入口处,多个寄存器会被自动压入栈中,这也被称作压栈。同时ISR的起始地址会被从向量表中取出。当中断请求来的时候中断挂起状态就置1,证明中断来了,等待着被处理器执行,当处理器执行中断处理函数的时候,会把中断的挂起位清掉,中断处理的请求电平也要被拉低。

    当中断处于活跃状态时,处理器无法在中断完成和异常返回前再次接受同一个中断请求,即中断请求即使来了,Pending位也不会被置位
[外链图片转存失败(img-svS4f03z-1568885073027)(EF30EA72A111418FB5D8E5797E357B40)]
    如上图7.15所示,当中断请求被处理器执行之前,挂起位就被清掉了,此后处理器空出来也将不会处理该中断。
[外链图片转存失败(img-iDZDeQpD-1568885073029)(D421717FF43F4E3F97495660BD996B92)]
    如上图7.16所示,当中断请求被处理器执行之前,挂起位被清掉了,但是中断请求还在,那么挂起位仍然会被重新置起来。
[外链图片转存失败(img-KDYv2LUI-1568885073030)(F49F4372AE25462F9459F5DC34AD7E7B)]
    如上图7.17所示,中断得到处理之后,挂起位被清除掉,但是中断请求依然还在,当中断函数执行完之后,又会再次将Pending位置起来,进入中断。
[外链图片转存失败(img-vTwwXSxp-1568885073031)(1F57BDC71BE74CC2B315E8178698A07A)]
    如上图7.18所示,对于脉冲形式的中断请求,在中断被执行前,即pending位被清掉前,无论来多少次中断请求,都按照一次来算。
[外链图片转存失败(img-yOmNckEi-1568885073032)(60948B0A149048698C6CD4AB761BD2B9)]

    如上图7.19所示,当处理器正在处理中断的时候(已经将Pending位清掉),有来了中断请求,这时就会又把Pending位置起,当前中断处理完成之后,则会再次进入中断。

    即使中断被禁止了,它的Pending状态仍然是可以被置的,即在_disable_irq之后中断请求仍然会将中断Pending位置位,这种情况下,中断稍后被使能了,它让然可以被触发并得到执行。但是有的时候我们希望临界区里面来的中断不被执行,这就需要在使能中断_enable_iqr之前清除中断Pending位。一般来说,NMI的请求方式和中孤单类似。若当前没有在运行NMI处理,或者处理器被暂停或处于锁定状态,由于NMI具有最高优先级且不能被禁止,因此它几乎会立即执行。

参考书籍:
《Cortex-M3/4权威指南》
《FreeRTOS源码详解与应用开发》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cortex-M系列中断和异常(一) 的相关文章

  • 笑谈Android图表------MPAndroidChart

    MPAndroidChart是一款基于Android的开源图表库 xff0c MPAndroidChart不仅可以在Android设备上绘制各种统计图表 xff0c 而且可以对图表进行拖动和缩放操作 xff0c 应用起来非常灵活 MPAnd
  • 详谈高大上的图片加载框架Glide -应用篇

    在Android设备上 xff0c 加载网络图片一直是一个头疼的问题 xff0c 因为Android设备种类繁多 xff08 当然最主要的是配置 xff09 xff0c 处理的稍不周到轻则应用卡顿 xff0c 严重者就会出现OOM的 xff
  • 微信小程序开发环境搭建

    微信小程序可谓是今天最火的一个名词了 xff0c 一经出现真是轰炸了整个开发人员 xff0c 当然很多App开发人员有了一个担心 xff0c 微信小程序的到来会不会给移动端App带来一个寒冬 xff0c 身为一个Android开发者我是不相
  • 实现APP定位功能

    源码传送门 若你不小心点击进入GitHub了捎带给个star 前言 最近更新项目中用的百度定位SDK时遇见了一个奇葩的问题 当升级SDK后百度定位一直返回505 通过百度定位官网查看该码表示AK非法或者不存在 很纠结 于是自己又写了一个de
  • Linux系统命令行创建新文件

    linux命令行创建文件 方法有许多 xff0c 下面简单介绍一下 方法1 使用cat命令 cat span class token operator gt span sample1 span class token punctuation
  • Java利器之UML类图详解

    前言 UML xff08 Unified Modeling Language xff09 中文统一建模语言 xff0c 是一种开放的方法 xff0c 用于说明 可视化 构建和编写一个正在开发的 面向对象的 软件密集系统的制品的开放方法 UM
  • 从零开始学习Linux部署Java web项目

    前言 最近越来越发现需要学习的东西太多了 xff0c 前几天公司服务器出现问题 xff0c 需要对服务器硬件进行维护 xff0c 当然服务器上的服务需要部署到另一个服务器上 这对于我来说是很陌生的 xff0c 虽然这件工作没有让我去做 xf
  • 致敬我奋起直追的2016

    前言 其实当用奋起直追这个词语形容我的2016时 xff0c 自己一度怀疑是不是配得上这个词语 虽然2016成长了不少 xff0c 但是依然没有达到我想要的效果 在学习过程中不断出现越学越倒退的感觉 还偶尔会出现一些恐惧感 不过庆幸的是 x
  • 微信小程序分页加载

    分页加载功能大家遇到的应该会经常遇到 xff0c 应用场景也很多 xff0c 例如微博 xff0c QQ xff0c 微信朋友圈以及新闻类应用 xff0c 都会有分页加载的功能 xff0c 这不仅节省了我们用户的流量 xff0c 还提升了用
  • ReactNative ViewPageAndroid组件详解

    源码传送门 在我们开发Android的时候 xff0c ViewPage这个控件的使用频率还是很高的 xff0c 最简单的就是制作引导页 xff0c 应用程序的主界面等 xff0c 在ReactNative开发中实现该功能的组件是ViewP
  • Android自定义数字键盘

    好久没有写Android的文章了 xff0c 有两三个月多了吧 xff0c 刚开始搞微信小程序 xff0c 后来又开搞ReactNative 现在又兴奋的开搞AI机器学习的东西 xff0c 感觉挺有意思的 xff0c 不过AI与其它的东西相
  • ConstraintLayout基础介绍

    自去年Google I O 大会发布ConstraintLayout至今 xff0c 已有一年多的时间 xff0c 但是并没有普及开来 xff0c 了解过ConstraintLayout布局的人知道 xff0c 它的性能的确提升了不少 在前
  • 嵌入式Linux实战开发之项目总体概述(基于IMX6ULL)

    文章目录 前言 xff08 一 xff09 开发环境 xff08 二 xff09 项目基本概述 xff08 三 xff09 程序框架 xff08 四 xff09 参考资料 前言 现在越来越多的智能设备融入到我们的生活 xff0c 然而 xf
  • Jetson Xavier NX安装opencv3.4.5(小白教程)

    作为小白 xff0c 近期开始上手嵌入式设备Jetson Xavier NX xff0c 系统为Ubuntu 18 04 6 xff0c 而因项目开发环境需要Opencv3 4 5版本 xff0c 预装系统内安装的是Opencv4 1 1
  • tortoisegit安装及实用操作

    TortoiseGit安装及实用操作 TortoiseGit安装TortoiseGit配置TortoiseGit基本操作Git Clone 克隆远程仓库到本地Git Commit 提交改动到本地的版本库Git Push 将本地修改提交到远程
  • linux系统如何开启和关闭core dump

    概述 大多数Linux系统默认开始core dump 我们一方面咱们想要收集信息以提升稳定性 排除故障 xff1b 另外一方面 xff0c 我们又想要限制debug的数据 避免泄漏一些敏感数据 第一个选择适合于研究不稳定的程序的机器 第二个
  • cartographer输出机器人相对地图位姿

    cartographer xff08 0 3 0版本 xff09 中机器人位姿是以tf的格式发布的 cartographer在关于位姿的tf tree为 xff1a map gt odom gt base footprint 其中odom
  • SUMO跟车模型之IDM模型

    IDM 智能交通模型Intelligent Driver Model 优点 xff1a IDM模型的参数数量少 意义明确 xff0c 并且能用统一的模型描述从自由流到完全拥堵流的不同状态 缺点 xff1a 缺乏随机项 xff0c 也就是输入
  • 《Python程序设计与算法基础教程(第二版)》江红 余青松 课后选择题 课后填空题答案

    目录 第一章一 选择题二 填空题 第二章一 选择题二 填空题 第三章一 选择题二 填空题 第四章一 选择题二 填空题 第五章一 选择题二 填空题 第八章一 选择题二 填空题 第一章 一 选择题 Python语言属于 C A 机器语言 B 汇
  • TensorFlow学习(二):变量常量类型

    更新时间 xff1a 2017 2 27 tensorflow 1 0出来了 xff0c API和以前有了一些不一样 xff0c 所以这里把把之前的代码迁移到新的上面去 更新时间 xff1a 2017 5 4 对于一些性质有了新的认识 补充

随机推荐

  • CAN总线的数据校验

    题目来源 有很多网友在QQ上问关于CAN总线上数据需不需要加校验 xff0c 换句话说 xff0c CAN总线支不支持校验 xff0c 我们需要在我们的数据场 xff08 数据域 xff09 加上校验码吗 xff1f 答案是否定的 CAN总
  • TensorFlow中报错 module ‘tensorflow_core._api.v2.train‘ has no attribute ‘GradientDescentOptimize

    原来函数是这样写的 xff1a optimizer 61 tf train GradientDescentOptimizer 报错 xff1a AttributeError module 39 tensorflow core api v2
  • 有趣的黑客网站 | 伪装成黑客高手,像电影黑客一样打字如飞

    当黑客 xff0c 门槛太高 xff1b 装黑客 xff0c 那就太容易了 今天刷知乎的时候无意中看到一个非常神奇的网站 xff0c 能让你瞬间变身成电影中的黑客 xff0c 操作出一系列看起来非常牛逼且装逼的功能 你只管噼里啪啦打字 xf
  • win10共享打印机(连接共享打印机的两种方法,IP地址变化的连接方法)

    一 首先电脑连接打印机 xff0c 把所连接的打印机设置为共享 xff0c 如下图所示 xff1a 先打开电脑设置 xff0c 然后点击设备 打印机和扫描仪 xff0c 打开如下界面 点击管理 打印机属性 xff0c 会出现如下界面 点击共
  • (Python)Pandas reset_index()用法总结

    Pandas是一个数据处理的库 xff0c 今天我们来学习reset index 这个函数的用法 pandas DataFrame reset index 函数作用 xff1a 重置索引或其level 重置数据帧的索引 xff0c 并使用默
  • 用Python批量修改图片名称(后缀)

    当我们需要修改批量即几百幅图片的名称或后缀时 xff0c 如果一个一个图片名称去重命名或是修改的话工作量就会很大 作为一名程序员 xff0c 当然是要通过代码去解决这些繁琐的事情 下面是用python代码来实现批量修改图片名称的代码 xff
  • git基本操作介绍

    简介 本文会简单介绍git的基本操作 这篇文章适合对git的安装 使用 运行环境 工作原理有一定了解的人员阅读 xff1b 对于初学者 xff0c 可以先参考以下文章 xff1a 最新git安装教程 windows系统git安装教程 git
  • Anaconda创建跟别人环境配置一样的虚拟环境(coda env creat -f environment.yml)

    当我们跑别人在github上的代码时 xff0c 往往需要配置跟作者一样的环境 当作者导出自己的环境配置时 xff0c 一般都是 yml文件 xff0c 这时候需要输入命令行来实现配置一模一样的环境 导出的yml文件一般配置如下 xff1a
  • 计算机视觉代码学习

    前言 自从2012年Hinton提出Alexnet以来 xff0c 深度学习 计算机视觉 xff08 CV xff09 就成为一个非常热门的赛道 从学术界到工业界 xff0c 纷纷掀起一股人工智能的浪潮 特别是学术界 xff0c 计算机视觉
  • 如何准备大学生电子设计竞赛

    大学生电子设计竞赛难度中上 xff0c 一般有好几个类型题目可以选择 xff0c 参赛者可以根据自己团队的能力 优势去选择合适自己的题目 xff0c 灵活自主空间较大 参赛的同学们可以在暑假好好学习相关内容 xff0c 把往年的题目拿来练练
  • 聊聊ChatGPT

    ChatGPT 这几周科技圈最火的当属ChatGPT xff0c 自媒体中十篇有九篇都是关于ChatGPT的 ChatGPT上可知天文 xff0c 下可知地理 xff0c 还可写论文 搞代 写小说 xff0c 可谓 全能型选手 自从去年11
  • 修改简历有用吗

    看情况 xff0c 一般都是很有用哒 xff01 简历修改会突出你的重点和优点 xff0c 优化你的简历内容 xff0c 让面试官一眼看到简历就被吸引了 xff01 如以上图片所示
  • 运行Python时出现SyntaxError: EOL while scanning string literal解决方法

    当运行Python时 xff0c 出行SyntaxError EOL while scanning string literal 一般是语法出现错误 xff0c 看一下是不是哪里忘记添加符号或是分号 xff1a 这些没打
  • 数据结构选择练习题(有解析)

    前言 已经到期末了 xff0c 昨天进行了一次马原考试 xff0c 那时候挺紧张的 xff0c 那时候虽然写完了试卷 xff0c 但是有4道题是乱写的 xff0c 因为我刚好没有背 xff0c 希望不会挂科吧 然后今天呢 xff0c 就开始
  • 论文阅读_异常检测综述

    英文题目 xff1a Anomaly Detection A Survey 中文题目 xff1a 异常检测综述 论文地址 xff1a https readpaper com paper 2122646361 领域 xff1a 异常检测 发表
  • 解决Mybatis-Plus分页插件无效

    1 导入依赖 span class token tag span class token tag span class token punctuation lt span dependencies span span class token
  • 一、FreeRTOS任务调度相关函数详解

    文章目录 1 FreeRTOS任务调度及相关函数分析1 1 任务创建过程分析1 1 1 任务创建函数分析1 1 2 任务初始化函数分析1 1 3 任务堆栈初始化分析1 1 4 添加任务到就绪列表 1 2 任务删除过程分析1 3 任务挂起过程
  • linux的exit和_exit

    进程退出 退出一个进程有多种方式 xff1a 正常退出 xff1a 在main函数里return 在进程里面调用exit exit 在进程的最后一个子线程调用pthread exit 异常退出 xff1a 被信号 xff08 9 15 xf
  • 三、任务切换之PendSV异常

    文章目录 PendSV异常1 没有PendSV异常的任务切换2 有PendSV异常的任务切换2 1 系统调用引起的任务切换2 2 systick中断引起任务切换2 3 PendSV异常处理函数2 4 寻找下一个要运行的任务2 5 时间片调度
  • Cortex-M系列中断和异常(一)

    文章目录 1 中断与异常1 1 异常的类型1 2 异常及中断的管理1 2 1 中断的一般使用方法 1 3 优先级的定义1 4 向量表和向量表的重定义1 4 1 向量表重定向的应用场景 1 5 中断输入和挂起行为1 5 1 中断请求的类型 1