打印
[应用相关]

VSF构架之动态多任务

[复制链接]
1323|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Simon21ic|  楼主 | 2014-10-16 22:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Simon21ic 于 2014-10-20 21:56 编辑

动态多任务实质上,是实现task类,然后实现task实例,代码中,动态分配task的资源,设置相应task的参数,并且由系统调度。大部分情况下,只有在操作系统的环境下,才能怎么使用的。

在VSF构架中,定义了完整的EDA状态机类(同样的类,可以实现为EDA构架、EDA状态机、EDA层次状态机),并且,支持子状态机。VSF构架中的PT线程,也是挂载在EDA状态机类上的线程类。所以,EDA状态机类可以动态生成,并且,PT线程类也可以动态生成。这样就很容易实现动态多线程。

一般方法为,定义好PT类的子类,并且实现相应的应用功能。在PT线程中,EDA状态机类只是一个外壳,所以简单生成一个基本的EDA状态机类就行,只需要实现init状态机,并且设置evt_handler为vsfpt_evt_handler,之后这个状态机就作为PT状态机运行了,EDA状态机实例的初始化中,会发送INIT事件,vsfpt_evt_handler会启动pt线程的thread线程,线程处理完毕后,把自己删除并且释放相应的资源(注意,释放完资源后,就不能再访问相应的线程的资源了)。

一般的应用环境,在请求-相应模型中,系统收到请求事件后,动态分配相应的资源,建立一个相应请求的PT线程,然后,作为子状态机挂载到当前EDA上去。

代码举例,使用USBCDC实现的串口命令行界面:
设备收到一个OUT数据包事件的时候,会对每个字符生成一个按键事件发送给命令行界面的事件处理器,命令行界面的事件处理器当收到回车事件后,便动态分配命令处理线程的资源,然后挂载为自己的子线程,之后任务调度器就会发送INIT等事件,执行相应的线程。简单示例代码如下:
https://github.com/versaloon/vsf/tree/master/vsf/example/vsfusbd_eda

就不多介绍代码了,能看懂的来举个手。

只是简单说一下功能:
实现的是一个IAD的USB组合设备,一个HID和一个CDC,CDC上实现了一个命令行,可以支持后台运行的命令,可以支持多个命令同时运行(前台命令只能有一个)。

下面是delayms命令的处理代码,能看出来是不是阻塞的代码?
static vsf_err_t
vsfshell_delayms_handler(struct vsfsm_pt_t *pt, vsfsm_evt_t evt)
{
    struct vsfshell_handler_param_t *param =
                        (struct vsfshell_handler_param_t *)pt->user_data;
    struct vsfshell_t *shell = param->shell;
   
    vsfsm_pt_begin(pt);
    if (param->argc != 2)
    {
        vsfshell_print_string(shell, "invalid format." VSFSHELL_LINEEND);
        vsfshell_print_string(shell, "format: delayms MS" VSFSHELL_LINEEND);
        goto handler_thread_end;
    }
   
    param->priv = MALLOC(sizeof(struct vsftimer_timer_t));
    if (NULL == param->priv)
    {
        vsfshell_print_string(shell, "not enough resources." VSFSHELL_LINEEND);
        goto handler_thread_end;
    }
    memset(param->priv, 0, sizeof(struct vsftimer_timer_t));
    ((struct vsftimer_timer_t *)param->priv)->sm = pt->sm;
    ((struct vsftimer_timer_t *)param->priv)->evt = VSFSM_EVT_USER_LOCAL_INSTANT;
    ((struct vsftimer_timer_t *)param->priv)->interval = strtoul(param->argv[1], NULL, 0);
    vsftimer_register((struct vsftimer_timer_t *)param->priv);
    vsfsm_pt_wfe(pt, VSFSM_EVT_USER_LOCAL_INSTANT);
    vsftimer_unregister((struct vsftimer_timer_t *)param->priv);
   
    vsfsm_pt_end(pt);
   
handler_thread_end:
    if (param->priv != NULL)
    {
        FREE(param->priv);
    }
    vsfshell_handler_exit(pt);
    return VSFERR_NONE;
}
沙发
mmuuss586| | 2014-10-17 08:43 | 只看该作者

楼主半夜出来讲课;

使用特权

评论回复
板凳
Simon21ic|  楼主 | 2014-10-17 12:06 | 只看该作者
mmuuss586 发表于 2014-10-17 08:43
楼主半夜出来讲课;

不是讲课,绝大部分开发人员不需要这样的开发方式,学了也没什么用。
只是准备找人写这个代码,所以在培训前简单写个说明。

使用特权

评论回复
地板
Simon21ic|  楼主 | 2014-10-20 21:51 | 只看该作者
更新了一下代码,能看懂的举个手吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:www.versaloon.com --- under construction

266

主题

2597

帖子

104

粉丝