在前文MCPS相关介绍的基础之上,对UWB协议栈中实现访问控制相关数据结构进行介绍,并介绍了其载体
struct mcps802154_local
,保存了MCPS的私有数据。
关于IEEE 802.15.4 MAC公共部分子层(MAC common part sublayer,MCPS)通道访问,Channel Access, 简写为CA。
ca.h
定义通道访问内部相关定义。
struct mcps802154_ca
定义了通道访问的私有数据。
struct mcps802154_ca {
/**
* @schedule: 当前MCPS调度计划
*/
struct mcps802154_schedule schedule;
/**
* @scheduler: 维护调度计划schedule的调度器,若未选择为NULL
*/
struct mcps802154_scheduler *scheduler;
/**
* @regions: 当前调度计划中可用的区域列表
*/
struct list_head regions;
/**
* @n_regions: 当前打开的区域数量
*/
int n_regions;
/**
* @held: 当前访问是否被持有且无法更改.
*/
bool held;
/**
* @reset: 当前调度计划是否无效且需要更改
*/
bool reset;
/**
* @idle_access: 当没有任务时用于等待的idle访问。
*/
struct mcps802154_access idle_access;
};
CA初始化与去初始化,需要包含MCPS私有数据(struct mcps802154_local *local
)。
以下CA相关操作需要FSM互斥锁加锁。包括CA的开始、停止、通知停止以及关闭,即对于执行通道访问相关操作时,都需要有限状态机(FSM)互斥锁加锁。
另外,CA的调度器的管理(调度器设置、参数设置以及调用);区域的设置、参数设置与调用也需要FSM加锁。
此外,mcps802154_ca_xmit_skb
实现将缓冲区的内容通过接受它的第一个域发送。
具体实现上,通过遍历ca.regions,若域支持skb发送,则调用发送。
int mcps802154_ca_xmit_skb(struct mcps802154_local *local, struct sk_buff *skb)
{
struct mcps802154_region *region;
int r = -EOPNOTSUPP;
list_for_each_entry (region, &local->ca.regions, ca_entry) {
if (region->ops->xmit_skb) {
if (region->ops->xmit_skb(region, skb)) {
r = 0;
break;
}
}
}
return r;
}
通过下次访问机会的时间以及当前MCPS私有数据,获得访问。
获得访问的函数原型如下:
struct mcps802154_access *
mcps802154_ca_get_access(struct mcps802154_local *local,
u32 next_timestamp_dtu);
当发生了可能影响当前访问的更改时,可以调用以下函数来评估并通知FProc。例如,当队列中新增一帧数据时,应执行此操作,FProc收到通知后,更改访问。
void mcps802154_ca_may_reschedule(struct mcps802154_local *local);
当有些访问比较重要时,不允许其他访问抢占,直到当前的访问完成,此时需要将held字段置位,通过以下函数实现:
void mcps802154_ca_access_hold(struct mcps802154_local *local);
当某些变化会影响当前的调度表时,可以通过调用以下函数来使调度表无效并强制更新。更新会在当前访问结束之后进行,由于会涉及到访问,因此fsm_lock应加锁。使用场景:当域参数发生变化时,整个调度表都将无效,因此需要调用此API,无效当前调度表,并进行更新,函数原型如下:
void mcps802154_ca_invalidate_schedule(struct mcps802154_local *local);
从CA相关的介绍以及相关原型定义上,可以看到在mcps802154的实现上,很多地方都出现了struct mcps802154_local
的引用。其构成如下:
定义了MCPS的私有数据,其中包括: