ARM Cordio WSF(四)——应用示例

时间:2024-04-12 20:12:30

在介绍了WSF的基础情况,API接口以及具体平台的移植之后,本文具体介绍WSF的应用该如何来写,包括框架的初始化、定时器的应用,外部事件的应用等等。作为一个简易的OS抽象层,在裸机平台上实现简单的任务的调度与分发也是非常方便。

4、WSF应用示例

4.1 WSF框架初始化

//1. 定义 WSF Buffer Pools

#define WSF_BUF_POOLS 5

// Default pool descriptor.
static wsfBufPoolDesc_t poolDescriptors[WSF_BUF_POOLS] = {
    {32, 8}, {64, 4}, {128, 4}, {256, 4}, {1024, 2},
};

//2. 需要使用NVM,则需要移植相关硬件平台实现,pal_flash.h/c
WsfNVMInit();

// 平台初始化,以适应WSF,pal_sys.h/c
PalSysInit();

// 设置定时器用于WSF调度器
WsfOsInit();
WsfTimerInit();
// sys_tick用于更新WsfTimerUpdateTicks
sys_tick_callback_set(WsfTimerUpdateTicks);
// 初始化缓冲池
uint32_t wsfBufMemLen = WsfBufInit(WSF_BUF_POOLS, poolDescriptors);
// 必要需要检查是否有足够的动态内存
// 预留heap内存
//WsfHeadAlloc(wsfBufMemLen);

//
// Create app task
//
wsfHandlerId_t handlerId = WsfOsSetNextHandler(app_handler);
app_init(handlerId);
// 主函数中,调用wsfOsDispatcher
while (1)
{
    wsfOsDispatcher();  //涉及Critical Section
    // 若需要进行低功耗处理
}

4.2 应用定义

第一步,创建Task,需要指定任务定义的handler;

void app_handler(wsfEventMask_t event, const void *param)
{
    const wsfMsgHdr_t *msg = (const wsfMsgHdr_t *)param;

    if (msg != NULL)
    {
        switch (msg->event)
        {
        		case APP_TIMER_MSG:
        			//TODO: 定时器处理函数
        		break;
            //App Task Message, 用户自定义
            default:
                break;
        }
    }
    // Handle events,若无消息,判断是否为事件
    else
    {
        if (event & APP_BTN_EVT)
        {
            //TODO: BTN EVT
        }
    }
}

WsfOsSetNextHandler的执行将会返回一个handler ID,wsfHandlerId_t ,因此,这里通过代码进行封装。
为了任务管理比较方便,我们根据需要,可以创建一个控制块(Control Block)结构体来进行管理,将需要的消息队列、handle_id、定时器等进行封装起来。

/* Main control block of the app task */
struct APP_CB_T
{
    wsfQueue_t msg_queue;
    wsfHandlerId_t handle_id;
    wsfTimer_t app_timer;
};
int app_init(uint8_t handle_id)
{
    /* store handler ID */
    app_cb.handle_id = handle_id;

    /* init rx queue */
    WSF_QUEUE_INIT(&app_cb.msg_queue);

    app_cb.app_timer.handlerId = handle_id;
    app_cb.app_timer.msg.event = APP_TIMER_MSG;
    return 0;
}

可以根据需要,来设置app定时器,可以单次触发,也可以周期性的触发定时器,不断触发任务执行。

WsfTimerStartMs(&app_cb.app_timer, 2000);  //2s 触发定时器

对于事件应用而言,例如实现一个按键时间,则可以在按键中断来触发事件,当事件触发之后,应用相关处理触发。

WsfSetEvent(app_cb.handle_id, APP_BTN_EVT);

通过外部事件、定时器中断等实现了APP Task任务的触发,实现调用,整体使用也比较方便。


持续更新,系列文章,收藏关注吧!

1、ARM Cordio WSF(一)——架构介绍
2、ARM Cordio WSF(二)——API接口介绍
3、ARM Cordio WSF(三)——nRF52840平台移植