基于TI-RTOS的CC2650DK开发(30)--- Swi官方示例

来源:互联网 发布:post请求返回json数据 编辑:程序博客网 时间:2024/06/06 05:25
官方示例中有一个专门针对Swi的例子,它演示了Swi的几种提交方法,基本针对Swi的几种提交方法写的程序,在读此程序之前请先阅读这篇日志

先上代码:

/* XDC module Headers */#include <xdc/std.h>#include <xdc/runtime/System.h>/* BIOS module Headers */#include <ti/sysbios/BIOS.h>#include <ti/sysbios/knl/Swi.h>#include <ti/sysbios/knl/Task.h>#include <ti/sysbios/knl/Clock.h>#include <ti/sysbios/knl/Semaphore.h>/* Example/Board Header files */#include "Board.h"#define TASKSTACKSIZE           512Task_Struct task0Struct;Char task0Stack[TASKSTACKSIZE];Swi_Struct swi0Struct, swi1Struct;Swi_Handle swi0Handle, swi1Handle;Clock_Struct clk0Struct;Semaphore_Struct sem0Struct;Semaphore_Handle sem0Handle;/* *  ======== swi0Fxn ======= */Void swi0Fxn(UArg arg0, UArg arg1){    System_printf("Enter swi0Fxn, a0 = %d, a1 = %d\n", (Int)arg0, (Int)arg1);    System_printf("swi0 trigger = %d\n", Swi_getTrigger());    System_printf("swi0 pri = %d\n", Swi_getPri(swi0Handle));    System_printf("Exit swi0Fxn\n");}/* *  ======== swi1Fxn ======= */Void swi1Fxn(UArg arg0, UArg arg1){    System_printf("Enter swi1Fxn, a0 = %d, a1 = %d\n", (Int)arg0, (Int)arg1);    System_printf("swi1 trigger = %d\n", Swi_getTrigger());    System_printf("swi1 pri = %d\n", Swi_getPri(swi1Handle));    System_printf("Exit swi1Fxn\n");}/* *  ======== clk0Fxn ======= */Void clk0Fxn(UArg arg0){    Swi_post(swi0Handle);    Swi_post(swi1Handle);    Semaphore_post(sem0Handle);}/* *  ======== task0Fxn ======= */Void task0Fxn(UArg arg0, UArg arg1){    UInt key;    /* wait for swis to be posted from Clock function */    Semaphore_pend(sem0Handle, BIOS_WAIT_FOREVER);    System_printf("Running tsk0Fxn\n");    key = Swi_disable();              /* swis are disabled */    Swi_inc(swi0Handle);              /* swi0 trigger = 1 */    Swi_inc(swi0Handle);              /* swi0 trigger = 2 */    Swi_restore(key);                 /* swi0 runs */    Swi_or(swi1Handle, 0x100);        /* swi1 runs with trigger = 0x103 */    Swi_andn(swi1Handle, 0x1);        /* swi1 trigger = 0x02 */    Swi_andn(swi1Handle, 0x2);        /* swi1 runs with trigger = 0x00 */    Swi_dec(swi1Handle);              /* swi1 trigger = 2 */    Swi_dec(swi1Handle);              /* swi1 trigger = 1 */    Swi_dec(swi1Handle);              /* swi1 runs with trigger = 0 */    System_printf("Calling BIOS_exit\n");    BIOS_exit(0);}/* *  ======== main ======== */Int main(){    /* Construct BIOS objects */    Task_Params taskParams;    Swi_Params swiParams;    Semaphore_Params semParams;    Clock_Params clkParams;    /* Call board init functions */    Board_initGeneral();    Task_Params_init(&taskParams);    taskParams.stackSize = TASKSTACKSIZE;    taskParams.priority = 1;    taskParams.stack = &task0Stack;    Task_construct(&task0Struct, (Task_FuncPtr)task0Fxn, &taskParams, NULL);    Swi_Params_init(&swiParams);    swiParams.arg0 = 1;    swiParams.arg1 = 0;    swiParams.priority = 2;    swiParams.trigger = 0;    Swi_construct(&swi0Struct, (Swi_FuncPtr)swi0Fxn, &swiParams, NULL);    swi0Handle = Swi_handle(&swi0Struct);    swiParams.arg0 = 2;    swiParams.arg1 = 0;    swiParams.priority = 1;    swiParams.trigger = 3;    Swi_construct(&swi1Struct, (Swi_FuncPtr)swi1Fxn, &swiParams, NULL);    swi1Handle = Swi_handle(&swi1Struct);    /* Construct a Semaphore object to be used as a resource lock, inital count 0 */    Semaphore_Params_init(&semParams);    Semaphore_construct(&sem0Struct, 0, &semParams);    /* Obtain instance handle */    sem0Handle = Semaphore_handle(&sem0Struct);    Clock_Params_init(&clkParams);    clkParams.startFlag = TRUE;    /* Construct a periodic Clock Instance with period = 2 system time units */    Clock_construct(&clk0Struct, (Clock_FuncPtr)clk0Fxn,                    2, &clkParams);    BIOS_start();    /* Does not return */    return(0);}

运行结果:

Enter swi0Fxn, a0 = 1, a1 = 0swi0 trigger = 0swi0 pri = 2Exit swi0FxnEnter swi1Fxn, a0 = 2, a1 = 0swi1 trigger = 3swi1 pri = 1Exit swi1FxnRunning tsk0FxnEnter swi0Fxn, a0 = 1, a1 = 0swi0 trigger = 2swi0 pri = 2Exit swi0FxnEnter swi1Fxn, a0 = 2, a1 = 0swi1 trigger = 259swi1 pri = 1Exit swi1FxnEnter swi1Fxn, a0 = 2, a1 = 0swi1 trigger = 0swi1 pri = 1Exit swi1FxnEnter swi1Fxn, a0 = 2, a1 = 0swi1 trigger = 0swi1 pri = 1Exit swi1FxnCalling BIOS_exit

下面我们来梳理下程序的运行过程:
本例程创建了两个Swi,一个Task,一个Clock。
swi0:优先级为2,trigger为0
swi1:优先级为1,trigger为3

  • 程序运行,最先被执行的是clk0Fxn,它提交了两个swi,并发送一个信号量给task0Fxn。由于Clock是最高优先级的Swi,所以两个Swi和一个task只是被提交到Post列表等待执行。
  • 接下来由于swi0的优先级更高,所以先执行它,然后执行swi1。这里需要注意,Swi_post是无条件提交swi到post列表,跟trigger没任何关系,也不会更改trigger的值。
  • 接下来执行task0Fxn的Semaphore_pend之后的内容。
    key = Swi_disable();              /* swis are disabled */
    Swi_inc(swi0Handle);              /* swi0 trigger = 1 */
    Swi_inc(swi0Handle);              /* swi0 trigger = 2 */
    Swi_restore(key);                 /* swi0 runs */
这里先关闭了Swi,然后调用两次Swi_inc,从而将swi0的trigger值由1增加至2。本来Swi_inc会导致swi被提交,但由于关闭了Swi,所以swi0不会运行,直到最后一句Swi_restore使得swi重新执行后,swi0被执行。
  • 接下来执行了以下语句:
Swi_or(swi1Handle, 0x100);
首先swi1的trigger会变为0x103(参数0x100跟trigger原值0x003进行或运算得出的结果)。然后swi执行(Swi_or无条件提交swi),执行完后加上去的0x100会被抠掉,trigger又变回0x03。
  • 接下来执行了以下语句:
    Swi_andn(swi1Handle, 0x1);        /* swi1 trigger = 0x02 */
    Swi_andn(swi1Handle, 0x2);        /* swi1 runs with trigger = 0x00 */
第一句的参数0x01会把trigger值0x03变成0x02(两值进行异或操作),不提交swi。
第一句的参数0x02会把trigger值0x02变成0x00(两值进行异或操作),对于Swi_andn来说,如果trigger变0则提交swi,使得swi1被执行。
注意:swi提交完后,trigger会恢复原值0x03,这一点请参考之前日志中有关Swi_andn那一段。
  • 最后执行了以下语句:
    Swi_dec(swi1Handle);              /* swi1 trigger = 2 */
    Swi_dec(swi1Handle);              /* swi1 trigger = 1 */
    Swi_dec(swi1Handle);              /* swi1 runs with trigger = 0 */
每一句都是trigger值减1,当减到0时,swi1被提交并运行。
注意:swi提交完后,trigger会恢复原值0x03,请参考之前日志。

最后来个总结吧:
Swi_Post:用于直接触发一个函数的执行。
Swi_or:用于触发多个函数的执行。
Swi_andn:用于多个不同事件发生后才触发一个函数的执行。
Swi_dec:用于一个事件发生多次才能触发一个函数的执行。
这总结,太精辟了,直击要害啊!呵呵,慢慢体会。


0 0
原创粉丝点击