范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

用AWTK和AWPLC快速开发嵌入式应用程序(4)自定义功能块(上)

  AWPLC 目前还处于开发阶段的早期,写这个系列文章的目的,除了用来验证目前所做的工作外,还希望得到大家的指点和反馈。如果您有任何疑问和建议,请在评论区留言。 1. 背景
  AWTK  全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎
  AWPLC  是 ZLG 自主研发的 PLC 系统(兼容 IEC61131-3),其中 AWPLC 的运行时库 (Runtime) 基于 ZLG TKC 开发,可以移植到到任何主流 RTOS 和 嵌入式系统。AWPLC 的集成开发环境 (IDE) 基于 AWTK 开发,可以运行在 Windows、MacOS 和 Linux 系统之上。AWPLC 的主要目标之一是把 PLC 中  低代码开发方法  引入到嵌入式软件,从而提高嵌入式软件的开发效率和可靠性。 2. 简介
  在前一篇文章中,我们说过,AWPLC 的重要特色之一就是高度可扩展,而且会内置 ZLG 多年在嵌入式系统开发中积累的功能块,包括各种算法、协议和实用功能,这将大大简化嵌入式软件的开发。
  那怎么去开发自定义的功能块呢?本文以 ZTIMER 为例介绍一下开发自定义功能块的方法。ZTIMER 是一个带计数功能的定时器,在前一篇文章中,我们用它实现了一个走马灯的演示,其使用方法如下:
  编辑切换为居中
  添加图片注释,不超过 140 字(可选)
  在 AWPLC 中,自定义功能块和内置功能块具有同等待遇,因为它们都是按同样的方式加入进来的。在进入正题前,我们先聊一下,系统的可扩展性以及实现方法。 2.1 可扩展性的好处
  在设计一个复杂软件的架构时,可扩展性是必须考虑的因素。可扩展性至少带来以下几个好处: 可扩展性将软件的框架与具体的实现分离开来,有助于降低系统的复杂度。系统的复杂性太高,会带来一系列的问题,比如让可理解性、可维护性和可靠性的降低,很多项目因此陷入无法挣脱的焦油坑里,最后士气低落,人员流失,项目取消,公司蒙受巨大损失。在设计复杂软件时,一定要存有敬畏之心。 可扩展性将软件变化的部分隔离开来,不但可以让扩展的功能独立变化,也可以方便的扩展新功能。在 AWPLC 中, 以后会扩展各种协议和算法的功能块,必须保证 AWPLC 框架和这些扩展的功能块是独立的,才能让开发工作顺利进行。 可扩展性有利于团队的协作。 不同的通讯协议和算法,需要不同团队的专家去开发,可扩展性让大家只要按相应的接口去实现,就可以方便的集成起来,不需要太多跨团队的交互。 2.2 如何保证可扩展性
  让软件系统具有可扩展性,通常并不是什么难事,只要做到下面两点就可以了: 针对接口编程。这个是大家都知道的,在《软件设计模式》等书里,都反复强调了,这里不再赘述。 利用工厂模式隔离组件的创建。工厂模式也是人人都知道的,而且大家都觉得很"简单"。但是能把工厂模式用好的程序员其实并不多见,一个主要原因就是很多人只会套用《软件设计模式》的工厂模式,而《软件设计模式》里几个工厂模式在现实中并不实用。利用这些这些工厂模式,无法满足 SOLID 原则中的开放封闭原则,增加一个新的扩展时,仍然需要修改对应的工厂。 3. AWPLC 功能块的接口
  要让 AWPLC 支持扩展各种自定义的功能块,首要条件条件是定义好功能块的接口。 3.1 功能块的基类
  在面向对象的 C 语言编程中,我们用结构 (struct) 来模拟类和接口。这里所说的接口是广义的接口,而不是 C++或其它语言中只包含纯虚函数的 interface,因为除了虚函数指针外,这里还有一些数据成员。 /**  * @class aw_plc_fb_t  * AWPLC 功能块接口。  */ struct _aw_plc_fb_t {   /**     * @property {bool_t} en    * 是否启用。    */   uint8_t en : 1;   /**     * @property {bool_t} eno    * 是否启用输出。    */   uint8_t eno : 1;    /*private*/   const aw_plc_fb_vtable_t* vt;  };  3.2 功能块的虚函数
  在功能块的虚函数表中,还定义了一些描述性的常量,让对象具有一点反射的能力,方便在运行时查询它的一些状态。顺便说一下,在定义接口的虚函数时,通常不会有创建函数,因为创建之前对象之前,是拿不到这个虚表对象的。但也不是绝对的,有时为了方便 clone,也可能提供一个 clone 函数或者 create 函数。
  任何接口都要定义析构函数 (destroy),在对象需要销毁时,框架可以以统一的方式销毁它。 typedef struct _aw_plc_fb_vtable_t {   /*功能块的类型名*/   const char* type;   /*输入参数名称列表,以 NULL 结束的字符串数组*/   const char* const* ins;   /*输出参数名称列表,以 NULL 结束的字符串数组*/   const char* const* outs;   /*输入输出参数名称列表,以 NULL 结束的字符串数组*/   const char* const* in_outs;   /*执行函数*/   aw_plc_fb_exec_t exec;   /*执行函数(带参数)*/   aw_plc_fb_exec_ex_t exec_ex;   /*获取属性(输入输出参数)的值*/   aw_plc_fb_get_prop_t get_prop;   /*获取输出的值*/   aw_plc_fb_get_output_t get_output;   /*设置输出的值*/   aw_plc_fb_set_input_t set_input;   /*析构函数*/   aw_plc_fb_destroy_t destroy; } aw_plc_fb_vtable_t;
  这个虚函数表和 AWTK/TKC 中的 object 虚函数表很相似,考虑到 object 为了做得通用,有点臃肿了,所以决定重新定义一套。4. AWPLC 功能块的工厂
  前面我们说过,可扩展性除了针对接口编程外,离不开工厂模式的支持。功能块的工厂其任务当然是创建功能块了,所以提供了一个创建功能块的函数。参数 type 指定功能块的类型,函数返回对应类型的功能块: /**  * @method aw_plc_fb_factory_create_fb  * 创建 fb。  * @param {const char*} type 类型。  *  * @return {aw_plc_fb_t*} 返回 fb 对象。  */ aw_plc_fb_t* aw_plc_fb_factory_create_fb(const char* type);
  有了这个创建函数,确实把创建任务与功能块的实现分开了。但是请想一下,如果每次增加新的功能块,都要修改这个创建函数,而这个函数又属于框架的一部分,框架是不是还是依赖于具体实现了呢?为了解决这个问题,我们需要提供一种注册机制来实现依赖倒置,让功能块的实现者主动将创建函数注册进来: /**  * @method aw_plc_fb_factory_register  * 注册创建函数。  * @param {const char*} type 类型。  * @param {aw_plc_fb_create_t} create 创建函数。  *  * @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。  */ ret_t aw_plc_fb_factory_register(const char* type, aw_plc_fb_create_t create);
  这种机制非常好用,真正满足了 SOLID 原则中的开放封闭原则 (OCP):扩展新的功能无需修改框架代码。在 ZLG 开源 GUI 引擎中,也大量使用了这种带注册功能的工厂模式,有兴趣的朋友可以去看看 AWTK 的代码。 5. ZTIMER5.1 ZTIMER 的结构
  在 C 语言中,一般用结构来模拟类,把基类作为结构的第一个成员来模拟继承。这里必须让 aw_plc_fb_t 作为 aw_plc_fb_ztimer_t 的第一个成员。 /**  * @class aw_plc_fb_ztimer_t  * @parent aw_plc_fb_t  * @annotation ["fb"]  * 循环定时器。  *   * > 当输入 IN 为 TRUE 时,开始计时,输出 Q 为 FALSE,ET 开始记录过去的时间。  * > 定时时间到时,COUNT 增加 1, 输出 Q 在本次循环为 TRUE,ET 重置为 0。  * > 输入 IN 为 FALSE 时重置定时器。  */ typedef struct _aw_plc_fb_ztimer_t {   aw_plc_fb_t fb;     /**     * @property {bool_t} in    * @annotation ["in"]    * 为 TRUE 开始计时,为 FALSE 时重置定时器。    */   bool_t in : 1;    /**     * @property {iec_time_t} pt    * @annotation ["in"]    * 预设时间 (ms)。    */   iec_time_t pt;  ... } aw_plc_fb_ztimer_t;
  这里的 API 注释采用了 AWTK 中定义的格式,但是对 annotation 做了一点扩展,增加了 3 个新的取值: fb 表示这是一个功能块。 in 表示这是一个输入参数。 out 表示这是一个输出参数。 5.2 ZTIMER 的实现
  每个功能块必须提供虚函数表中定义的函数,不过主要代码集中 exec 函数里(其它函数可以自动生成出来): static ret_t aw_plc_fb_ztimer_exec(aw_plc_fb_t* fb) {   aw_plc_fb_ztimer_t* ztimer = AW_PLC_FB_ZTIMER(fb);    if (aw_plc_fb_before_exec(fb) == RET_OK) {     ztimer->current_time = aw_plc_now_ms();     if (ztimer->state == 0 && !ztimer->prev_in && ztimer->in) {       ztimer->state = 1;       ztimer->q = FALSE;        ztimer->et = 0;       ztimer->count = 0;       ztimer->start_time = ztimer->current_time;     } else {       if (!ztimer->in) {         ztimer->q = FALSE;         ztimer->state = 0;          ztimer->et = 0;         ztimer->count = 0;         ztimer->start_time = ztimer->current_time;       } else if (ztimer->state == 1) {         if ((ztimer->start_time + ztimer->pt) <= ztimer->current_time) {           ztimer->q = TRUE;            ztimer->et = 0;           ztimer->count++;           ztimer->start_time = ztimer->current_time;         } else {           ztimer->q = FALSE;           ztimer->et = ztimer->current_time - ztimer->start_time;         }          }        }        ztimer->prev_in = ztimer->in;   }    return RET_OK; }  5.3 注册 ZTIMER
  功能块需要注册到前面介绍的功能块工厂: aw_plc_fb_factory_register(AW_PLC_FB_TYPE_ZTIMER, aw_plc_fb_ztimer_create);
  坦白的讲,本文只是介绍了实现自定义功能块的关键步骤,实际工作要麻烦很多。如果手工去做这些工作,开发一个功能块还觉得好玩,而开发几十个甚至几百个功能块,人不会变疯就会变傻。下一篇文章会我们介绍一下,如何用代码生成器来完成这些单调的工作,让开发自定义功能块成为一项快乐的工作。

一旦患上糖尿病,是否要放弃主食?提醒没准可能带来更大的隐患对于糖尿病这种病,或许咱们再熟悉不过。作为临床上常见的慢性疾病,一旦患上糖尿病,患者身体上会有多种不适的症状,比如头晕乏力莫名口渴皮肤感染等等。如果没有控制好血糖值,病情不再发展下李兰娟院士早晨或是养肝黄金期,4种早餐,或会让肝脏变好肝脏是人体当中最大的器官,同时,也是人体中最大的消化器官以及解毒器官,一旦肝脏健康受损,身体当中的毒素无法排出,人体健康就会受到相应的影响。随着时代的不断发展,有越来越多的人养成了南财快评以高质量发展和共同富裕应对人口负增长根据国家统计局最新消息,2022年末我国人口比上年末减少85万人。这个消息让很多人惊讶,也有不少人对此没什么感觉。惊讶是因为我们很多人已经习惯了中国人口的正增长,而这次是新中国成立CBA三消息辽宁引援再被拒绝,周俊成逐渐消失,于德豪功过抵消大家好呀,我是北柠,各位小伙伴们要养成先看后赞的习惯哦!辽宁队现在还是有很多引援计划想要完成的,球迷们应该也都非常清楚,现在辽宁队主要把工作重心放到了青训上面,现在辽宁队中的年轻球数十年的实验让科学家们考虑一种可能性宇宙的存在没有意义?宇宙是自然的还是我们生活在多元宇宙中的非典型泡沫?大型强子对撞机最近的结果迫使许多物理学家面对后者的可能性。2012年7月,希格斯玻色子的发现证实了一个已有近50年历史的理论,即基国家发改委29省份今年经济增长预期目标定为5左右甚至更高央视网消息1月18日,在国家发展改革委1月新闻发布会上,国家发改委政策研究室主任金贤东表示,展望今年,随着各地疫情高峰过去,生活中的烟火气正在迅速回归,生产秩序正在逐步恢复,近期交教育部发布信息技术产品国家通用语言文字使用管理规定记者16日从教育部获悉,教育部日前发布信息技术产品国家通用语言文字使用管理规定,要求信息技术产品使用国家通用语言文字,应当符合国家颁布的语言文字规范标准。规定指出,数字和网络出版物国家发改委进一步加力支持新型基础设施建设中新网1月18日电18日,国家发展改革委召开1月例行新闻发布会,国家发改委政策研究室主任金贤东表示,2023年,国家发展改革委将会同有关方面,进一步加力支持新型基础设施建设,引导支国家发改委谈扩内需增加城乡居民收入,全面促进消费提质升级1月18日,在国家发展改革委1月新闻发布会上,有媒体提问扩内需的作用在中央经济工作会议中得到了进一步突显,近期出台的扩大内需战略规划纲要(20222035年)十四五扩大内需战略实施新春走基层预订年夜饭,预制菜成春节餐桌新宠中国商报(记者贺阳)农历新年将至,春节的氛围愈发浓郁,不少家庭开始提前准备大年三十的年夜饭。虽然餐饮堂食已回归正常,但是问了几家饭店的年夜饭预订情况,有的已早早订满,有的价格太贵了给狂飙11位演员演技排个名吴刚第九,倪大红第五,张译第三狂飙更新到了第9集。徐江和白江波经过泰叔调停之后,表面上握手言和,背地里徐江直接掳走白江波,将对方干掉了。本着祸不及家人的江湖道义,他放过了白江波的老婆和孩子,但这成为了一个隐患。
国足归化终迎喜讯,5大锋霸将携手空降,助扬科维奇冲亚洲冠军北京时间9月4日,中超联赛官方公布了第12轮的最佳球员,其中武汉三镇外援马尔康,凭借登场65分钟完成的大四喜成功当选。目前马尔康还排在中超射手榜第一的位置,以16个进球数遥遥领先第汽车市场将全面进击电动时代,预计2030年实现全面电动化导言随着双碳政策的不断实施以及2030年碳达峰目标的提出,各行各业都在进行整治,尤其是作为大件消费的汽车市场。众所周知,汽车的车尾气排放是导致二氧化碳排放超标的重要原因之一,因其排这是山西秋天独有的七种情调,每一处都美得让人心动每个人心中都有一个向往的地方,可能是一张秋日的图片,也可能是因为某个故事,秋日的山西就是一个让人心生向往的地方,如果你错过了这里的夏天,那么你应该来看看它的秋天,这里藏着别样的秋日打着华为旗号的AITO问界含为量到底有多高?AITO问界M5问界M7已经推出就被官方冠以华为赋能,在自媒体的宣传中甚至更是直言这是华为汽车,在刚刚过去的八月,AITO凭借华为赋能的这个噱头达成了10045辆的交付量,力压小鹏QQ推出QQ学生卡9月5日,QQ上线QQ学生卡交互功能,用户可一键查看账号的Q龄与等级学院,并生成学生卡进行分享。不少网友纷纷晒出自己的学生卡,重温情怀,引发关注。高一时被同学送的第一个,当时觉得很华为Mate50将先于iPhone14实现卫星通信率先接入北斗卫星上周,余承东在一段采访中提到,华为Mate50这次将搭载全新的通信技术,要向上捅破天。当时业内就纷纷猜测,华为Mate50将支持卫星通信功能。今天,这个传闻终于得到官方验证,华为终周二这三个板块或将迎来大幅上涨一天然气板块。周一天然气板块无疑是市场最靓的一个,板块大涨4。01,有17只个股涨停或涨幅超过10,爆发了涨停潮。十四五规划提出,要加快建设天然气主干管道,完善油气互联互通网络,这十三生笑祝贺北京冬奥会开闭幕式等IP荣获2021十大年度国家IP嘉奖十三生笑祝贺北京冬奥会开闭幕式等IP荣获2021十大年度国家IP嘉奖2021十大年度国家IP评选2022年9月3日,2021十大年度国家IP颁奖典礼在陕西延安红街盛大举行,在中华民北京怀柔的一个唯美小山村,不仅板栗飘香,还有肥美烤鱼常在北京郊区游玩的人,没有人会怀疑怀柔区的山水之色在北京的存在地位,怀柔的美突出一个秀字。一个美轮美奂的雁栖湖镇就足以让人惊诧掉下巴,还有渤海镇的慕田峪长城响水湖,四海镇的四季花海2022年北京市全民健身与营养社区行走进通州区潞城镇大营村为贯彻运河体育精神,深入挖掘和丰富大运河文化内涵,推动了体育健身项目和旅游消费发展深度融合,行走大运河运河体育系列活动,北京市社区运动会2022年北京市全民健身与营养社区行走进通州1993年北京申奥失败,有人质疑国外有人捣鬼?邓小平12个字回复1993年9月23日,夜色已深,不过在摩纳哥的格蒙特卡洛路易体育馆内,却坐满了人。他们精神抖擞,紧张地等待着台上奥委会主席萨马兰奇的宣布。众人屏息之下,萨马兰奇终于念出了一个城市名