SylixOS Zynq平台私有中断绑定

1. 概述

    本篇主要介绍在Zynq平台编写中断相关的驱动程序时,涉及CPU私有中断的相关绑定办法。

2. 私有中断简介

    私有中断是多核CPU上特有的中断,私有中断只能被其所有者核心获取和响应,不会被其他核发现。常见的私有中断有全局定时器,私有看门狗定时器,私有定时器等,Zynq平台上还有来自PL的FIQ\IRQ。

3. 私有中断的绑定方法

3.1      常规共享中断绑定

    Zynq平台使用的是GIC通用中断框架,常规的共享中断绑定和普通的中断绑定没有区别,在SylixOS上直接调用API_InterVectorConnectAPI_InterVectorEnable这两个函数即可绑定,绑定后中断可由任意一个CPU核心响应。

3.2      私有中断绑定

    私有中断只能有所有者核心获取和响应,因此对应的中断和中断服务是绑定在相关的CPU核心上。在SylixOS下绑定私有中断需要让常规共享中断的绑定流程在对应CPU核心上完成才能成功绑定。即在驱动绑定私有中断的时候创建一个绑定在对应CPU核心上的绑定线程,然后由这个绑定线程去完成私有中断绑定。绑定流程如图 3.1示。

SylixOS Zynq平台私有中断绑定_第1张图片

图 3.1私有中断绑定流程

    Zynq平台31号私有定时器中断绑定框架如程序清单 3.1所示。

程序清单 3.1 Zynq平台31号私有定时器中断绑定框架

#define ZYNQ_VECTOR_NIRQ     31                  /* 31号私有中断           */

static LW_HANDLE  _G_bindthread       = LW_OBJECT_HANDLE_INVALID;

static LW_HANDLE  _G_syncSignal       = LW_OBJECT_HANDLE_INVALID; 

/***************************************************************************

** 函数名称: __nIrqIsr

** 功能描述: 中断服务程序

** 输 入  : pvArg

** 输 出  : NONE

** 返  回  : LW_NULL

***************************************************************************/

static irqreturn_t __nIrqIsr (PVOID  pvArg)

{

return  LW_IRQ_HANDLED;

}

/***************************************************************************

** 函数名称: __bindThread

** 功能描述: 私有中断绑定线程

** 输 入  : pvArg

** 输 出  : NONE

** 返  回  : LW_NULL

***************************************************************************/

static PVOID  __bindThread (PVOID  pvArg)

{

API_SemaphoreBPend(_G_syncSignal,

LW_OPTION_WAIT_INFINITE);              /* 等待同步信号量      */

API_InterVectorConnect(ZYNQ_VECTOR_NIRQ,             /* 连接中断服务程序    */

                     (PINT_SVR_ROUTINE)__nIrqIsr,

                     (PVOID)NULL,

                     "nIrq");

API_InterVectorEnable(ZYNQ_VECTOR_NIRQ);             /* 使能中断            */

}

/***************************************************************************

** 函数名称: __nIrqInit

** 功能描述: 中断服务初始化

** 输 入  : NONE

** 输 出  : NONE

** 返  回  : 成功返回ERROR_NONE,失败返回PX_ERROR

***************************************************************************/

INT  __nIrqInit (VOID)

{

LW_CLASS_CPUSET            cpuset;



_G_syncSignal = API_SemaphoreBCreate("SYNCSEM",     /* 创建同步等待信号    */

                                            0,

                                            LW_OPTION_OBJECT_GLOBAL,

                                            LW_NULL);

if (_G_syncSignal == LW_OBJECT_HANDLE_INVALID) {    /*判断信号量创建是否成功*/

     printk ("BIND signal init failed !\r\n");

     return PX_ERROR;

}

/*

 *  设置线程CPU绑定属性

*/

LW_CPU_ZERO(&cpuset);

LW_CPU_SET(0, &cpuset);

_G_bindthread = API_ThreadCreate("bindThread",      /* 创建绑定线程          */

                                   __bindThread,

                                   LW_NULL,

                                      LW_NULL);

if (_G_bindthread == LW_OBJECT_HANDLE_INVALID) {  /*判断绑定线程是否创建成功*/

    printk ("BIND thread init failed !\r\n");

    return PX_ERROR;

}



API_ThreadSetAffinity(_G_bindthread,               /* 将绑定线程设置到CPU0上*/

sizeof(cpuset),

&cpuset);    

API_SemaphoreBPost(_G_syncSignal);                 /* 发送信号启动绑定线程    */

}

 

转载于:https://my.oschina.net/senjienly/blog/1579296

你可能感兴趣的:(SylixOS Zynq平台私有中断绑定)