嵌入式中断函数设计

常用中断

外部管脚中断

  即使用GPIO管脚作为中断源,连接外设,通过外设拉高或者拉低管脚,触发外部管脚中断;

定时器中断

  即使用MCU内置的Timer,通过给Timer配置定时周期,周期性的触发中断;

通信接口中断

  即MCU内置的通信模块,例如SPI、UART通信,当MCU作为从方,外设作为主方对MCU发起通信时,触发MCU通信接收中断。

中断设计原则

中断优先级

  在一个项目中,需要将所有的中断罗列出来,根据各中断功能的重要程度,即实时性,设计优先级大小。
  【例】对外通信接口一般来说优先级是最高的,需要软件以最快速度响应外部命令,是不允许被打断的。如果通信接口中断在接收的过程中被打断,转而执行其它耗时更久的事务,可能会导致命令的接收出现丢数据或其它异常。

中断函数执行负载

  中断响应函数一般来说强调小而精,不应把大量计算或者耗时操作在中断函数中执行,仅执行必要且必须的逻辑操作。如果中断函数执行时间较长,可能对程序整体的运行造成致命的影响。
  【例】在项目中存在一个定时器中断,定时周期为10ms,中断响应函数中进行了一个复杂的矩阵运算。如果该矩阵运算单次执行耗时8ms,那么对程序整体而言,有大于等于80%的负载开销在了定时器中断上了,导致定时器中断外的其它程序逻辑没有更多的MCU计算资源,也就是常说的程序饿死;如果该矩阵运算单次执行耗时为20ms,那么每次定时器中断的唤醒,无法在设计的10ms周期内执行完既定功能,这样就会导致定时器中断阻塞,因为定时器中断的唤醒一定是要在当前中断函数执行完成后的。
  上述例子说明,中断响应函数对于程序整体运行的负载是至关重要的,一般中断的负载设计不要超过20%,这样可以留出充足的MCU计算资源给其它功能模块即时执行,从维护和可扩展性的角度来看,也方便后序增加更多复杂的功能。

中断函数互斥

  由于中断的优先级高,会将当前执行的程序打断,那么中断函数在访问公共资源时,一定要做好互斥设计。
  【例1】中断响应函数中会对外设进行SPI通信,当中断外的程序对同样的外设进行SPI通信过程中,如果中断触发了,中断响应函数会立即对外设进行通信,此时两次通信时序如果混杂在一起,会导致出现通信异常。在这种情况下需要考虑锁中断操作来避免。
  【例2】中断响应函数会对全局变量a进行赋值操作,当中断外的程序在操作a时,如果此操作不是原子操作(一般来说,赋值或者计算被编译为汇编指令后,均需要多个指令才能执行完成,即不是原子操作),会导致中断执行完成后,变量a的值在程序中不符合预期。

中断函数中执行浮点计算

  高危操作,中断函数中能否执行浮点计算,依赖当前MCU中是否有浮点寄存器,如果没有,浮点计算会出现异常。一般来说,在corte-m4核及以上是支持的,如果采用更低的MCU,需要先查阅芯片用户手册。

你可能感兴趣的:(嵌入式软件实战,单片机,嵌入式硬件)