4、SYS/BIOS--CLOCK

本文主要講解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進行節拍數的打印。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章