OMAPL138學習----DSP BIOS

參考資料:77F6-TI DSP BIOS Real-time Operating System v6.x User’s Guide.pdf

DSP/BIOS

一、關於DSP/BIOS

DSP/BIOS 是一個可裁剪實時內核,它提供了多線程搶佔、硬件抽象、實習分析、配置工具。

實時軟件組件(RTSC)爲模塊打包和配置提供了一個標準,RTSC包含一組工具(XDCtools)和一個實時包

二、線程模塊

1、DSP/BIOS 啓動順序

1) xdctools 運行時啓動順序

CPU初始化-->用戶提供的重置函數-->運行cinit()以初始化C運行環境-->運行用戶提供的first functions-->運行所有模塊的初始化函數-->運行pinit()-->運行用戶提供的 last functions-->運行main()函數

2)main()運行結束時,BIOS_start()被調用

啓動函數-->使能硬件中斷-->使能軟件中斷-->啓動計時器-->啓動任務

2、線程模塊

1)DSP/BIOS 提供了幾種不同優先級的線程,線程類型有:(從高優先級到低優先級)

硬件中斷(HWI,包括計時器函數)、軟件中斷(SWI ,包括時鐘函數)、任務、後臺線程(IDLE)

硬件中斷線程:HWI 線程,也叫ISR,是DSP/BIOS應用程序中優先級最高的線程

軟件中斷線程:軟件中斷由調用SWI模塊API函數產生

任務線程:DSP/BIOS提供了很多內部任務通信和同步的機制,包括信號量、事件、消息隊列、郵箱。

2)模塊的選擇

如函數功能相對簡單而且有數據共享則選擇SWI,如果需求複雜則選擇TASK。高優先級會搶佔低優先級線程,因此只有任務(task)可以等待另一個事件,比如說可用資源。SWI比TASK更高效。

幾種線程的比較:


characteristic Hwi Swi Task Idle
priority  highest  2nd highest 2nd lowest lowest
number of priority levels family/device-specific up to 32. Periodic functions run at the priority of the Clock Swi. up to 32 (including for the Idle Loop) 1
Can yield and pend No,runs to completion except for premption no,runs to completion except for preemption yes should not pend.Pending would disable all registered Idle threads.
Execution states Inactive,ready,running Inactive,ready,running Ready,running,blocked,terminated Ready,running
Thread scheduler disabled by interrupt occurs Swi_post(),Swi_andn();Swi_dec(),Swi_inc(),Swi_or() Task_create()
and various
task synchronization
mechanisms
(Event,
Semaphore,
Mailbox)
main() exits and no
other thread is currently
running
Stack used System stack
(1 per program)
System stack
(1 per program)
Task stack
(1 per task)
Task stack used by
default (see Note 1)
Context saved
when preempts
other thread
Entire context
minus saved-bycallee
registers (as
defined by the TI C
compiler) are
saved to system
Certain registers
saved to system
Entire context
saved to task stack
Not applicable
Context saved
when blocked
Not applicable Not applicable Saves the savedby-
callee registers
(see optimizing
compiler user’s
guide for your platform).
Not applicable
Share data with
thread via
Streams, lists,
pipes, global
variables
Streams, lists,
pipes, global
variables
Streams, lists,
pipes, gates,
mailboxes,
message queues,
global variables
Streams, lists,
pipes, global
variables
Synchronize with
thread via
Not applicable Swi trigger Semaphores,
events, mailboxes
Not applicable
Function hooks Yes: register,
create, begin, end,
delete
Yes:register,
create, ready,
begin, end, delete
Yes: register,
create, ready,
switch, exit, delete
No
Dynamic creation yes  yes  yes no
Dynamically
change priority
See Note 1 yes yes no
Implicit logging Interrupt event Post, begin, end Switch, yield,
ready, exit
none
Implicit statistics none none none none



Thread Type Hook Functions
Hwi Register, Create, Begin, End, and Delete. See Section 2.3.2.
Swi Register, Create, Ready, Begin, End, and Delete. See Section 2.4.8.
Task Register, Create, Ready, Switch, Exit, and Delete. See Section 2.5.4.


3、硬件中斷

如果硬件中斷被提交多次,中斷服務程序只會執行一次,因此要讓硬件中斷函數儘可能的短。

1)建立硬件中斷對象

Hwi_Handle hwi0;
Hwi_Params hwiParams;
Hwi_Params_init(&hwiParams);
hwiParams.arg = 5;
hwi0 = Hwi_create(id, hwiFunc, &hwiParams, &eb);

相應的靜態配置硬件中斷創建語句:

var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
var hwiParams = new Hwi.Params;
hwiParams.arg = 5;
Program.global.hwi0 = Hwi.create(id, '&hwiFunc', hwiParams);

2)硬件中斷勾子函數

註冊,創建Hwi_create(),開始,結束,刪除 Hwi_delete()

typedef struct Hwi_HookSet {
Void (*registerFxn)(Int); /* Register Hook */
Void (*createFxn)(Handle, Error.Block *); /* Create Hook */
Void (*beginFxn)(Handle); /* Begin Hook */
Void (*endFxn)(Handle); /* End Hook */
Void (*deleteFxn)(Handle); /* Delete Hook */
};

註冊函數:void registerFxn(Int id);

創建和刪除函數:void createFxn(Hwi_Handle hwi,Eror_Block *eb);void deleteFxn(Hwi_Handle hwi)

開始和結束函數:void beginFxn(Hwi_Handle hwi); void endFxn(Hwi_handle hwi)

4、軟件中斷

軟件中斷通過DSP/BIOS API 的調用而觸發,比如說Swi_post()。可以產生或提交軟件中斷的 API 有

Swi_andn(),  Swi_dec(),  Swi_inc(),  Swi_or(),  Swi_post();

可使用以下語句來創建一個軟件中斷:

Swi_Handle swi0;
Swi_Params swiParams;
Swi_Params_init(swiParams);
swi0 = Swi_create(swiFunc, &swiParams, &eb);

      注意:Swi_create()只能被任務級調用而不是硬件中斷或另一個軟件中斷。

在XDCtools 中創建一個軟件中斷對象:

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

默認創建的軟件中斷優先級爲16,默認系統堆棧大小爲 4096 bytes,也可以這樣來設置 Program.stack= yourStackSize

Swi_andn(),Swi_dec(),Swi_inc(),Swi_or()和Swi_post()都可以觸發軟件中斷執行程序。

注意:1、軟件中斷一旦開始執行就必須完成,不能被阻塞

    2、有硬件中斷時,必須由硬件分配器喚醒調用任何能夠觸發軟件中斷的代碼序列

軟件中斷可被高優先級的線程所搶佔,然而,軟件中斷不能被阻塞,比如說,你不能掛起一個正在等待某事的軟件中斷。

使用Swi_inc()來提交一個軟件中斷


已閱至nps77F6-TI DSP BIOS Real-time Operating System v6.x User’s Guide    ::Page 53 

5、執行狀態和調度

Task_Mode_RUNNING

Task_Mode_READY

Task_Mode_BLOCKED

Task_Mode_TERMINATED

Task_Mode_INACTIVE

Task_Mode_RUNNING 通過調用Task_exit()變爲Task_Mode_TERMINATED

    通過調用函數(例如Semaphore_pend()或Task_sleep())變爲Task_Mode_BLOCKED

    當其他比此任務優先級更高的任務準備執行時,變爲Task_Mode_READY

當一個任務使用比較多的內存時,就需要給任務分配堆棧。Task_checkstacks()和Task_stat()用來觀察堆棧的大小

Task_Stat statbuf; /* declare buffer */
Task_stat(Task_self(), &statbuf); /* call func to get status */
if (statbuf.used > (statbuf.stacksize * 9 / 10)) {
Log_printf(&trace, "Over 90% of task's stack is in use.\n")
}

任務鉤子函數

typedef struct Task_HookSet {
Void (*registerFxn)(Int); /* Register Hook */
Void (*createFxn)(Handle, Error.Block *); /* Create Hook */
Void (*readyFxn)(Handle); /* Ready Hook */
Void (*switchFxn)(Handle, Handle); /* Switch Hook */
Void (*exitFxn)(Handle); /* Exit Hook */
Void (*deleteFxn)(Handle); /* Delete Hook */
};

1)註冊函數

註冊函數在系統初始化時中斷使能前被調用,void registerFxn(int id)

2)創建和刪除函數

void createFxn(Task_Handle task,Error_Block *eb);

void deleteFxn(Task_Handle task)

3)開關函數

void switchFxn(Task_Handle prev,Task_Handle next);中斷已使能

4)準備函數

void readyFxn(Task_Handle task),中斷已使能

5)退出函數

void exitFxn(Task_Handle task),中斷已使能

task hooks example:

       

/* ======== TaskHookExample.c ========
* This example demonstrates basic task hook processing
* operation for dynamically created tasks. */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
Task_Handle myTsk0, myTsk1, myTsk2;
Int myHookSetId, myHookSetId2;
/* HookSet functions */
/* ======== myRegister ========
* invoked during Swi module startup before main()
* for each HookSet */
Void myRegister(Int hookSetId)
{
System_printf("myRegister: assigned HookSet Id = %d\n",
hookSetId);
myHookSetId = hookSetId;
}
Tasks
Threading Modules 2-51
/* ======== myCreate ========
* invoked during Task_create for dynamically
* created Tasks */
Void myCreate(Task_Handle task, Error_Block *eb)
{
String name;
Ptr pEnv;
name = Task_Handle_name(task);
pEnv = Task_getHookContext(task, myHookSetId);
System_printf("myCreate: task name = '%s', pEnv = 0x%x\n",
name, pEnv);
Task_setHookContext(task, myHookSetId, (Ptr)0xdead);
}
/* ======== myReady ========
* invoked when Task is made ready to run */
Void myReady(Task_Handle task)
{
String name;
Ptr pEnv;
name = Task_Handle_name(task);
pEnv = Task_getHookContext(task, myHookSetId);
System_printf("myReady: task name = '%s', pEnv = 0x%x\n",
name, pEnv);
Task_setHookContext(task, myHookSetId, (Ptr)0xc0de);
}
/* ======== mySwitch ========
* invoked whenever a Task switch occurs/is made ready to run */
Void mySwitch(Task_Handle prev, Task_Handle next)
{
String prevName;
String nextName;
Ptr pPrevEnv;
Ptr pNextEnv;
if (prev == NULL) {
System_printf("mySwitch: ignoring dummy 1st prev Task\n");
}
Tasks
2-52
else {
prevName = Task_Handle_name(prev);
pPrevEnv = Task_getHookContext(prev, myHookSetId);
System_printf("mySwitch: prev name = '%s',
pPrevEnv = 0x%x\n", prevName, pPrevEnv);
Task_setHookContext(prev, myHookSetId, (Ptr)0xcafec0de);
}
nextName = Task_Handle_name(next);
pNextEnv = Task_getHookContext(next, myHookSetId);
System_printf(" next name = '%s', pNextEnv = 0x%x\n",
nextName, pNextEnv);
Task_setHookContext(next, myHookSetId, (Ptr)0xc001c0de);
}
/* ======== myExit ========
* invoked whenever a Task calls Task_exit() or falls through
* the bottom of its task function. */
Void myExit(Task_Handle task)
{
Task_Handle curTask = task;
String name;
Ptr pEnv;
name = Task_Handle_name(curTask);
pEnv = Task_getHookContext(curTask, myHookSetId);
System_printf("myExit: curTask name = '%s', pEnv = 0x%x\n",
name, pEnv);
Task_setHookContext(curTask, myHookSetId, (Ptr)0xdeadbeef);
}
/* ======== myDelete ========
* invoked upon Task deletion */
Void myDelete(Task_Handle task)
{
String name;
Ptr pEnv;
name = Task_Handle_name(task);
pEnv = Task_getHookContext(task, myHookSetId);
System_printf("myDelete: task name = '%s', pEnv = 0x%x\n",
name, pEnv);
}
Tasks
Threading Modules 2-53
/* Define 3 identical tasks */
Void myTsk0Func(UArg arg0, UArg arg1)
{
System_printf("myTsk0 Entering\n");
System_printf("myTsk0 Calling Task_yield\n");
Task_yield();
System_printf("myTsk0 Exiting\n");
}
Void myTsk1Func(UArg arg0, UArg arg1)
{
System_printf("myTsk1 Entering\n");
System_printf("myTsk1 Calling Task_yield\n");
Task_yield();
System_printf("myTsk1 Exiting\n");
}
Void myTsk2Func(UArg arg0, UArg arg1)
{
System_printf("myTsk2 Entering\n");
System_printf("myTsk2 Calling Task_yield\n");
Task_yield();
System_printf("myTsk2 Exiting\n");
}
/* ======== main ======== */
Int main(Int argc, Char* argv[])
{
Task_Params params;
Task_Params_init(&params);
params.instance->name = "myTsk0";
myTsk0 = Task_create(myTsk0Func, &params, NULL);
params.instance->name = "myTsk1";
myTsk1 = Task_create(myTsk1Func, &params, NULL);
params.instance->name = "myTsk2";
myTsk2 = Task_create(myTsk2Func, &params, NULL);
BIOS_start();
return (0);
}
Tasks
2-54
/* ======== myIdleFunc ======== */
Void myIdleFunc()
{
System_printf("Entering idleFunc().\n");
Task_delete(&myTsk0);
Task_delete(&myTsk1);
Task_delete(&myTsk2);
System_exit(0);
}

5、分時調度P76

6、空閒循環

空閒循環是DSP/BIOS的後臺線程,當沒有HWI,SWI 或Task 運行的時候,它就會運行。其他任何線程都可以搶佔,空閒循環具有最低的優先級

7、使用硬件中斷,軟件中斷,任務線程的例子

P82

三、同步模塊

1、信號量

     信號量對象可定義爲計數和信號量,被用作任務同步和互斥。信號量的值不能超過1。配置信號量的語句:config Mode mode= Mode_COUNTING

     可以使用Semaphore_create()和Semaphore_delete()來創建和刪除一個信號量。

     Semaphore_pend()用於等待一個信號量,如果計數信號量大於0,Semaphore_pend()計數並返回,否則等待Semaphore_post()。可通過semaphore_pend()來設置超時等待。

semaphore example using three writer tasks:

/* ======== semtest.c ======== */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define NUMMSGS 3 /* number of messages */
#define NUMWRITERS 3 /* number of writer tasks created with */
/* Config Tool */
typedef struct MsgObj {
List_Elem elem; /* first field for List */
Int id; /* writer task id */
Char val; /* message value */
} MsgObj, *Msg;
Void reader();
Void writer();
/* The following objects are created statically. */
extern Semaphore_Handle sem;
extern List_Handle msgList;
extern List_Handle freeList;
/* ======== main ======== */
Int main(Int argc, Char* argv[])
{
Int i;
MsgObj *msg;
msg = (MsgObj *) Memory_alloc(NULL, NUMMSGS * sizeof(MsgObj),
0, NULL);
/* Put all messages on freeList */
for (i = 0; i < NUMMSGS; msg++, i++) {
List_put(freeList, (List_Elem *) msg);
}
BIOS_start();
System_exit(0);
return(0);
}
/* ======== reader ======== */
Void reader()
{
Msg msg;
Int i;
for (i = 0; i < NUMMSGS * NUMWRITERS; i++) {
/* Wait for semaphore to be posted by writer(). */
Semaphore_pend(sem, BIOS_WAIT_FOREVER);
/* get message */
msg = List_get(msgList);
/* print value */
System_printf("read '%c' from (%d).\n", msg->val,
msg->id);
/* free msg */
List_put(freeList, (List_Elem *) msg);
}
System_printf("reader done.\n");
}
/* ======== writer ======== */
Void writer(Int id)
{
Msg msg;
Int i;
for (i = 0; i < NUMMSGS; i++) {
/* Get msg from the free list. Since reader is higher
* priority and only blocks on sem, list is never
* empty. */
msg = List_get(freeList);
/* fill in value */
msg->id = id;
msg->val = (i & 0xf) + 'a';
System_printf("(%d) writing '%c' ...\n", id, msg->val);
/* put message */
List_put(msgList, (List_Elem *) msg);
/* post semaphore */
Semaphore_post(sem);
}
System_printf("writer (%d) done.\n", id);
}

result:

(0) writing 'a' ...
read 'a' from (0).
(0) writing 'b' ...
read 'b' from (0).
(0) writing 'c' ...
read 'c' from (0).
writer (0) done.
(1) writing 'a' ...
read 'a' from (1).
(1) writing 'b' ...
read 'b' from (1).
(1) writing 'c' ...
read 'c' from (1).
writer (1) done.
(2) writing 'a' ...
read 'a' from (2).
(2) writing 'b' ...
read 'b' from (2).
(2) writing 'c' ...
read 'c' from (2).
reader done.
writer (2) done.

2、事件模式

事件提供了一種線程間通信和同步的方法,它和信號量相似。

只有TASK可以調用Event_pend(),HWI,SWI以及其他TASK都能調用Event_post()。

UInt Event_pend(Event_Handle event,
UInt andMask,
UInt orMask,
UInt timeout);

Void Event_post(Event_Handle event,
UInt eventIds);

3、Gates

GateHwi,GateSwi,GateTask,GateMutex,GateMutexPri

4、郵箱

Mailbox_pend()被用來從一個郵箱中讀取一個緩衝,如果郵箱是空的,則Mailbox_pend()阻塞。Mailbox_post()被用來提交一個緩衝到郵箱裏。如果郵箱爲空,Mailbox_post()阻塞。

四、時間服務

與計時器有關的函數

五、內存

與內存分配有關

HeapMem,HeapBuf,HeapMultiBuf

六、硬件抽象層

1、硬件抽象接口

2、HWI 模式

3、計時器模式

4、Cache 模式

5、硬件抽象層組織包


參考資料:TMS320C55x DSP BIOS 5.x Application Programming Interface (API) Reference Guide.pdf

DSP/BIOS Modules 

ATM Module:Atomic functions written in assembly language
BUF Module : Maintains buffer pools of fixed size buffers
C55 Module : Target-specific functions
CLK Module : System clock manager
DEV Module Device driver interface
GBL Module Global setting manager
GIO Module I/O module used with IOM mini-drivers
HOOK Module Hook function manager
HST Module Host channel manager
HWI Module Hardware interrupt manager
IDL Module Idle function and processing loop manager
LCK Module Resource lock manager
LOG Module Event Log manager
MBX Module Mailboxes manager
MEM Module Memory manager
MSGQ Module Variable-length message manager
PIP Module Buffered pipe manager
POOL Module Allocator interface module
PRD Module Periodic function manager
PWRM Module Reduce application’s power consumption
QUE Module Queue manager
RTDX Module Real-time data exchange manager
SEM Module Semaphores manager
SIO Module Stream I/O manager
STS Module Statistics object manager
SWI Module Software interrupt manager
SYS Module System services manager
TRC Module Trace manager
TSK Module Multitasking manager

在學習 DSP/BIOS APIs 之前先學習一下 BIOS Tconf Language

參考文檔:Bios_Tconf_User_Guide.pdf、Bios_Tconf_Language_coding_Standards.pdf


使用 Tconf 腳本來配置 DSP/BIOS 中的應用程序。

一、簡單認識 Tconf 腳本

以下給出怎樣使用文本編輯器來建立一個 Tconf 腳本,配置了一個簡單的應用程序,一個名爲 “trace” 的LOG對象打印出“hello world”

#include <std.h>
#include <log.h>
#include "hellocfg.h"
/* ======== main ======== */
Void main()
{
LOG_printf(&trace, "Hello World!");
/* fall into DSP/BIOS idle loop */
return;
}

爲應用程序編寫 Tconf 腳本的步驟:

1、建立一個後綴名爲 .tcf 的文本文件

2、加載一個平臺 如:utils.loadPlatform("ti.platforms.dsk6416");

3、添加語句來創建對象及設置他們的屬性

bios.enableRealTimeAnalysis(prog);
bios.enableRtdx(prog);

然後創建一個 “trace” 的 LOG 對象,最後設置 LOG_system 的大小

var trace;
trace = bios.LOG.create("trace");
trace.bufLen = 1024;
trace.logType = "circular";
bios.LOG_system.bufLen = 512;

4、在文件的最後寫下這種語句:

if (config.hasReportedError == false) {
prog.gen();
}

以上步驟做完後,就完成了這個 hello 應用程序的腳本:

/* Load the DSK6416 platform. */
utils.loadPlatform("ti.platforms.dsk6416");
/* Enable needed DSP/BIOS features */
bios.enableRealTimeAnalysis(prog);
bios.enableRtdx(prog);
/* Create and initialize a LOG object */
var trace;
trace = bios.LOG.create("trace");
trace.bufLen = 1024;
trace.logType = "circular";
/* Set the buffer length of LOG_system buffer */
bios.LOG_system.bufLen = 512;
// !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
if (config.hasReportedError == false) {
prog.gen();
}

二、運行 Tconf 腳本

1、 Tconf 腳本是通過一個多功能 tconf 命令行來運行,這個可執行 tconf 文件位於 xdctools 子文件夾下

tconf -Dconfig.importPath="C:/dspbios/bios_5_20/packages" hello.tcf

2、生成的文件

<program>cfg_c.c. Source file to define DSP/BIOS structures andproperties.
❏ <program>cfg.h. Includes DSP/BIOS module header files anddeclares external variables for objects in the configuration file.
❏ <program>cfg.s##. Assembly source file for DSP/BIOS settings.Since in our example we loaded dsk6416 platform, based on 64architecture, the name of this file is hel
 ocfg.s64.
❏ <program>cfg.h##. Assembly language header file included byprogramcfg.s##. In our example, the name of this file is hellocfg.h64.
❏ <program>cfg.cmd. Linker command file.
❏ <program>.cdb. Configuration Data Base (CDB) file. Read-only file.No longer used as a source file.
      


多功能 tconf 命令行

1、設置環境變量 myScript = environment["config.scriptName"];

例如,如果你要在 D:/platforms 目錄下新建你的自定義平臺,必須設置config.importpath 的路徑:tconf -Dconfig.importPath="d:/platforms" hello.tcf

2、參數數組變量,如

numOfTasksToCreate = arguments[0];
numOfReaders = arguments[1];
numOfWriters = arguments[2];

Tconf 操作模式

 DSP/BIOS configuration tool

  command-line mode

  GUI debugger

  interactive mode

三、Tconf 語言和對象模式

1、目標內容對象模型

2、加載其他腳本的方法

load()

utils.importFile()

utils.loadPlatform()

3、使能 DSP/BIOS 組件

首選的方法是通過調用 bios 命名空間來使能和禁用 DSP/BIOS 組件。如:

bios.enableRealTimeAnalysis(prog); // enables RTA
bios.enableMemoryHeaps(prog); // enables heaps
bios.enableRtdx(prog); // enables RTDX
bios.enableTskManager(prog); // enables tasks
bios.disableRealTimeAnalysis(prog); // disables RTA
bios.disableMemoryHeaps(prog); // disables heaps
bios.disableRtdx(prog); // disables RTDX
bios.disableTskManager(prog); // disables tasks

4、對象與屬性的命名和引用

5、模塊和實例的屬性命名

6、print() 函數

for (var i in obj) {
print("obj." + i + " = " + obj[i])
}

四、Tconf 平臺文件

五、Tconf 對象參考模型

config class:board(), boards(), create(), destroy(), warn()

borad class: cpus(),create(),destroy(),getMemoryMap()

cpu class:create(),destroy(),getMemoryMap(),program(),programs()

program class:extern(),externs(),destroy(),gen(),get(),module(),modules()

memory class

extern class

module class:create(),instance(),instances()

instance class:destroy(),references()

六、DSP/BIOS 配置工具(Gconf


Tconf Language coding

模塊對象:var myModule = { }

初始化函數: myModule.init = function() { }

在模塊文件後,初始化函數應該被調用:myModule.init()

內部函數. 如果模塊定義了一個內部函數,那這個函數必須通過 “internal” 對象進行定義,如果你需要建立一個內部函數,在建立模塊對象後就立即建立內部函數對象:

var myModule.internal = {};

內部函數必須使用內部對象來定義: myModule.internal.myInternalFxn = function()  {}

例如:

/*
* myModule.tci
*/
/* define the myModule object */
var myModule = {};
/* define myModule’s variables in alphabetical order */
myModule.myInteger = 1;
myModule.myString = “hello”;
/* define myModule’s functions in alphabetical order */
myModule.foo = function()
{
}
myModule.init = function()
{
}

myModule.xyz = function()
{
/*
* These variables do not need to be declared in the
* alphabetical list above because they are local to this function.
*/
var x;
var y;
var z;
x = y = z = 2;
}
/* explicitly call the init function */
myModule.init();

添加模塊源文件,如:utils.importFile("dsk6713_common.tci");

Tconf 代碼結構

1、Platform-independent files(存儲爲 .tci 文件)

2、Platform-dependent files(一般存儲爲 .tcf 文件)

詞法約定:

標識符:

變量第一個單詞小寫後面爲大寫,如:var countNumberFrames;

關鍵字和;後一般跟一個空格。

函數定義:

模塊函數:使用以下格式

myModule.myFunction = function (argument1, argument2)
{
var i;
for (i = 0; i < 10; i++) {/* note the blank line before this */
argument1 += argument2;
}
return (argument1);
}

非模塊函數:使用以下格式

function myFunction (argument1)
{
var x;
x = argument1;
return (x);
}

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