zoukankan      html  css  js  c++  java
  • 允许嵌套调用和恢复初始值,禁止和使能 MCU 中断的方法

    引入需求

    中断是 MCU 开发的重点和难点,在一些临界关键代码段(经常是 ISR 和 进程共享的硬件和变量)需要禁止和使能中断。
    这本来是一件容易的事情,因为编译器提供了原始语句
    禁止中断 __disable_interrupt();
    使能中断 __enable_interrupt();

    然而,有 2 种特殊情况的引入需要特别小心设计。
    嵌套调用 :禁止中断后,第 2,3 ... N 次禁止中断,仅当最后一次使能中断时才生效。
    恢复初始值:禁止中断时,保存当下中断寄存器状态;使能中断时,恢复保存的中断寄存器状态。

    实现代码

    /*!
     * Nested interrupt counter.
     *
     * 
    emark Interrupt should only be fully revert once the value is 0
     */
    static uint8_t    s_byIrqNestLevel = 0;
    static halIntState_t    s_intState;
    
    void BoardDisableIrq( void )
    {
        if (0 == s_byIrqNestLevel)
        {
            s_intState = __get_interrupt_state();
            __disable_interrupt();
        }
    
        s_byIrqNestLevel++;
    }
    
    void BoardEnableIrq( void )
    {
        s_byIrqNestLevel--;
        if (0 == s_byIrqNestLevel)
        {
            __set_interrupt_state(s_intState); 
        }
    }
    

    单元测试

    初始值,IRQ=Enable,嵌套=1层

    HAL_ENABLE_INTERRUPTS();
    BoardDisableIrq();
    BoardEnableIrq();
    

    初始值,IRQ=Enable,嵌套=2层

    HAL_ENABLE_INTERRUPTS();
    BoardDisableIrq();
    BoardDisableIrq();
    BoardEnableIrq();
    BoardEnableIrq();
    

    初始值,IRQ=Disable,嵌套=1层

    HAL_DISABLE_INTERRUPTS();
    BoardDisableIrq();
    BoardEnableIrq();
    

    初始值,IRQ=Disable,嵌套=3层

    HAL_DISABLE_INTERRUPTS();
    BoardDisableIrq();
    BoardDisableIrq();
    BoardDisableIrq();
    BoardEnableIrq();
    BoardEnableIrq();
    BoardEnableIrq();
    

    上面的 4 种单元测试结果说明这 2 个函数达到目标:既允许嵌套调用,又能恢复初始值。

  • 相关阅读:
    jQuery的几个Grid插件简单比较
    位运算符
    Unity --- 纹理压缩基本知识点
    Unity---资源管理中不同资源的路径获取方式
    Unity--- 资源路径问题
    数据结构 --- 基本概念
    《UnityShader入门精要》学习笔记之渲染流水线
    UnityShader中的语义相关
    补充一下角度制与弧度制的相关知识
    NGUI中处理层级问题的几个方法总结
  • 原文地址:https://www.cnblogs.com/rimelink/p/12617679.html
Copyright © 2011-2022 走看看