2、SYS/BIOS--SWI

本模块主要介绍软件中断(SWI);软件中断通过调用SYS/BIOS中断API接口函数如Swi_post()来触发中断程序。SWI优先级高于任务,低于HWI。

同以下API函数可以触发或者发起一个SWI:

  1. Swi_andn():当触发器值变为0时,发出(post)一个Swi对象
  2. Swi_dec():当触发器值变为0时,发出(post)一个Swi对象
  3. Swi_inc():在发出一个Swi对象时,Swi触发器值增加一
  4. Swi_or():根据作为参数传递的一个掩码设置触发变量相应的位
  5. Swi_post():发布一个Swi,并且不修改Swi对象触发变量的值

当程序调用以上中的一个函数时,SWI管理器会规划相应的SWI函数执行。

创建SWI可以动态或者静态创建SWI

动态创建SWI:

Swi_Handle swi0;
Swi_Params swiParams;
Error_Block eb;
Error_init(&eb);
Swi_Params_init(&swiParams);
swi0 = Swi_create(swiFunc, &swiParams, &eb);
if (swi0 == NULL) {
System_abort("Swi create failed");
}

swi0句柄用于创建SWI对象,swiFunc是与SWI相关的函数,swiParams是结构体包含了Swi实例的参数。eb为错误块,通过它处理在执行Swi对象创建时发生的错误。

静态创建Swi对象在cfg文件中:

var Swi = xdc.useModule('ti.sysbios.knl.Swi');
var swiParams = new Swi.Params();
program.global.swi0 = Swi.create(swiParams);

 SWI的中断优先级共计16个,最低优先级为0,最高优先级为15。

 

Swi钩子函数:

typedef struct Swi_HookSet {
    Void (*registerFxn)(Int); /* Register Hook */
    Void (*createFxn)(Handle, Error.Block *); /* Create Hook */
    Void (*readyFxn)(Handle); /* Ready Hook */
    Void (*beginFxn)(Handle); /* Begin Hook */
    Void (*endFxn)(Handle); /* End Hook */
    Void (*deleteFxn)(Handle); /* Delete Hook */
};
  1. registerFxn:寄存器函数,任何静态创建的Swi在运行时被初始化前调用的一个函数,在main函数之前,中断使能前,该函数被调用。
  2. createFxn:当一个Swi被创建,包括静态或者动态创建时调用的一个函数。
  3. readyFxn:任何Swi准备运行时调用的一个函数。
  4. beginFxn:正要运行一个Swi函数前调用的一个函数。
  5. endFxn:刚刚从一个Swi函数返回之后调用的一个函数。
  6. deleteFxn:在一个Swi运行时被Swi_delete删除后调用的一个函数。

例子:

/* ======== SwiHookExample.c ========
* This example demonstrates basic Swi hook usage */
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Timestamp.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/knl/Swi.h>

Swi_Handle mySwi;
Int myHookSetId1, myHookSetId2;

/* HookSet 1 functions */
/* ======== myRegister1 ========
* invoked during Swi module startup before main
* for each HookSet */
Void myRegister1(Int hookSetId)//由registerFxn创建,在main之前被调用
{
    System_printf("myRegister1: assigned hookSet Id = %d\n", hookSetId);
    myHookSetId1 = hookSetId;
}

/* ======== myCreate1 ========
* invoked during Swi_create for dynamically created Swis */
Void myCreate1(Swi_Handle swi, Error_Block *eb)//由createFxn创建,创建swi的时候被调用
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId1);
    /* pEnv should be 0 at this point. If not, there's a bug. */
    System_printf("myCreate1: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId1, (Ptr)0xdead1);
}

//* ======== myReady1 ========
/* invoked when Swi is posted */
Void myReady1(Swi_Handle swi)//当swi准备运行时执行,由readyFxn创建
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId1);
    System_printf("myReady1: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId1, (Ptr)0xbeef1);
}

/* ======== myBegin1 ========
* invoked just before Swi func is run */
Void myBegin1(Swi_Handle swi)//由myBegin1创建
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId1);
    System_printf("myBegin1: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId1, (Ptr)0xfeeb1);
}

/* ======== myEnd1 ========
* invoked after Swi func returns */
Void myEnd1(Swi_Handle swi)//endFxn创建
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId1);
    System_printf("myEnd1: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId1, (Ptr)0xc0de1);
}

/* ======== myDelete1 ========
* invoked upon Swi deletion */
Void myDelete1(Swi_Handle swi)//由deleteFxn创建
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId1);
    System_printf("myDelete1: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
}

/* HookSet 2 functions */
/* ======== myRegister2 ========
* invoked during Swi module startup before main
* for each HookSet */
Void myRegister2(Int hookSetId)
{
    System_printf("myRegister2: assigned hookSet Id = %d\n", hookSetId);
    myHookSetId2 = hookSetId;
}

/* ======== myCreate2 ========
* invoked during Swi_create for dynamically created Swis */
Void myCreate2(Swi_Handle swi, Error_Block *eb)
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId2);
    /* pEnv should be 0 at this point. If not, there's a bug. */
    System_printf("myCreate2: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId2, (Ptr)0xdead2);
}

/* ======== myReady2 ========
* invoked when Swi is posted */
Void myReady2(Swi_Handle swi)
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId2);
    System_printf("myReady2: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId2, (Ptr)0xbeef2);
}

/* ======== myBegin2 ========
* invoked just before Swi func is run */
Void myBegin2(Swi_Handle swi)
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId2);
    System_printf("myBegin2: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId2, (Ptr)0xfeeb2);
}

/* ======== myEnd2 ========
* invoked after Swi func returns */
Void myEnd2(Swi_Handle swi)
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId2);
    System_printf("myEnd2: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
    Swi_setHookContext(swi, myHookSetId2, (Ptr)0xc0de2);
}

/* ======== myDelete2 ========
* invoked upon Swi deletion */
Void myDelete2(Swi_Handle swi)
{
    Ptr pEnv;
    pEnv = Swi_getHookContext(swi, myHookSetId2);
    System_printf("myDelete2: pEnv = 0x%x, time = %d\n", pEnv, Timestamp_get32());
}

/* ======== mySwiFunc ======== */
Void mySwiFunc(UArg arg0, UArg arg1)
{
    System_printf("Entering mySwi.\n");//swi函数。即软件中断处理函数
}

/* ======== myTaskFunc ======== */
Void myTaskFunc(UArg arg0, UArg arg1)
{
    System_printf("Entering myTask.\n");//在此之前没有中断触发因此执行任务函数
    System_printf("Posting mySwi.\n");
    Swi_post(mySwi);    //启动软件中断
    System_printf("Deleting mySwi.\n");
    Swi_delete(&mySwi); //删除swi
    System_printf("myTask exiting ...\n");
}

/* ======== myIdleFunc ======== */
Void myIdleFunc()
{
    System_printf("Entering myIdleFunc().\n");//空闲函数,在所有中断完成后才执行
    System_exit(0);
}

/* ======== main ======== */
Int main(Int argc, Char* argv[])
{
    Error_Block eb;
    Error_init(&eb);
    System_printf("Starting SwiHookExample...\n");//main之前执行registerFxn
    /* Create mySwi with default params
    * to exercise Swi Hook Functions */
    mySwi = Swi_create(mySwiFunc, NULL, &eb);//创建swi对象
    if (mySwi == NULL) {
    System_abort("Swi create failed");
    }
    BIOS_start();
    return (0);
}

CFG配置文件:

/* pull in Timestamp to print time in hook functions */
xdc.useModule('xdc.runtime.Timestamp');

/* Disable Clock so that ours is the only Swi in the application */
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.clockEnabled = false;

var Idle = xdc.useModule('ti.sysbios.knl.Idle');
Idle.addFunc('&myIdleFunc');

/* Create myTask with default task params */
var Task = xdc.useModule('ti.sysbios.knl.Task');
var taskParams = new Task.Params();
Program.global.myTask = Task.create('&myTaskFunc', taskParams);

/* Define and add two Swi Hook Sets */
var Swi = xdc.useModule("ti.sysbios.knl.Swi");

/* Hook Set 1 */
Swi.addHookSet({
	registerFxn: '&myRegister1',	//寄存器钩子函数,在main函数前,中断使能前被调用
	createFxn: '&myCreate1',
	readyFxn: '&myReady1',			//当post一个swi后,任何SWI准备运行时调用的函数
	beginFxn: '&myBegin1',			//在正要运行一个swi函数前调用
	endFxn: '&myEnd1',				//执行完swi创建的函数后执行该函数
	deleteFxn: '&myDelete1'			//执行完swi_delete后执行
});

/* Hook Set 2 */
Swi.addHookSet({
	registerFxn: '&myRegister2',
	createFxn: '&myCreate2',
	readyFxn: '&myReady2',
	beginFxn: '&myBegin2',
	endFxn: '&myEnd2',
	deleteFxn: '&myDelete2'
});

运行结果:

 

结果分析:

  1.  程序启动后,首先执行registerFxn创建的myRegister1和myRegister2函数,ID分别为1,2。
  2. 接着执行main函数中的System_printf函数。
  3. 执行Swi_create函数,创建myswi对象。执行由createFxn创建的myCreate1和myCreate2函数。createFxn创建的函数是在创建swi对象前被调用,执行后才会执行Swi_create(mySwiFunc, NULL, &eb)中的mySwiFunc函数。
  4. 此时没有发布SWI,因此执行较低优先级的任务函数,由Task.create创建的myTaskFunc函数中断内容。
  5. myTaskFunc函数中通过Swi_post(mySwi)发布了一个swi中断,便执行由readyFxn创建的myReady1和myReady2函数。该函数是在发布了swi后,当swi准备执行时所运行的函数。
  6. 在执行完readyFxn创建后的函数后,执行由beginFxn创建的myBegin1和myBegin2函数。
  7. 这里正式执行swi软件中断函数,即swi中断处理函数是在beginFxn后执行。
  8. 中断处理函数执行完后,执行由endFxn创建的myEnd1和myEnd2函数。该函数是在执行完swi创建的中断函数后执行。
  9. 返回myTaskFunc中继续执行System_printf("Deleting mySwi.\n")。
  10. 在myTaskFunc中执行Swi_delete(&mySwi);执行后执行由deleteFxn创建的myDelete1和myDelete2函数。
  11. 返回myTaskFunc中继续执行System_printf("myTask exiting ...\n")。
  12. 所有中断执行完后,执行空闲进程中断的函数即myIdleFunc。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值