logo资料库

第11章-单任务多任务(uCGUI中文手册).pdf

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
第11章 运行模型:单任务/多任务
11.1 支持的运行模型
单任务系统(超级循环)
µC/GUI 多任务系统:一个任务调用 µC/GUI
µC/GUI 多任务系统:多个任务调用 µC/GUI
11.2 单任务系统(超级循环)
描述
超级循环范例(没有使用 µC/GUI)
优点
缺点
使用 µC/GUI
11.3 µC/GUI 多任务系统:一个任务调用 µC/GUI
描述
优点
缺点
使用 µC/GUI
11.4 µC/GUI 多任务系统:多个任务调用 µC/GUI
描述
优点
缺点
使用 µC/GUI
建议
范例
11.5 多任务支持的 GUI 配置宏
GUI_MAXTASK
GUI_OS
11.6 内核接口函数 API
GUI_X_InitOS()
GUI_X_GetTaskID()
GUI_X_Lock()
GUI_X_Unlock()
第11章 运行模型:单任务/多任务 µC/GUI 从一开始就被设计成够适应不同的环境类型。它能工作在单任务和多任务应用当 中,包括私有的操作系统或任何商业 RTOS,例如 embOS 或 µC/OS。 µC/GUI 中文手册 第 1 页
第 11 章 运行模型:单任务/多任务 11.1 支持的运行模型 我们主要区别一下三种不同的执行模型: 单任务系统(超级循环) 所有的程序运行在一个超级循环中。通常情况下,所有软件单元被有秩序地调用。既然 没用用到实时内核,软件的实时功能必须要依靠中断来完成。 µC/GUI 多任务系统:一个任务调用 µC/GUI 使用了一个实时内核(RTOS),但是其中只有一个任务调用 µC/GUI 函数。 从图形软件 的观点来看,它和单任务系统中的使用是一样的。 µC/GUI 多任务系统:多个任务调用 µC/GUI 使用了一个实时内核(RTOS),其中多个任务调用 µC/GUI 函数。 这样的工作避免了软 件造成的线程保护问题,该项工作通过在配置中使能多任务支持及配合内核接口函数来完成。 对于普遍的的内核,内核接口函数易于使用。 11.2 单任务系统(超级循环) 描述 所有的程序运行在一个超级循环中。通常情况下,所有软件单元被有秩序地调用。没有 使用实时内核,因此软件的实时功能必须要依靠中断来完成。这类系统起初用于更小的系统 或如果实时行为并不是很必须的情况下。 超级循环范例(没有使用 µC/GUI) void main(void) { HARDWARE_Init(); /* 初始化软件单元 */ XXX_Init( ) ; YYY_Init( ) ; /* 超级循环: 有秩序地调用所有软件单元 */ 第 2 页 µC/GUI 中文手册
第 11 章 运行模型:单任务/多任务 while(1) { /* 执行所有的软件单元 */ XXX_Exec(); YYY_Exec(); } } 优点 没有使用实时内核(占用更小的 ROM 空间,只有一个任务,用于堆栈的 RAM 单元也很少), 不存在 优先权/同步 问题。 缺点 超级循环程序如果超过一定的大小,可能变得很难维护。实时行为极有限,因为一个软 件单元不能被其它的单元所打断(只有通过中断)。这意思是一个软件单元的反应时间依赖于 这个系统中所有其它单元的执行时间。 使用 µC/GUI 关于µC/GUI 的使用,没有真的约束。如通常情况一样,GUI_Init()在你使用这个软件前 必须要先调用,在这基础上,可以使用任何 API 函数。如果用到视察管理器的回调机制,一 个µC/GUI 更新函数必须定期被调用。在从超级循环中调用 GUI_Exec()是一种典型做法。单元 化函数例如 GUI_Delay()和 GUI_ExecDialog(),不应在循环中使用,因为它们会妨碍其它软 件模块。 使用默认配置,它并不支持多任务系统使用(#define GUI_MT 0);不需要内核接口函 数。 超级循环范例(使用 µC/GUI): void main(void) { HARDWARE_Init(); /* 初始化软件单元 */ XXX _Init(); YYY_Init(); µC/GUI 中文手册 第 3 页
第 11 章 运行模型:单任务/多任务 GUI_Init(); /* 初始化 µC/GUI * / /* 超级循环:有秩序地调用所有的软件单元*/ while(1) { /* 运行所有的软件单元 */ XXX_Exec(); YYY_Exec(); GUI_Exec(); /* 功能性运行 µC/GUI 如更新窗口*/ } } 11.3 µC/GUI 多任务系统:一个任务调用 µC/GUI 描述 使用一个实时内核(RTOS)。用户程序被分割成不同的部分,运行在不同的任务中,具有 典型不同的优先级别。通常情况下,实时的临界任务(要求某一个反应时间)具有最高级别。 一个单个任务调用µC/GUI 函数,用于用户界面。这个任务通常在系统中的任务级别最低,至 少是最低的级别之一(一些统计任务或简单的空闲处理的任务级别甚至可能更低)。中断可以 用于软件的实时部分,但不是必须的。 优点 系统实时行为极佳。任务的实时行为只受运行在更高级别任务影响。这意思是换一个运 行在低级别任务的程序单元的一点也不会影响实时行为。如果用户界面在一个低级别任务中 运行,这意味者换到用户界面不会影响实时行为。这种系统使分配不同的软件单元到不同的 开发组变得很容易,这能给于彼此工作非常高的独立性。 缺点 你需要一个实时内核(RTOS),这需要花费金钱,耗尽 ROM 和 RAM (用于堆栈)。另外, 你要考虑到任务同步和如何从一个任务传输信息到另一个任务。 使用 µC/GUI 如 果 用 到 视 察 管 理 器 的 回 调 机 制 , 一 个µ C/GUI 更 新 函 数 ( 典 型 是 GUI_Exec() , GUI_Delay())必须定期地从调用µC/GUI 的任务中调用。 因为 µC/GUI 只被一个任务调用, 第 4 页 µC/GUI 中文手册
第 11 章 运行模型:单任务/多任务 对于µC/GUI 来说,这和单任务系统中使用是一样的。 使用默认配置,它并不支持多任务系统的使用(#define GUI_MT 0);不需要内核接口 函数。你可以使用任何实时内核,包括商业的或私有的。 11.4 µC/GUI 多任务系统:多个任务调用 µC/GUI 描述 使用一个实时内核。用户程序被分割成不同的部分,运行在不同的任务中,具有典型不 同的优先级别。通常情况下,实时的临界任务(要求某一个反应时间)具有最高级别。多个 任务用于用户界面,调用µC/GUI 函数。这些任务在系统中具有典型的低级别,因此它们不会 影响系统的实时行为。 中断可以用于软件的实时部分,但不是必须的。 优点 系统实时行为极佳。任务的实时行为只受运行在更高级别任务影响。这意思是换一个运 行在低级别任务的程序单元的一点也不会影响实时行为。如果用户界面在一个低级别任务中 运行,这意味者换到用户界面不会影响实时行为。这种系统使分配不同的软件单元到不同的 开发组变得很容易,这能给于彼此工作非常高的独立性。 缺点 你需要一个实时内核(RTOS),这需要花费金钱,耗尽 ROM 和 RAM (用于堆栈)。另外, 你要考虑到任务同步和如何从一个任务传输信息到另一个任务。 使用 µC/GUI 如 果 用 到 视 察 管 理 器 的 回 调 机 制 , 一 个µ C/GUI 更 新 函 数 ( 典 型 是 GUI_Exec() , GUI_Delay())必须定期地从一个或多个调用µC/GUI 的任务中调用。 默认配置并不支持多任务系统的使用(#define GUI_MT 0),在此不能使用。在配置中, 需要启用多任务支持,定义调用µC/GUI 的任务的最大数量(引用自 GUIConf.h): #define GUI_MT 1 #define GUI_MAX_TASK 5 // 启用多任务支持 // 能调用µC/GUI 的任务的最大数量 µC/GUI 中文手册 第 5 页
第 11 章 运行模型:单任务/多任务 需要用到内核接口函数,需要与使用的内核相匹配。你可以使用任何实时内核,包括商 业的或私有的。在下面的章节,会对宏和函数二者进行论述。 建议 (1)仅仅从一个任务调用µC/GUI 更新函数(即 GUI_Exec(),GUI_Delay())。这对保持 程序结构清晰有帮助。如果你的系统有足够的 RAM,专门使用一个任务(最低级别)更新 µC/GUI。该任务将不断地调用 GUI_Exec(),不做其它事情,就象下面例子显示的一样。 (2)保持你的实时任务(决定你的系统行为,关于 I/O,接口,网络等等)与调用µC/GUI 的任务分开。这对保证获得最佳的实时性能有很大帮助。 (3)如果可能的话,你的用户界面只使用一个任务。这利于保持程序结构简洁,易于调 试(但是,这不是必需的,在一些系统也可能是不合适的。) 范例 该引用显示专门的 dedicated µC/GUI 更新函数。它从范例 MT_Multitasking 中拿来, 这个范例包括在随µC/GUI 发布的范例当中: /*************************************************************************** * GUI 背景处理 * ***************************************************************************/ /* 该任务进行背景处理。主要工作是更新有效窗口,其它的事情,例如测试鼠标或 * 触摸屏输入也可以处理 */ void GUI_Task(void) { } while(1) { } GUI_Exec(); /* 做背景工作……更新窗口等等 */ GUI_X_ExecIdle(); /* 剩下暂时不做什么事情……空闲处理 */ 第 6 页 µC/GUI 中文手册
第 11 章 运行模型:单任务/多任务 11.5 多任务支持的 GUI 配置宏 下表显示了用于一个多个任务调用µC/GUI 多任务系统的配置宏: 类型 宏 默认值 说明 N B GUI_MAXTASK GUI_OS 4 0 当多任务支持启用时(如下),定义调用 µC/GUI 最大任务数量。 激活多任务支持的启用。 GUI_MAXTASK 描述 定义调用µC/GUI 访问显示屏的最大任务的数量。 类型 数值 附加信息 该功能只有在 GUI_OS 激活情况下才相应有效。 GUI_OS 描述 通过激活 GUITask 组件启用多任务支持。 类型 二进制开关 0: 停止,多任务支持禁止(默认值) 1: 激活,多任务支持启用 11.6 内核接口函数 API 一个 RTOS 通常提供一个机制,称为资源旗语。在它的里面,使用一个特定资源的一个 µC/GUI 中文手册 第 7 页
第 11 章 运行模型:单任务/多任务 任务在实际使用这个资源之前要声明这个资源。显示屏是一个需要和资源旗语一起被保护的 资源的例子。µC/GUI 使用宏 GUI_USE 在访问显示屏之前或使用一个临界内部数据之前调用 函数 GUI_Use()。 类似的方法,它在访问显示屏之后或使用一个临界内部数据之后调用函数 GUI_Unuse()。这在模块 GUITask.c 中实现。 GUITask.c 依次使用下表所示的 GUI 内核接口函数。这些函数的前缀为 GUI_X_,因为它 们是高层函数(与硬件相关)。它们必须与所使用的实时内核相匹配,以构造µC/GUI 任务(或 线程)保护。详细的函数描述在后面,还有范例说明如何与不同的内核匹配。 函数 说明 GUI_X_InitOS() 初始化内核接口模块(建立一个资源“旗语/互斥”)。 GUI_X_GetTaskId() 返回一个当前任务(线程)的唯一的 32 位标识符。 GUI_X_Lock() 锁定 GUI(阻塞资源“旗语/互斥”)。 GUI_X_Unlock() 解锁 GUI(解锁资源“旗语/互斥”)。 GUI_X_InitOS() 描述 建立资源旗语或互斥(体),最典型是由 GUI_X_Lock()和 GUI_X_Unlock()使用。 函数原型 void GUI_X_InitOS(void) GUI_X_GetTaskID() 描述 返回当前任务的唯一 ID。 函数原型 U32 GUI_X_GetTaskID(void); 返回值 当前任务的 ID 是一个 32 位整数。 附加信息 第 8 页 µC/GUI 中文手册
分享到:
收藏