本文主要講解SYS/BIOS的定時器模塊(CLOCK)。
對於定時器模塊,可以設置成週期性的定時器,也可以設置爲一次性的定時。如上圖所示,當startFLAG爲True表示立即啓動而不需要調用Clock_start()來啓動。Clock_create中來配置timeout,clkParams.period設置是否爲週期調用,若爲週期性的定時器,則會沒經過period個時間重複調用Function。Clock_getTicks()獲得從Clock_start開始時的節拍總數,當返回的值在達到32位存儲的最大值後,將返回到零。而時鐘的創建Clock_create()只能在TASK或者main中進行創建。
以下通過兩種方式來創建一個週期定時器:
1.
Clock_Params clockParams;//創建結構體對象clockParams
Clock_Handle myClock; //創建myclock句柄
Error_Block eb; //創建錯誤塊
Error_init(&eb); //初始化錯誤塊
Clock_Params_init(&clockParams); //初始化時鐘參數
clockParams.period = 5; //設置定時器的執行週期
clockParams.startFlag = TRUE; //True表示create後立即啓動
clockParams.arg = (UArg)0x5555;
myClock = Clock_create(myHandler1, 5, &clockParams, &eb);//創建時鐘,延遲5個週期執行,週期執 行的函數名爲myHandler1,並返回myClock句柄
if (myClock == NULL) {
System_abort("Clock create failed");
}
2. 通過CFG腳本文件配置定時器:
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var clockParams = new Clock.Params();
clockParams.period = 5;
clockParams.startFlag = true;
clockParams.arg = (UArg)0x5555;
Program.global.clockInst1 = Clock.create("&myHandler1", 5, clockParams);
例子:
/*
* ======== clock.c ========
* The clock example shows how to use the ti.sysbios.knl.Clock module to
* create one-shot and periodic Clock Instances. Clock Instances are
* essentially functions that run after a certain number of Clock ticks.
*/
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
Void clk0Fxn(UArg arg0);
Void clk1Fxn(UArg arg0);
/*
* ======== main ========
*/
Int main()
{
Clock_Handle clk2; //創建clk2句柄(句柄只能調用系統提供的服務,不像指針可以操作底層的地址)
Clock_Params clkParams; //Clock_Params創建出來的結構體
/* Create a periodic Clock Instance with period = 5 system time units */
Clock_Params_init(&clkParams);//初始化時鐘參數
clkParams.period = 5; //設置函數的執行週期
clkParams.startFlag = TRUE; //立即啓動
Clock_create(clk0Fxn, 4, &clkParams, NULL);//創建時鐘,clk0Fxn爲需要週期執行的函數名,在Clock_start後延遲4執行
//錯誤塊傳遞爲NULL
/* Create an one-shot Clock Instance with timeout = 11 system time units */
clkParams.period = 0; //週期爲0,即不是週期
clkParams.startFlag = FALSE;//不立即啓動(需要手動調用Clock_start來啓動)
clk2 = Clock_create(clk1Fxn, 11, &clkParams, NULL);//創建時鐘函數clk1Fxn,在Clock_start後延遲11執行,返回clk2句柄
Clock_start(clk2);//啓動clk2句柄
BIOS_start(); /* does not return *///使能中斷
return(0);
}
/*
* ======== clk0Fxn =======
*/
Void clk0Fxn(UArg arg0)
{
UInt32 time;
time = Clock_getTicks(); //返回時鐘節拍數從clock開始時,返回的值在達到32位存儲的最大值後,將返回到零。
System_printf("System time in clk0Fxn = %lu\n", (ULong)time); //打印節拍數
if(time > 40) { //定時器超過40才執行中止
System_printf("Calling BIOS_exit() from clk1Fxn\n");
BIOS_exit(0);//當你想讓SYS/BIOS中止執行,它會調用System_exit()然後中止
}
}
/*
* ======== clk1Fxn =======
*/
Void clk1Fxn(UArg arg0)
{
UInt32 time;
time = Clock_getTicks();
System_printf("System time in clk1Fxn = %lu\n", (ULong)time); //返回時鐘節拍數從clock開始時,返回的值在達到32位存儲的最大值後,將返回到零。
}
配置文件:
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Main = xdc.useModule('xdc.runtime.Main');
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
/*
* Uncomment this line to globally disable Asserts.
* All modules inherit the default from the 'Defaults' module. You
* can override these defaults on a per-module basis using Module.common$.
* Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
*/
/*
* Uncomment this line to keep module names from being loaded on the target.
* The module name strings are placed in the .const section. Setting this
* parameter to false will save space in the .const section. Error and
* Assert messages will contain an "unknown module" prefix instead
* of the actual module name.
Defaults.common$.namedModule = false;
*/
/*
* Minimize exit handler array in System. The System module includes
* an array of functions that are registered with System_atexit() to be
* called by System_exit().
*/
System.maxAtexitHandlers = 4;
/*
* Uncomment this line to disable the Error print function.
* We lose error information when this is disabled since the errors are
* not printed. Disabling the raiseHook will save some code space if
* your app is not using System_printf() since the Error_print() function
* calls System_printf().
Error.raiseHook = null;
*/
/*
* Uncomment this line to keep Error, Assert, and Log strings from being
* loaded on the target. These strings are placed in the .const section.
* Setting this parameter to false will save space in the .const section.
* Error, Assert and Log message will print raw ids and args instead of
* a formatted message.
Text.isLoaded = false;
*/
/*
* Uncomment this line to disable the output of characters by SysMin
* when the program exits. SysMin writes characters to a circular buffer.
* This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
*/
/*
* The BIOS module will create the default heap for the system.
* Specify the size of this default heap.
*/
BIOS.heapSize = 0x2000;
/*
* Build a custom SYS/BIOS library from sources.
*/
BIOS.libType = BIOS.LibType_Custom;
/* System stack size (used by ISRs and Swis) */
Program.stack = 0x1000;
/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x400;
/*
* Create and install logger for the whole system
*/
var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 32;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;
/*
* Configure SysMin for System_printfs because SysStd cannot be used when
* calling System_printf from Hwis and Swis
*/
System.SupportProxy = SysMin;
運行結果:
結果分析:
main函數中創建了兩個定時器,一個是週期性,一個非週期性,對於週期性定時器,當節拍數大於40後,系統中止,在此之前,每過5個週期執行一次clk0Fxn。而對於非週期定時器,當調用Clock_start(clk2)後,節拍開始計數,time = Clock_getTicks()獲得節拍數,System_printf進行節拍數的打印。