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 个函数达到目标:既允许嵌套调用,又能恢复初始值。

  • 相关阅读:
    es6-字符串常用方法
    新增行数据校验
    python-Django路由传参
    递归算法
    CSS动画效果
    克隆远程仓库
    添加git仓库
    滚动条——overflow:auto 自定义样式
    CSS——链接伪类选择器
    进程,线程,同步 ,异步
  • 原文地址:https://www.cnblogs.com/rimelink/p/12617679.html
Copyright © 2011-2022 走看看