基于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
- 基于TI-RTOS的CC2650DK开发(30)--- Swi官方示例
- 基于TI-RTOS的CC2650DK开发(26)--- LCD官方示例
- 基于TI-RTOS的CC2650DK开发(9)---任务示例
- 基于TI-RTOS的CC2650DK开发(27)--- 邮箱示例
- 基于TI-RTOS的CC2650DK开发(2)---点亮LED
- 基于TI-RTOS的CC2650DK开发(5)---线程概览
- 基于TI-RTOS的CC2650DK开发(6)---硬件中断
- 基于TI-RTOS的CC2650DK开发(7)---软件中断
- 基于TI-RTOS的CC2650DK开发(8)---任务
- 基于TI-RTOS的CC2650DK开发(10)---空闲循环
- 基于TI-RTOS的CC2650DK开发(11)---信号量
- 基于TI-RTOS的CC2650DK开发(12)---事件模块
- 基于TI-RTOS的CC2650DK开发(13)---门
- 基于TI-RTOS的CC2650DK开发(14)---邮箱
- 基于TI-RTOS的CC2650DK开发(17)---支持模块
- 基于TI-RTOS的CC2650DK开发(21)---检测
- 基于TI-RTOS的CC2650DK开发(22)--- 时间基准
- 基于TI-RTOS的CC2650DK开发(23)--- 尺寸基准
- 二分图匹配模板
- 最常用的Eclipse快捷键
- 程序员面试金典: 9.9 递归和动态规划 9.9八皇后问题
- PAT甲级1001
- Ubantu 14.04 下连接mysql
- 基于TI-RTOS的CC2650DK开发(30)--- Swi官方示例
- 解析IntelliJ IDEA内部设计
- PAT1002-A+B for Polynomials
- [acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts 后缀自动机
- Gzip压缩和解压缩以及assets目录文件的拷贝
- OC中的self和super
- 给Eclipse提速的7个技巧
- caffe bug notes
- java之happen before relationship 学习篇