Cortex-A7的GIC(全局中断控制器)使用方法(5):基于stm32MP135的GIC配置API配置GIC

0 参考资料

STM32MP13xx参考手册.pdf(RM0475)
ARM Generic Interrupt Controller Architecture version 2.0 - Architecture Specification.pdf

1 基于Cortex-A7的GIC配置API配置GIC

前面我们已经了解了GIC几个关键的寄存器,通过这几个关键寄存器,我们就可以按照NVIC的用法,使用GIC对中断进行管理。操作步骤概括如下:
(1)设置中断优先级掩码寄存器GICC_PMR,确定中断优先级位数
(2)设置中断抢占优先级和响应优先级配置寄存器GICC_BPR,确定中断抢占优先级和响应优先级的位数
(3)设置中断优先级配置寄存器GICD_IPRIORITYRn,指定中断优先级
(4)设置中断使能寄存器GICD_ISENABLERn/中断失能寄存器GICD_ICENABLERn来使能/失能中断
相关代码如下:

/**
 * @brief GIC初始化
 *
 * @param prio_bits 中断优先级位数0-5
 * @param main_prio_bits 中断抢占优先级(主优先级)位数(不得为0)
 * @return int 
 */
int gic_init(u32 prio_bits, u32 main_prio_bits)
{
    u32 i;
    u32 pmr_mask = 0;

    if (prio_bits > STM32MP13XX_PRIO_MAX_BITS)
    {
        return -1;
    }

    if ((main_prio_bits > prio_bits) || (main_prio_bits == 0))
    {
        return -1;
    }

    /* 构造GIMC_PMR寄存器值 */
    for (i = 0; i < prio_bits; i++)
    {
        pmr_mask |= (1 << i);
    }
    pmr_mask = pmr_mask << 3;

    /* 将pmr_mask值写入GIMC_PMR寄存器,设置中断优先级位数 */
    GIC_SetInterfacePriorityMask(pmr_mask);
    imx_printf("pmr_mask : 0x%x\r\n", pmr_mask);

    /* 将抢占优先级设置值写入GICC_BPR寄存器 */
    GIC_SetBinaryPoint(7 - main_prio_bits);
    imx_printf("7 - main_prio_bits : 0x%x\r\n", 7 - main_prio_bits);

    gic_cfg.prio_bits = prio_bits;
    gic_cfg.main_prio_bits = main_prio_bits;

    return 0;
}

/**
 * @brief GIC中断优先级配置
 * 
 * @param IRQn 中断ID
 * @param main_prio 主优先级
 * @param sub_prio 子优先级
 * @return int 0:成功 -1:失败
 */
int gic_prio_config(IRQn_Type IRQn, u32 main_prio, u32 sub_prio)
{
    u32 priority = 0;

    /* 如果主优先级大于主优先级位数表示的最大值 */
    if (main_prio > ((1 << (gic_cfg.main_prio_bits)) - 2))
    {
        return -1;
    }

    /* 只有当主优先级位数小于优先级位数时才检查子优先级是否合理 */
    if (gic_cfg.main_prio_bits != gic_cfg.prio_bits)
    {
        if (sub_prio > ((1 << (gic_cfg.prio_bits - gic_cfg.main_prio_bits)) - 1))
        {
            return -1;
        }
    }


    if (gic_cfg.main_prio_bits == gic_cfg.prio_bits)
    {
        /* 仅包含主优先级 */
        priority = main_prio << 3;
    }
    else
    {
        /* 包含主优先级和子优先级 */
        priority = ((main_prio << (gic_cfg.prio_bits - gic_cfg.main_prio_bits)) | (sub_prio)) << 3;
    }
    imx_printf("priority : 0x%x\r\n", priority);
    GIC_SetPriority(IRQn, priority);

    return 0;
}

使用实例:
以配置GIC优先级位数为5,主优先级位数为3,ETH1_IRQn主优先级为5,子优先级为0为例,相关代码如下:

void config_eth1_gic_example(void)
{
    gic_init(5, 3);
    gic_prio_config(ETH1_IRQn, 5, 0);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NW嵌入式开发

感谢您的支持,让我们一起进步!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值