系统时钟管理器(System Clock Manager)
概述
#include<ti/sysbios/knl/Clock.h>
函数
细节
系统时钟管理器负责SYS/BIOS中的所有定时服务。它产生周期性的系统滴答声。滴答周期是可以配置的。所有时钟实例的超时和周期以及其他SYS/BIOS模块中的超时值都是根据时钟信号来指定的。
时钟管理器支持两种滴答"模式":一种是周期模式,每个滴答声上都有一个中断(TickMode_PERIODIC),另一种是滴答声抑制模式(TickMode_DTNAMIC),它将计时器中断的数量减少到支持计划超时所需的最小值。对于支持该模式的设备(例如MSP430设备),如果在应用程序配置中未指定,则TickMode_DYNAMIC可能是默认模式;否则,默认模式将为TickMode_PERIODIC。
以下示例显示了滴答模式如何在应用程序中被指定:
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
// Tell the Clock module to use TickMode_PERIDIC
Clock.tickMode = Clock.TickMode_PERIODIC;
时钟对象包含可以计划在特定时钟周期后运行的函数。时钟对象可以是一次性的,也可以是周期性的。实例在创建时启动,或者随后使用Clock_start()函数启动。可以使用Clock_stop()函数停止实例。所有时钟实例在软件中断上下文中过期时执行。
时钟对象在创建/构造时会放置在时钟对象服务列表中,并一直保留到删除/销毁。为了最小化开销,应该删除或销毁未使用或过期的时钟对象。
默认情况下,所有时钟函数都在Swi的上下文中运行。也就是说,时钟模块自动创建一个Swi供其使用,并在该Swi内运行时钟功能。时钟使用的Swi优先级可以通过配置Clock.swiPriority来更改。
如果在应用程序中禁用了Swis(即BIOS.swiEnabled=false),则所有时钟功能都将在计时器Hwi的上下文中执行。
注意:
由于时钟函数在Swi或Hwi上下文中执行,因此不允许他们调用阻塞API。
getTicks()函数返回自启动时的时钟滴答数
默认情况下,TimerProxy定义的计时器模块用于静态创建一个计时器实例,该实例提供周期性的1ms时钟中断
如果要为时钟模块的时钟信号源使用自定义配置的计时器,参考以下配置示例:
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
// Tell the Clock module that YOU are providing the periodic interrupt
Clock.tickSource = Clock.TickSource_USER;
// this example uses the ti.sysbios.timers.dmtimer.Timer module
var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
// Change Timer 3 frequency to 24 Mhz from default if necessary
Timer.intFreqs[3] = { hi:0, lo:24000000 };
// create a dmtimer config parameter object
var timerParams = new Timer.Params();
// make sure you set the period to 1000 us (1ms)
timerParams.period = 1000;
// custom dmtimer config parameters here...
timerParams.twer.ovf_wup_ena = 1;
// Create the timer.
// This example uses timer id 3.
// Provide your own timer interrupt handler function.
Timer.create(3, '&myTimerTick', timerParams);
在’C’程序中,添加计时器中断处理程序,并让它调用Clock_tick(),它将执行所有时钟模块的tick任务:
#include <ti/sysbios/knl/Clock.h>
Void myTimerTick(UArg arg)
{
Clock_tick();
...
}
上下文调用
枚举和函数说明
enum Clock_TickMode
时钟滴答模式
typedef enum Clock_TickMode {
Clock_TickMode_PERIODIC,
// Timer will interrupt every period
Clock_TickMode_DYNAMIC
// Unnecessary timer ticks will be suppressed
} Clock_TickMode;
enum Clock_TickSource
时钟滴答源
typedef enum Clock_TickSource {
Clock_TickSource_TIMER,
// Internally configure a Timer to periodically call Clock_tick()
Clock_TickSource_USER,
// Application code calls Clock_tick()
Clock_TickSource_NULL
// The Clock module is disabled
} Clock_TickSource;
值:
- Clock_TickSource_TIMER:时钟模块自动配置定时器实例(请参阅TimerProxy)以驱动时钟滴答。具体的定时器及其周期可通过timerId和tickPeriod控制。
- TickSource_USER:应用程序负责周期性调用Clock_tick()。确保Clock.tickPeriod被设置为Clock_tick()被调用的周期。
像大多数其他的模块配置参数一样,Clock.tickPeriod配置参数值在运行时C代码中可作为"Clock_tickPeriod"访问。 - TickSource_NULL:时钟模块被关闭。在这种情况下,应用程序调用Clock_tick()是错误的。
typedef Clock_FuncPtr
实例函数原型:
typedef Void (*Clock_FuncPtr)(UArg);
config Clock_A_badThreadType
在时钟创建和时钟删除中异常
extern const Assert_Id Clock_A_badThreadType;
config Clock_A_clockDisabled
在Clock_create()中异常
extern const Assert_Id Clock_A_clockDisabled;
config Clock_LM_begin
在调用每个时钟函数之前记录
extern const Log_Event Clock_LM_begin;
config Clock_LM_tick
在每个时钟滴答中断时记录
extern const Log_Event Clock_LM_tick;
config Clock_LW_delayed
如果时钟Swi延迟>=1次,则记录
extern const Log_Event Clock_LW_delayed;
config Clock_tickMode
定时器滴答模块
extern const Clock_TickMode Clock_tickMode;
细节:
此参数指定基础计时器要使用的tick模式。
使用TickMode_PERIODIC,计时器将以tickPeriod定义的固定速率中断
使用TickMode_DYNAMIC,计时器可以通过时钟动态重新编程,以便在计划超时实际需要下一个tick时中断CPI。并不是所有的设备都支持TickMode_DYNAMIC,并且可能存在一些应用程序限制。
config Clock_tickPeriod
以微秒为单位指定的刻度周期
extern const UInt32 Clock_tickPeriod;
细节:
默认值取决于族。例如,Linux系统通常只支持10000us的最小周期和10000us的倍数。TI平台的默认值为1000us。
与大多数其他模块配置参数一样,Clock.tickPeriod配置参数值在运行时C代码中可作为“Clock_tickPeriod”访问。
config Clock_tickSource
时钟ticks源
extern const Clock_TickSource Clock_tickSource;
细节:
如果这个参数没有被设置为TickSource_TIMER,Clock_tickStart(),Clock_tickStop(),和Clock_tickReconfig(),将没有影响。
默认是TickSource_TIMER.
config Clock_timerId
用于创建定时器实例的定时器Id
extern const UInt Clock_timerId;
细节:
如果Clock.tickSource被设置为tickSource_TIMER时,时钟模块在内部创建一个静态计时器实例,该实例定期自动调用Clock_doTick()
此配置参数允许控制用于驱动时钟模块的计时器
默认值是Timer.ANY(~0)并且可能的最大timerId是系列和设备指定的
Clock_getTicks()
在时钟ticks中的时间
UInt32 Clock_getTicks();
返回值:
在时钟ticks中的时间
细节:
返回的值在达到可存储在32位中的最大值后将返回零
Clock_tick()
一次滴答的高级时钟
Void Clock_tick();
细节:
在递增全局时钟计数器后,此函数将释放处理时钟实例的Swi。
当tickSource设置为tickSource_TIMER时,计时器ISR会自动调用此函数。
当tickSource设置为TickSource_USER,Clock_tick()必须被应用程序调用。通常,这是在用户定义的硬件、软件和任务中完成的。
请注意,此函数不是可重入函数。应用程序负责确保此函数的调用被序列化:要么系统中只有一个线程调用此函数,要么所有调用都被适当的互斥量"包装"。
Clock_tickReconfig()
重新配置新CPU频率的时钟
返回值:
如果成功则返回true
细节:
此函数使用新的cpu频率重新配置用于生成时钟滴答声的计时器,以确保滴答声周期准确。此函数与Clock_tickStop()和Clock_tickStart()一起使用,以允许在运行时重新配置计时器。
某些类型的计时器可能不支持重新配置,也不支持Clock.TickModeDYNAMIC;在这些情况下,此函数调用将无效,并返回false。
在main()之外调用Clock_tickReconfig时,还必须调用Clock_tickStop和Clock_tickStart来停止和重启定时器。使用以下调用顺序:
// disable interrupts if an interrupt could lead to
// another call to Clock_tickReconfig or if interrupt
// processing relies on having a running timer
Hwi_disable() or Swi_disable();
BIOS_setCpuFreq(&freq);
Clock_tickStop();
Clock_tickReconfig();
Clock_tickStart();
Hwi_restore() or Swi_enable()
当从main()中调用Clock_tickReconfig时,计时器尚未启动,因为计时器是作为BIOS_start()的一部分启动的。因此,可以在main()中使用以下简化的调用序列:
BIOS_setCpuFrequency(Types.FreqHz *freq);
Clock_tickReconfig(Void);
如果定时器不支持新的频率,则返回值为false。
约束条件:
此函数是不可重入的,必须使用适当的锁来防止重入。
Clock_tickStart()
在重新配置后启动时钟
Void Clock_tickStart();
细节:
此函数启动用于生成时钟信号的计时器,它与clock_tickStop()和clock_tickReconfig()一起使用,以允许在运行时重新配置计时器。新的计时器配置反映了调用reconfig()一起的更改。
某些类型的计时器可能不支持重新配置和重新启动计时器,也不支持Clock.TickMode_DYNAMIC,在这些情况下,此函数调用将无效。
约束条件:
此函数是不可重入的,必须使用适当的锁来防止重入。
Clock_tickStop()
对重新配置后停止时钟
Void Clock_tickStop();
细节:
此功能用于停止用于生成时钟信号的计时器。它与Clock_tickStart和Clock_tickReconfig()一起使用,以允许在运行时重新配置计时器。
某些类型的计时器可能不支持停止定时器,并且不支持Clock.TickMode_DYNAMIC;在这些情况下,此函数将调用无效。
约束条件
此函数是不可重入的,必须使用适当的锁来防止重入。
模块设置范围
Types_ModuleId Clock_Module_id();
// Get this module's unique id
Bool Clock_Module_startupDone();
// Test if this module has completed startup
IHeap_Handle Clock_Module_heap();
// The heap from which this module allocates memory
Bool Clock_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 Clock_Module_getMask();
// Returns the diagnostics mask for this module
Void Clock_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
实例对象类型
typedef struct Clock_Object Clock_Object;
// Opaque internal representation of an instance object
typedef Clock_Object *Clock_Handle;
// Client reference to an instance object
typedef struct Clock_Struct Clock_Struct;
// Opaque client structure large enough to hold an instance object
Clock_Handle Clock_handle(Clock_Struct *structP);
// Convert this instance structure pointer into an instance handle
Clock_Struct *Clock_struct(Clock_Handle handle);
// Convert this instance handle into an instance structure pointer
实例配置参数
typedef struct Clock_Params {
// Instance config-params structure
IInstance_Params *instance;
// Common per-instance configs
UArg arg;
// Uninterpreted argument passed to instance function
UInt32 period;
// Period of this instance (in clock ticks)
Bool startFlag;
// Start immediately after instance is created
} Clock_Params;
Void Clock_Params_init(Clock_Params *params);
// Initialize this config-params structure with supplier-specified defaults before instance creation
配置 Clock_Params.arg
传递给实例函数的未解释参数
struct Clock_Params {
...
UArg arg;
细节:
默认值为null
配置 Clock_Params.period
实例的周期(时钟滴答)
struct Clock_Params {
...
UInt32 period;
细节:
此参数用于设置周期性实例的后续超时间隔(以时钟周期为单位)。
此参数的默认值为0,表示这是一个一次性的时钟对象
此参数的非零值指定将定期调用Clock对象,还指定在初始化"timeout"参数周期后调用Clock函数的速率(以时钟信号为单位)。
对于一次性时钟实例,此参数必须设置为零
配置 Clock_Params.startFlag
创建实例后立即启动
struct Clock_Params {
...
Bool startFlag;
细节:
当此标志设置为false时,用户必须调用Clock_start()来启动实例。
当设置为true时,当用户调用BIOS_start()时,静态创建的时钟对象和main()中创建的时钟对象都在main()的末尾启动。在main()之后(即在task中)创建的动态创建的时钟对象将立即启动。
此参数的默认设置为false
对于一次性和周期性的时钟对象,初始调用配置的时钟函数的时间间隔等于"超时"参数
周期时钟对象随后将按period参数指定的速率调用
运行实例创建
Clock_Handle Clock_create(Clock_FuncPtr clockFxn, UInt timeout, const Clock_Params *params, Error_Block *eb);
// Allocate and initialize a new instance object and return its handle
Void Clock_construct(Clock_Struct *structP, Clock_FuncPtr clockFxn, UInt timeout, const Clock_Params *params);
// Initialize a new instance object inside the provided structure
参数:
clockFxn:超时时运行的函数
timeout:一次性超时或初始启动延迟(以时钟滴答为单位)
params:每个实例配置参数,或NULL以选择默认值(仅限目标域)
eb:活动错误处理模块,或NULL以选择默认策略(仅限目标域)
细节:
第一个参数是超时过期时调用的函数
"timeout"参数用于指定单次和周期时钟实例的启动超时(以时钟周期为单位)。此超时在时钟实例启动时应用。对于周期性实例,配置的时钟函数将在等于超时的间隔后最初调用,随后将以period参数指定的速率调用。对于一次性实例(period参数为0),一旦时钟实例启动(使用Clock_start()或如果startFlag为true,则自动启动),配置的时钟函数将在等于超时的间隔后调用一次
创建实例时,它们被放置在时钟模块管理的链表上。因此,无法从Hwi或Swi上下文创建实例。
默认情况下,所有时钟函数都在Swi的上下文中运行。也就是说,时钟模块自动创建一个Swi供其使用,并在该Swi内运行时钟功能。时钟使用的Swi优先级可以通过配置Clock.swiPriority来更改。
如果在应用程序中禁用了Swis(即BIOS.swiEnabled=false),则所有时钟功能都将在计时器Hwi的上下文中执行。
约束条件:
由于时钟函数在Swi或Hwi上下文中执行,因此不允许它们调用阻塞APIs。
实例删除
Void Clock_delete(Clock_Handle *handleP);
// Finalize and free this previously allocated instance object, setting the referenced handle to NULL
Void Clock_destruct(Clock_Struct *structP);
// Finalize the instance object inside the provided structure
Clock_getPeriod()
获取实例的周期
UInt32 Clock_getPeriod(Clock_Handle handle);
参数:
handle:以前创建的时钟实例对象的句柄
返回值:
返回以时钟滴答为单位的周期间隔
细节:
返回实例的周期
Clock_getTimeout()
获取实例的延时
UInt32 Clock_getTimeout(Clock_Handle handle);
参数:
handle:以前创建的时钟实例对象的句柄
返回值:
返回以时钟滴答为单位的周期间隔
细节:
如果实例处于活动状态,则返回剩余时间;如果实例未处于活动状态,则返回零
Clock_isActive()
确定时钟对象当前是否处于活动状态(即正在运行)
Bool Clock_isActive(Clock_Handle handle);
参数:
handle:以前创建的时钟实例对象的句柄
返回值:
返回活动状态
细节:
如果时钟对象当前处于活动状态,则返回TRUE
Clock_setFunc()
覆盖时钟函数和参数
Void Clock_setFunc(Clock_Handle handle, Clock_FuncPtr fxn, UArg arg);
参数:
handle:以前创建的时钟实例对象的句柄
closeFxn:FuncPtr型函数
arg:clockFxn的参数
细节:
替换"创建"中最初提供的时钟对象的closeFxn函数
约束条件:
无法更改已启动的时钟对象的函数和参数
Clock_setPeriod()
设置周期间隔
Void Clock_setPeriod(Clock_Handle handle, UInt32 period);
参数:
handle:以前创建的时钟实例对象的句柄
period:时钟滴答声中的周期间隔
约束条件:
无法更改已启动的实例的周期
Clock_setTimeout()
设置初始化延时
Void Clock_setTimeout(Clock_Handle handle, UInt32 timeout);
参数:
handle:以前创建的时钟实例对象的句柄
timeout:以时钟为单位的初始超时
约束条件:
无法更改已启动的实例的初始超时
Clock_start()
启动实例
Void Clock_start(Clock_Handle handle);
参数:
handle:以前创建的时钟实例对象的句柄
细节:
使用在create()期间或通过调用Clock_setTimeout()和Clock_setPeriod()设置的超时值和时段值,并重新计算到期时间。请注意,对于周期的实例,使用指定的超时计算第一次到期。后续所有的到期时都使用此周期值
约束条件:
实例的超时不能为零
Clock_stop()
停止实例
Void Clock_stop(Clock_Handle handle);
参数:
handle:以前创建的时钟实例对象的句柄
实例内置
Int Clock_Object_count();
// The number of statically-created instance objects
Clock_Handle Clock_Object_get(Clock_Object *array, Int i);
// The handle of the i-th statically-created instance object (array == NULL)
Clock_Handle Clock_Object_first();
// The handle of the first dynamically-created instance object, or NULL
Clock_Handle Clock_Object_next(Clock_Handle handle);
// The handle of the next dynamically-created instance object, or NULL
IHeap_Handle Clock_Object_heap();
// The heap used to allocate dynamically-created instance objects
Types_Label *Clock_Handle_label(Clock_Handle handle, Types_Label *buf);
// The label associated with this instance object
String Clock_Handle_name(Clock_Handle handle);
// The name of this instance object
配置设置
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
local proxy modules
Clock.TimerProxy = ITimer.Module null
Clock.TimerProxy.delegate$ = ITimer.Module null
Clock.TimerProxy.abstractInstances$ = false
module-wide constans & types
values of type Clock.TickMode
const Clock.TickMode_PERIODIC;
const Clock.TickMode_DYNAMIC;
values of type Clock.TickSource
const Clock.TickSource_TIMER;
const Clock.TickSource_USER;
const Clock.TickSource_NULL;
module-wide config parameters
Clock.A_badThreadType = Assert.Desc {
msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
};
Clock.A_clockDisabled = Assert.Desc {
msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
};
Clock.LM_begin = Log.EventDesc {
mask: Diags.USER1 | Diags.USER2,
msg: "LM_begin: clk: 0x%x, func: 0x%x"
};
Clock.LM_tick = Log.EventDesc {
mask: Diags.USER1 | Diags.USER2,
msg: "LM_tick: tick: %d"
};
Clock.LW_delayed = Log.EventDesc {
mask: Diags.USER3,
msg: "LW_delayed: delay: %d"
};
Clock.tickMode = Clock.TickMode undefined;
Clock.tickPeriod = UInt32 undefined;
Clock.tickSource = Clock.TickSource Clock.TickSource_TIMER;
Clock.timerId = UInt ~0;
Clock.common$ = Types.Common$ undefined;
Clock.rovViewInfo = ViewInfo.Instance ViewInfo.create;
Clock.swiPriority = UInt undefined;
per-instance config parameters
var params = new Clock.Params;
params.arg = UArg null;
params.period = UInt32 0;
params.startFlag = Bool false;
per-instance creation
var inst = Clock.create(Void(*)(UArg) clockFxn, UInt timeout, params);
proxy Clock.TimerProxy
特定于目标/设备的计时器实现
配置设置
Clock.TimerProxy = ITimer.Module null
// some delegate module inheriting the ITimer interface
Clock.TimerProxy.delegate$ = ITimer.Module null
// explicit access to the currently bound delegate module
Clock.TimerProxy.abstractInstances$ = false
// use indirect runtime function calls if true
细节:
当Clock.tickSource_TIMER被配置时,时钟模块使用的计时器模块创建一个定时器实例
默认情况下,为此在内部选择特定于目标的计时器模块。如果用户希望使用不同的定时器模块,则以下配置脚本将作为实现该目标的示例:
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
// Use a dmtimer Timer instance
Clock.TimerProxy = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
enum Clock.TickMode
时钟滴答模式
配置设置
values of type Clock.TickMode
const Clock.TickMode_PERIODIC;
// Timer will interrupt every period
const Clock.TickMode_DYNAMIC;
// Unnecessary timer ticks will be suppressed
enum Clock.TickSource
时钟滴答源
配置设置
values of type Clock.TickSource
const Clock.TickSource_TIMER;
// Internally configure a Timer to periodically call Clock_tick()
const Clock.TickSource_USER;
// Application code calls Clock_tick()
const Clock.TickSource_NULL;
// The Clock module is disabled
值
TickSource_TIMER:时钟模块自动配置计时器实例以驱动时钟滴答。具体计时器及其周期可通过timerId和tickPeriod控制
TickSource_USER:应用程序负责周期性调用Clock_tick()。确保Clock.tickPeriod设置为调用Clock_tick()的周期。
与大多数其他模块配置参数一样,Clock.tickPeriod配置参数值在运行时C代码中可作为"Clock_tickPeriod"访问。
TickSource_NULL:时钟模块被禁用。在这种情况下,应用程序调用Clock_tick()时一个错误。
config Clock.A_badThreadType
在Clock_create和Clock_delete中异常
配置设置
Clock.A_badThreadType = Assert.Desc {
msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
};
config Clock.A_clockDisabled
在Clock_create()中发生异常
配置设置
Clock.A_clockDisabled = Assert.Desc {
msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
};
config Clock.LM_begin
在调用每个时钟函数之前记录
配置设置
Clock.LM_begin = Log.EventDesc {
mask: Diags.USER1 | Diags.USER2,
msg: "LM_begin: clk: 0x%x, func: 0x%x"
};
config Clock.LM_tick
记录每个时钟滴答中断
配置设置
Clock.LM_tick = Log.EventDesc {
mask: Diags.USER1 | Diags.USER2,
msg: "LM_tick: tick: %d"
};
config Clock.LW_delayed
如果时钟Swi延迟>=1次,则记录
配置设置
Clock.LW_delayed = Log.EventDesc {
mask: Diags.USER3,
msg: "LW_delayed: delay: %d"
};
config Clock.tickMode
定时器滴答模式
配置设置
Clock.tickMode = Clock.TickMode undefined;
细节:
此参数指定基础计时器要使用的滴答模式。
使用Tick_PERIODIC,计时器将以tickPeriod定义的固定速率中断CPU。
使用TickMode_DYNAMIC,计时器可以通过时钟动态重新编程,以便在计划超时实际需要下一个tick时中断CPU。并非所有设备都支持TickMode_DYNAMIC,并且肯能存在一些应用程序限制。
config Clock.tickPeriod
以微秒指定Tick周期
配置设置
Clock.tickPeriod = UInt32 undefined;
细节:
默认值取决于族。例如,Linux系统通常只支持10000us的最小周期和10000us的倍数。TI平台的默认值为1000us。
与大多数其他模块配置参数一样,Clock.tickPeriod配置参数值在运行C代码中可作为“Clock_tickPeriod”访问。
config Clock.tickSource
时钟ticks源
配置设置
Clock.tickSource = Clock.TickSource Clock.TickSource_TIMER;
细节:
如果这个参数不设置为TickSource_TIMER时,Clock_tickStart(),Clock_tickStop(),和Clock_tickReconfig(),没有影响。
默认值为TickSource_TIMER
config Clock.timerId
用于创建计时器实例的计时器Id
配置设置
Clock.timerId = UInt ~0;
细节:
如果Clock.tickSource被设置为TickSource_TIMER时,时钟模块在内部创建一个静态计时器实例,该实例定期自动调用Clock_doTick()
此配置参数允许控制用于驱动时钟模块的计时器
默认值时Timer.ANY(~0)并且可能的最大时间间隔是特定于族和设备的
metaonly config Clock.common$
公共模块配置参数
配置设置
Clock.common$ = Types.Common$ undefined;
细节:
所有模块都有此配置参数。其名称包含"$"字符,以确保它与模块声明的配置参数不冲突。这允许将来添加新的配置参数,而不会被破坏现有模块。
metaonly config Clock.rovVierInfo
配置设置
Clock.rovViewInfo = ViewInfo.Instance ViewInfo.create;
metaonly config Clock.swiPriority
时钟用于处理其实例的Swi的优先级
配置设置
Clock.swiPriority = UInt undefined;
细节:
所有时钟实例都在单个Swi的上下文中执行。此参数允许控制Swi的优先级。
此参数的默认值为Swi.numPriorities-1;最大Swi优先级
Instance Config Parameters
配置设置
var params = new Clock.Params;
// Instance config-params object
params.arg = UArg null;
// Uninterpreted argument passed to instance function
params.period = UInt32 0;
// Period of this instance (in clock ticks)
params.startFlag = Bool false;
// Start immediately after instance is created
config Clock.Params.arg
传递给实例函数的未解释参数
配置设置
var params = new Clock.Params;
...
params.arg = UArg null;
细节:
默认值为null
config Clock.Params.period
这个实例的周期(以时钟节拍为单位)
配置设置
var params = new Clock.Params;
...
params.period = UInt32 0;
细节:
此参数用于设置周期性实例的后续超时间隔(以时钟周期为单位)。
此参数的默认值为0,表示这是一个一次性时钟对象。
此参数的非零值指定将定期调用Clock对象,还指定在初始"timeout"参数周期后调用Clock函数的速率(以时钟信号为单位)。
对于一次性时钟实例,此参数必须设置为零。
config Clock.Params.startFlag
创建实例后立即启动
配置设置
var params = new Clock.Params;
...
params.startFlag = Bool false;
细节:
当此标志设置为false时,用户必须调用Clock_start()来启动实例。
当设置为true时,当用户调用BIOS_start()时,静态创建的时钟对象和main()中创建的时钟对象都在main()的末尾启动。在main()之后(即在任务中)创建的动态创建的时钟对象将立即启动。
此参数的默认设置为false
对于一次性和周期性时钟对象,初始调用配置的时钟函数的时间间隔等于"超时"参数。
周期时钟对象随后将按period参数指定的速率调用
Static Instance Creation
配置设置
var params = new Clock.Params;
// Allocate instance config-params
params.config = ...
// Assign individual configs
var inst = Clock.create(Void(*)(UArg) clockFxn, UInt timeout, params);
// Create an instance-object
参数
clockFxn:超时时运行的函数
timeout:一次性超时或初始启动延迟(以时钟滴答为单位)
params:每个实例配置参数,或NULL以选择默认值(仅限目标域)
eb:活动错误处理块,或NULL以选择默认策略(仅限目标域)
细节:
第一个参数是超时过期时调用的函数
"timeout"参数用于指定单次和周期时钟实例的启动超时(以时钟周期为单位)。此超时在时钟实例启用时应用。对于周期性实例,配置的时钟函数将在等于超时的间隔后最初调用,随后将以period参数指定的速率调用。对于一次性实例(period参数为0),一旦时钟实例启动(使用Clock_start()或如果startFlag为true,则自动启动),配置的时钟函数将在等于超时的间隔后调用一次。
创建实例时,它们被放置在时钟模块管理的链表上。因此,无法从Hwi或Swi上下文创建实例。
默认情况下,所有时钟函数都在Swi的上下文中运行。也就是说,时钟模块自动创建一个Swi供其使用,并在该Swi内运行时钟功能。时钟使用的Swi优先级可以通过配置Clock.swiPriority来更改。
如果在应用程序中禁用了SWI(即BIOS.swiEnabled=false),则所有时钟功能都将在计时器Hwi的上下文中执行。
约束条件
由于时钟函数在Swi或Hwi上下文中执行,因此不允许它们调用阻塞API。
参考文献:
- SYS/BIOS API Document《module ti.sysbios.knl.Clock》