用于处理IEEE 802.15.4中的相关帧,Frame Processing,简写为:fproc。
在实现中,维护了关于帧处理的有限状态机(FSM)。本文从帧处理的数据结构和部分典型处理实现上进行简要的介绍。
关于帧处理状态机相关的事件回调定义为struct mcps802154_fproc_state
,用于处理从活跃状态的转换。
struct mcps802154_fproc_state {
/** @name: State name. */
const char *name;
/** @enter: Run when the state is entered. */
void (*enter)(struct mcps802154_local *local);
/** @leave: Run when the state is left. */
void (*leave)(struct mcps802154_local *local);
/** @rx_frame: Handle frame reception. */
void (*rx_frame)(struct mcps802154_local *local);
/** @rx_timeout: Handle reception timeout. */
void (*rx_timeout)(struct mcps802154_local *local);
/** @rx_error: Handle reception error. */
void (*rx_error)(struct mcps802154_local *local,
enum mcps802154_rx_error_type error);
/** @tx_done: Handle end of transmission. */
void (*tx_done)(struct mcps802154_local *local);
/** @broken: Handle unrecoverable error. */
void (*broken)(struct mcps802154_local *local);
/** @timer_expired: Handle timer expiration. */
void (*timer_expired)(struct mcps802154_local *local);
/** @schedule_change: Handle schedule change. */
void (*schedule_change)(struct mcps802154_local *local);
};
主要包括了entered、left、rx_frame、rx_timeout、rx_error、tx_done、broken、timer_expired、schedule_change几个状态,通过该结构体定义了相关状态切换对应的回调函数。
在MCPS的私有数据struct mcps802154_local
中,定义了帧处理的私有数据,通过结构体struct mcps802154_fproc
实现。
struct mcps802154_fproc {
/** 指向当前状态的指针 */
const struct mcps802154_fproc_state *state;
/** 指向正在处理中访问的指针 */
struct mcps802154_access *access;
/** 发送帧的buffer指针 */
struct sk_buff *tx_skb;
/** 多帧方法下的帧索引 */
size_t frame_idx;
};
由于fproc的相关处理大多会涉及到MCPS私有数据的访问,因此在文件中通过对结构体进行声明struct mcps802154_local
(未直接引用头文件的方式)。
帧处理相关操作包括:
fproc_stopped.c
中定义;fproc_broken.c
中定义;fproc_nothins.c
文件;关于MCPS802154的帧,通过分配sk_buff来存储,主要构成包括:帧头 + 载荷 + FCS(IEEE802154_FCS_LEN)。
通过struct sk_buff *mcps802154_frame_alloc(struct mcps802154_llhw *llhw, unsigned int size, gfp_t flags)
函数实现。
通过调用mcps802154_fproc_change_state
函数,主要操作:当前的状态调用leave回调函数(若有),并将MCPS私有域的状态切换为新的状态,若定义了enter函数,则调用enter回调函数。
void mcps802154_fproc_change_state( struct mcps802154_local *local, const struct mcps802154_fproc_state *new_state)
{
if (local->fproc.state->leave)
local->fproc.state->leave(local);
local->fproc.state = new_state;
if (local->fproc.state->enter)
local->fproc.state->enter(local);
}
通过函数void mcps802154_fproc_access(struct mcps802154_local *local, u32 next_timestamp_dtu)
实现帧处理的访问,通过mcps802154_ca_get_access
函数,获取access指针,进行处理。
关于帧的访问操作,根据不同的访问方式来调用不同的帧处理,主要包括rx、tx、multi以及vendor。
switch (access->method) {
case MCPS802154_ACCESS_METHOD_NOTHING:
mcps802154_fproc_nothing_handle(local);
r = 0;
break;
case MCPS802154_ACCESS_METHOD_IMMEDIATE_RX:
r = mcps802154_fproc_rx_handle(local, access);
break;
case MCPS802154_ACCESS_METHOD_IMMEDIATE_TX:
r = mcps802154_fproc_tx_handle(local, access);
break;
case MCPS802154_ACCESS_METHOD_MULTI:
r = mcps802154_fproc_multi_handle(local, access);
break;
case MCPS802154_ACCESS_METHOD_VENDOR:
r = mcps802154_fproc_vendor_handle(local, access);
break;
default:
r = -1;
}
void mcps802154_rx_frame(struct mcps802154_llhw *llhw)
{
// 基于底层硬件获取当前的MCPS802154本地私有数据指针
struct mcps802154_local *local = llhw_to_local(llhw);
// 状态机加锁
mutex_lock(&local->fsm_lock);
trace_llhw_event_rx_frame(local);
// 调用当前状态的rx_frame回调函数
if (local->fproc.state->rx_frame)
local->fproc.state->rx_frame(local);
else
mcps802154_broken_safe(local);
trace_llhw_event_done(local);
mutex_unlock(&local->fsm_lock);
}
EXPORT_SYMBOL(mcps802154_rx_frame);
对于rx_timeout、rx_error、tx_done等均为类似的处理方式,最后都通过EXPORT_SYMBOL宏,就符号导出供其他模块使用。
可以看到在帧处理获得访问之后,将调用mcps802154_fpoc_rx_handle
来处理对应状态下的操作,对于接收的帧处理状态定义如下:
static const struct mcps802154_fproc_state mcps802154_fproc_rx = {
.name = "rx",
.rx_frame = mcps802154_fproc_rx_rx_frame,
.rx_error = mcps802154_fproc_rx_rx_error,
.schedule_change = mcps802154_fproc_rx_schedule_change,
};
int mcps802154_fproc_rx_handle(struct mcps802154_local *local,
struct mcps802154_access *access)
{
int r;
struct mcps802154_rx_info rx_info = {
.flags = MCPS802154_RX_INFO_AACK,
.timeout_dtu = -1,
};
r = llhw_rx_enable(local, &rx_info, 0);
if (r)
return r;
mcps802154_fproc_change_state(local, &mcps802154_fproc_rx);
return 0;
}
状态定义中,仅定义了rx_frame、rx_error以及schedule_change,分别处理帧接收、帧接收错误处理以及调度切换。
接收帧处理中,底层硬件使能接收,然后将帧处理状态切换到mcps802154_fproc_rx
。