本发明涉及控制领域,尤其涉及控制领域中一种控制方法和装置。
背景技术:
龙芯ls2k1000双核处理器是由龙芯中科技术有限公司自主研发的国产化cpu,具备较高的硬件完全性。和利时公司基于该处理器研发了高安全的微内核操作系统内核(简称微内核),该微内核运行在cpu的内核空间。和利时公司基于该微内核还开发了plc控制器软件,该plc控制器软件运行在cpu的用户空间。
该微内核只提供线程管理、进程间通信(ipc)、虚拟内存空间、句柄空间、设备基础单元(中断对象)五项功能,这些功能十分有限且非常原始,使得直接使用这些功能开发plc控制器软件不仅工作难度大,而且工作量大。
技术实现要素:
本发明要解决的技术问题是提供一种控制方法和装置,简化了plc控制器软件的开发难度和开发工作量。
为了解决上述技术问题,本发明实施例提供了一种控制方法,包括:
接收被调用的接口函数发送的进程间通信ipc消息;其中,所述ipc消息包括消息类型;
根据所述消息类型调用与所述消息类型对应的处理函数,被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数。
一种示例性的实施例中,上述方法还具有下面特点:
所述消息类型为任务创建;所述被调用的接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务栈大小、任务入口地址;
所述消息类型对应的处理函数为用于创建任务的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
一种示例性的实施例中,上述方法还具有下面特点:
所述消息类型为激活任务;所述被调用的接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级;
所述消息类型对应的处理函数为用于激活任务的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
一种示例性的实施例中,上述方法还具有下面特点:
所述消息类型为任务睡眠;所述被调用的接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址;
所述消息类型对应的处理函数为用于任务睡眠的处理函数,所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋值给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
一种示例性的实施例中,上述方法还具有下面特点:
所述生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数后还包括:
所述用于任务睡眠的接口函数用于接收所述ipc应答消息,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
其中,所述时钟中断线程定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息。
一种示例性的实施例中,上述方法还具有下面特点:
所述消息类型为页面映射或dma映射;所述被调用的接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度;
所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的接口函数。
为了解决上述问题,本发明还提供了一种控制装置,包括:存储器和处理器;所述存储器,用于保存接口函数、处理函数以及用于进行控制的程序;
所述处理器,用于当所述接口函数被调用时执行以下操作:发送进程间通信ipc消息,在所述ipc消息中携带消息类型;
所述处理器还用于读取所述用于进行控制的程序,执行如下操作:
接收被调用的接口函数发送的ipc消息;
根据所述ipc消息中携带的消息类型调用与所述消息类型对应的处理函数;
所述处理器还用于当所述处理函数被调用时执行以下操作:执行相应处理,并构建ipc应答消息返回给被调用的接口函数。
一种示例性的实施例中,上述装置还具有下面特点:
所述消息类型为任务创建,所述接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务优先级、任务栈大小、任务入口地址;
所述消息类型对应的处理函数为用于创建任务的处理函数;
所述执行相应处理,并构建ipc应答消息返回给被调用的接口函数,包括:
所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
一种示例性的实施例中,上述装置还具有下面特点:
所述消息类型为激活任务;所述接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级;
所述消息类型对应的处理函数为用于激活任务的处理函数;所述处理函数执行相应处理,并构建ipc应答消息返回给被调用的接口函数包括:
所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
一种示例性的实施例中,上述装置还具有下面特点:
所述消息类型为任务睡眠;所述接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址;
所述消息类型对应的处理函数为用于任务睡眠的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
一种示例性的实施例中,上述装置还具有下面特点:所述处理器当所述用于任务睡眠的接口函数被调用时还执行以下操作:
在接收到所述ipc应答消息后,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息;
所述存储器还用于保存进行时钟中断的程序;
所述处理器还用于读取执行所述用于时钟中断的程序,执行以下操作:
定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数还用于接收发送给所述线程通知句柄的消息,并向接口函数的调用方返回表明睡眠结束的消息。
一种示例性的实施例中,上述装置还具有下面特点:
所述消息类型为页面映射或dma映射;所述接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度;
所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的处理函数。
综上,本发明实施例提供的控制方法和装置,基于龙芯处理器和微内核操作系统,通过一组接口函数定义和该组接口函数底层实现,简化了plc控制器软件的开发难度和开发工作量。
附图说明
图1为plc控制器结构框图。
图2为根据本发明实施例一的控制方法的示意图。
图3为本发明实施例二的控制方法的流程图。
图4根据本发明实施例二的管理线程流程图。
图5为根据本发明实施例二的任务创建流程图。
图6为根据本发明实施例二的睡眠流程图。
图7为根据本发明实施例二的内存映射流程图。
图8为根据本发明实施例三的控制装置的示意图。
具体实施方式
为使本发明的目的、技术方案和优点更加清楚明白,下文中将结合附图对本发明的实施例进行详细说明。需要说明的是,在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互任意组合。
实施例一
图2为本发明实施例一的控制方法的示意图,如图2所示,本实施例的控制方法包括:
s11、接收被调用的接口函数发送的进程间通信ipc消息。
其中,所述ipc消息包括消息类型。
一种示例性的实施例中,所述被调用的接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务栈大小、任务入口地址。
一种示例性的实施例中,所述被调用的接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级。
一种示例性的实施例中,所述被调用的接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址。
一种示例性的实施例中,所述被调用的接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度。
s12、根据所述消息类型调用与所述消息类型对应的处理函数。
一种示例性的实施例中,所述消息类型为任务创建;所述消息类型对应的处理函数为用于创建任务的处理函数。
一种示例性的实施例中,所述消息类型为激活任务;所述消息类型对应的处理函数为用于激活任务的处理函数。
一种示例性的实施例中,所述消息类型为任务睡眠;所述消息类型对应的处理函数为用于任务睡眠的处理函数。
一种示例性的实施例中,所述消息类型为页面映射或dma映射;所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数。
s13、被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数。
一种示例性的实施例中,所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
一种示例性的实施例中,所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
一种示例性的实施例中,所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋值给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
所述生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数后还包括:
所述用于任务睡眠的接口函数用于接收所述ipc应答消息,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
其中,所述时钟中断线程定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息。
一种示例性的实施例中,所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的接口函数。
实施例二
图3为本发明实施例三的控制方法的流程图。如图3所示,包括步骤如下:
步骤301:调用方调用接口函数,生成ipc消息,将该ipc消息发给管理线程,并被阻塞直到接收到ipc应答消息。
一种示例性的实施例中,基于龙芯处理器和微内核操作系统的plc控制器的软件接口,包括一组接口函数定义和该组接口函数底层实现两部分。该组接口函数定义对应图1(plc控制器结构框图)中的部件22软件接口,该组接口函数底层实现对应图1中的部件18管理线程和部件16时钟中断线程。
本发明所指的接口函数定义,位于图1中的部件22软件接口。软件接口给上层用户提供易于理解的参数,并封装成ipc消息发送给管理线程,从而简化上层用户的复杂度。该软件接口实质上是函数库,它不是独立的任务,它隶属于任何调用它的任务。
本发明所指的接口函数底层实现位于图1中的部件18管理线程和部件16时钟中断线程。管理线程和时钟中断线程是两个独立的线程,由初始线程创建。
本发明所指的接口函数定义具体指:
(1)intos_api_task_create(char*name,intpriority,intoptions,intstacksize,void*entrypt,void*arg1,void*arg2,void*arg3,void*arg4,void*
arg5,void*arg6,void*arg7,void*arg8,void*arg9,void*arg10);
(2)intos_api_task_activate(intitaskid);
(3)intos_api_task_sleep(intimsperiod);
(4)unsignedintos_api_page_map(unsignedintbase_addr,unsignedintlen,unsignedintcacheable,unsignedintwriteable);
(5)unsignedintos_api_dma_map(unsignedintlen,unsignedintcacheable,unsignedintwriteable,unsignedint*dma_paddr)。
还可以包括以下接口:
(6)os_api_task_resume、os_lib_task_resume
(7)os_api_task_del、os_lib_task_del
(8)os_api_task_suspend、os_lib_task_suspend
(9)os_api_task_priority_set、os_lib_task_priority_set
(10)os_api_task_get_id、os_lib_task_get_id
(11)os_api_task_name_to_id、os_lib_task_name_to_id
(12)os_api_task_delay、os_lib_task_delay
本发明所指的接口函数实现具体指管理线程和时钟中断线程的逻辑流程,以及os_lib_task_create、os_lib_task_activate、os_lib_task_sleep、os_lib_page_map、os_lib_dma_map的逻辑流程。
步骤302:管理线程接收并解析ipc消息,根据解析出的不同的消息类型调用不同的处理函数,被调用的处理函数执行相应处理后,构建ipc应答消息并发送给接口函数。
其中,消息类型可以为os_api_taskcreate(=1)、os_api_taskactivate(=8)、os_api_tasksleep(=11)、os_api_page_map(=21)、os_api_dma_map(=22)。
一种示例性的实施例中,管理线程流程图如图4所示,该线程主要逻辑为:
(1)阻塞并等待ipc消息,直到接收到ipc消息;
(2)解析ipc消息;
(3)根据解析出的不同的消息类型调用不同的处理函数,包括:
当os_api_taskcreate(=1)时调用os_lib_task_create;
当os_api_taskactivate(=8)时调用os_lib_task_activate;
当os_api_tasksleep(=11)时调用os_lib_task_sleep;
当os_api_page_map(=21)时调用os_lib_page_map;
当os_api_dma_map(=22)时调用os_lib_dma_map;
也可调用其它处理函数。
(4)返回第(1)步。
一种示例性的实施例中,os_api_task_create和os_lib_task_create协作完成os_api_task_create和os_lib_task_create协作完成任务创建,协作过程如图5任务创建流程图所示。
当调用方调用os_api_task_create时将生成一个ipc消息。该ipc消息类型为os_api_taskcreate(=1),该ipc消息内容依次为:priority(任务优先级)、stacksize(任务栈大小)、entrypt(任务入口)、options(任务选项)、arg1(参数1)、arg2、arg3、arg4、arg5、arg6、arg7、arg8、arg9、arg10、name(任务名)。之后os_api_task_create调用callwithmrs发送该ipc消息给管理线程,并被阻塞直到收到应答。
管理线程收到ipc消息后解析ipc消息并调用对应的处理函数。os_api_taskcreate(=1)对应的处理函数是os_lib_task_create,该函数的具体步骤为:
(1)从ipc消息中解析所有入参
本步骤中入参即ipc消息的内容。
(2)申请一个任务描述符
需要说明的是,管理线程在初始化时静态创建了256个任务描述符,并全部初始化为0。每个任务描述符包括线程关键信息、线程通知句柄、线程入口地址、线程睡眠时间、线程名字。线程关键信息包括线程tcb句柄、线程上下文句柄、线程栈大小、线程栈指针、线程ipc内存指针等。申请一个任务描述符就是遍历全部任务描述符,如果一个任务描述符的线程句柄等于0,则认为该描述符空闲可用,就返回该任务描述符。
(3)创建并填写任务配置结构体
本步骤创建一个结构体,将入参保存到结构体中,方便函数调用时传参。
(4)申请tcb内存(拆分出1kb的内核对象,至少需要与内核1次交互)
本步骤向内核申请tcb(任务控制块),详细过程与os_lib_page_map中描述的过程类似。申请tcb内存后得到一个句柄,将该句柄赋值给任务描述符的线程关键信息的线程tcb句柄。
(5)申请ipc内存(每次申请4kb,至少需要与内核1次交互)
本步骤向内核申请ipc内存,详细过程与os_lib_page_map中描述的过程类似。
(6)设置tcb基本参数(需要与内核1次交互)
本步骤通过系统调用函数tcbconfiguration设置内核中该任务的ipc内存地址。
(7)设置tcb调度参数(需要与内核1次交互)
本步骤通过系统调用函数tcbsetpriority设置内核中该任务的优先级。
(8)申请栈内存(每次申请4kb,需要与内核多次交互)
本步骤向内核申请栈大小为stacksize的栈内存,详细过程与os_lib_page_map中描述的过程类似。
(9)创建信号量并给线程入口地址赋值
本步骤为该任务创建信号量并记录任务人口地址。信号量用于配合实现任务睡眠功能。任务睡眠实际是任务在等待该信号量,时钟中段线程通过该信号量唤醒该任务。新创建的信号量赋值给任务描述符的线程通知句柄,供后续线程睡眠使用。然后将参数entrypt(任务入口)赋值给任务描述符的线程入口地址,供后续线程激活使用。
(10)构建ipc应答并发送给os_api_task_create
本步骤将线程tcb句柄当做任务id,生成一个包含该任务id的ipc消息,并调用reply发送给os_api_task_create。
os_api_task_create收到管理线程的ipc应答后,取出任务id,并返回调用方。
os_api_task_activate和os_lib_task_activate协作完成任务激活。
当调用方调用os_api_task_activate时将生成一个ipc消息。该ipc消息类型为os_api_taskactivate(=8),该ipc消息内容为:itaskid(任务id),该任务id即创建任务时返回的线程tcb句柄。之后os_api_task_activate调用callwithmrs发送该ipc消息给管理线程,并被阻塞直到收到应答。
os_api_taskactivate(=8)对应的处理函数是os_lib_task_activate。
该函数的流程为:
(1)从ipc消息中解析出任务id
(2)根据任务id查找到任务的描述符
(3)根据任务的描述符和ipc消息得到该任务的入口地址、栈地址、ipc内存地址、任务优先级、任务入口、任务栈大小。
(4)设置该任务的上述关键信息(需要与内核1次交互)
本步骤通过系统调用函数tcbwriteregister将任务的入口地址、栈地址、ipc内存地址、任务参数填写到该任务的上下文寄存器中。
如果写入成功,则表示激活成功;否则,激活失败。
(5)构建ipc应答并发送给os_api_task_activate
本步骤生成表示是否激活成功的ipc消息,并调用reply发送给软件接口。
os_api_task_create收到管理线程的ipc应答后,返回调用方。
os_api_task_sleep、os_lib_task_sleep、时钟中断线程协作完成任务睡眠,协作过程如图6睡眠流程图所示。
当调用方调用os_api_task_sleep时将生成一个ipc消息。该ipc消息类型为os_api_tasksleep(=11),该ipc消息内容为:imsperiod(睡眠时间)和ipcbufaddr(ipc内存地址)。之后os_api_task_sleep调用callwithmrs发送该ipc消息给管理线程,并被阻塞直到收到应答。
os_api_tasksleep(=11)对应的处理函数是os_lib_task_sleep。该函数的流程为:
(1)从ipc消息中解析出imsperiod(睡眠时间)和ipcbufaddr(ipc内存地址)
(2)根据任务的ipcbufaddr查找到任务描述符
本步骤遍历256个任务描述符,如果某个任务描述符的ipc内存地址与该ipcbufaddr相同,则返回该描述符。
(3)设置该任务描述符的睡眠时间,即把ipc消息中的睡眠时间赋给任务描述符的线程睡眠时间。
(4)构建ipc应答并发送给os_api_task_sleep
本步骤从任务描述符中得到线程通知句柄,生成一个包含该线程通知句柄的ipc消息,并调用reply发送给软件接口。线程通知句柄中包含信号量。
os_api_task_sleep收到管理线程的ipc应答后,解析出线程通知句柄,开始等待时钟中断线程(图1之部件16)发送给信号量的消息,并被阻塞。
时钟中断线程(图1之部件16)定周期检查睡眠任务队列,对睡眠到期的任务给该任务对应的信号量(即对应的线程通知句柄)发送消息,以触发该任务重新执行(即触发该任务进入就绪态,如果该任务优先级最高,该任务会立即执行)。
os_api_task_sleep收到时钟中断线程的信号量,表明设定的睡眠时间结束,于是直接返回调用方。
os_api_page_map、os_lib_page_map协作完成内存申请,协作过程如图7内存映射流程图所示。
当调用方调用os_api_page_map时将生成一个ipc消息。该ipc消息标志为os_api_page_map(=21),该ipc消息内容依次为:base_addr(物理地址)、len(内存长度)、cacheable(是否cache)、writeable(是否可写)。之后os_api_page_map调用callwithmrs发送该ipc消息给管理线程,并被阻塞直到收到应答。
os_api_page_map(=21)对应的处理函数是os_lib_page_map。该函数的流程为:
(1)从ipc消息中解析出base_addr(物理地址)、len(内存长度)、cacheable(是否cache)、writeable(是否可写)这些参数,根据len计算出4kb页面的个数n。
内存长度len是字节数,4kb是内存页面的大小,n是计算出来的内存页数,分配内存时只能整页的分配内存,不足整页时自动向上取整到整页。
(2)申请一片连续的虚拟地址空间,可以容纳n个4kb页面。
本步骤检查xxx到xxx 4k*n这块连续的虚拟地址是否没有使用,如果没有使用,xxx就是返回的虚拟地址,虚拟地址空间就是n个连续的4kb页面的虚拟地址。
(3)申请物理内存。每次通过微内核申请一个物理页,重复n次。这n个页的物理地址可以不连续。
(4)建立虚拟地址和物理页的映射关系。每次通过微内核映射一页,映射n次。
需要说明的是,1个4kb页面的虚拟地址与1个物理页对应,程序使用的全部是虚拟地址,内存管理单元mmu根据上面的对应关系找到对应的物理地址,然后通过该物理地址直接访问ddr内存对应的页面(物理页)。
(5)构建ipc应答并发送给os_api_page_map
本步骤生成包含虚拟地址的ipc消息,并调用reply发送给软件接口。
os_api_dma_map、os_lib_dma_map协作完成dma内存申请,其协作过程与图7内存映射流程图类似。
步骤303:接口函数接收该ipc应答消息,并返回调用方。
需要说明的是,本发明所实现的软件接口,不能用于初始线程(图1之部件15)、时钟中断线程(图1之部件16)、调试线程(图1之部件17)、管理线程(图1之部件18),可以用于除此之外的其它线程。
实施例三
图8为本发明实施例的控制装置的示意图,如图8所示,本实施例的控制装置包括:存储器和处理器;
所述存储器,用于保存接口函数、处理函数以及用于进行控制的程序;
所述处理器,用于当所述接口函数被调用时执行以下操作:发送进程间通信ipc消息,在所述ipc消息中携带消息类型;
所述处理器还用于读取所述用于进行控制的程序,执行如下操作:
接收被调用的接口函数发送的ipc消息;
根据所述ipc消息中携带的消息类型调用与所述消息类型对应的处理函数;
所述处理器还用于当所述处理函数被调用时执行以下操作:执行相应处理,并构建ipc应答消息返回给被调用的接口函数。
一种示例性的实施例中,所述消息类型为任务创建,所述接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务优先级、任务栈大小、任务入口地址;
所述消息类型对应的处理函数为用于创建任务的处理函数;
所述执行相应处理,并构建ipc应答消息返回给被调用的接口函数,包括:
所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
一种示例性的实施例中,所述消息类型为激活任务;所述接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级;
所述消息类型对应的处理函数为用于激活任务的处理函数;所述处理函数执行相应处理,并构建ipc应答消息返回给被调用的接口函数包括:
所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
一种示例性的实施例中,所述消息类型为任务睡眠;所述接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址;
所述消息类型对应的处理函数为用于任务睡眠的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
一种示例性的实施例中,所述处理器当所述用于任务睡眠的接口函数被调用时还执行以下操作:
在接收到所述ipc应答消息后,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息;
所述存储器还用于保存进行时钟中断的程序;
所述处理器还用于读取执行所述用于时钟中断的程序,执行以下操作:
定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数还用于接收发送给所述线程通知句柄的消息,并向接口函数的调用方返回表明睡眠结束的消息。
一种示例性的实施例中,所述消息类型为页面映射或dma映射;所述接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度;
所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的处理函数。
本领域普通技术人员可以理解上述方法中的全部或部分步骤可通过程序来指令相关硬件完成,所述程序可以存储于计算机可读存储介质中,如只读存储器、磁盘或光盘等。可选地,上述实施例的全部或部分步骤也可以使用一个或多个集成电路来实现。相应地,上述实施例中的各模块/单元可以采用硬件的形式实现,也可以采用软件功能模块的形式实现。本发明不限制于任何特定形式的硬件和软件的结合。
以上仅为本发明的优选实施例,当然,本发明还可有其他多种实施例,在不背离本发明精神及其实质的情况下,熟悉本领域的技术人员当可根据本发明作出各种相应的改变和变形,但这些相应的改变和变形都应属于本发明所附的权利要求的保护范围。
1.一种控制方法,其特征在于,包括:
接收被调用的接口函数发送的进程间通信ipc消息;其中,所述ipc消息包括消息类型;
根据所述消息类型调用与所述消息类型对应的处理函数,被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数。
2.如权利要求1所述的方法,其特征在于,包括:
所述消息类型为任务创建;所述被调用的接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务栈大小、任务入口地址;
所述消息类型对应的处理函数为用于创建任务的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
3.如权利要求1所述的方法,其特征在于,包括:
所述消息类型为激活任务;所述被调用的接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级;
所述消息类型对应的处理函数为用于激活任务的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
4.如权利要求1所述的方法,其特征在于,包括:
所述消息类型为任务睡眠;所述被调用的接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址;
所述消息类型对应的处理函数为用于任务睡眠的处理函数,所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋值给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
5.如权利要求4所述的方法,其特征在于,所述生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数后还包括:
所述用于任务睡眠的接口函数用于接收所述ipc应答消息,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
其中,所述时钟中断线程定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息。
6.如权利要求1所述的方法,其特征在于,包括:
所述消息类型为页面映射或dma映射;所述被调用的接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度;
所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数;所述被调用的处理函数执行相应处理后,构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的接口函数。
7.一种控制装置,包括:存储器和处理器;其特征在于:
所述存储器,用于保存接口函数、处理函数以及用于进行控制的程序;
所述处理器,用于当所述接口函数被调用时执行以下操作:发送进程间通信ipc消息,在所述ipc消息中携带消息类型;
所述处理器还用于读取所述用于进行控制的程序,执行如下操作:
接收被调用的接口函数发送的ipc消息;
根据所述ipc消息中携带的消息类型调用与所述消息类型对应的处理函数;
所述处理器还用于当所述处理函数被调用时执行以下操作:执行相应处理,并构建ipc应答消息返回给被调用的接口函数。
8.如权利要求7所述的装置,其特征在于:
所述消息类型为任务创建,所述接口函数为用于创建任务的接口函数;所述ipc消息还包括任务的任务优先级、任务栈大小、任务入口地址;
所述消息类型对应的处理函数为用于创建任务的处理函数;
所述执行相应处理,并构建ipc应答消息返回给被调用的接口函数,包括:
所述用于创建任务的处理函数申请一个空闲的任务描述符;其中,所述任务描述符包括线程关键信息、线程通知句柄、线程入口地址;所述线程关键信息包括线程任务控制块tcb句柄、线程栈指针和ipc内存指针;
向内核申请任务控制块tcb内存,将返回的句柄赋给线程tcb句柄;
向内核申请ipc内存,将返回的内核中该任务的ipc内存地址赋给ipc内存指针;
根据所述任务栈大小向内核申请栈内存,将返回的栈地址赋给线程栈指针;
记录所述任务入口地址,将所述任务入口地址赋值给线程入口地址;
生成的包含所述线程tcb句柄的ipc应答消息,返回给所述用于创建任务的接口函数。
9.如权利要求7所述的装置,其特征在于,包括:
所述消息类型为激活任务;所述接口函数为用于激活任务的接口函数;所述ipc消息还包括线程tcb句柄、任务栈大小和任务优先级;
所述消息类型对应的处理函数为用于激活任务的处理函数;所述处理函数执行相应处理,并构建ipc应答消息返回给被调用的接口函数包括:
所述用于激活任务的处理函数根据从所述ipc消息中解析出线程tcb句柄获取该线程tcb句柄对应的任务描述符;
将任务描述符中的线程入口地址、栈地址、ipc内存地址以及所述ipc消息中的任务优先级、任务栈大小写入相应的寄存器;
若写入成功,则生成包含任务激活成功的ipc应答消息,返回给所述用于激活任务的接口函数;
若写入失败,则生成包含任务激活失败的ipc应答消息,返回给所述用于激活任务的接口函数。
10.如权利要求7所述的装置,其特征在于,包括:
所述消息类型为任务睡眠;所述接口函数为用于任务睡眠的接口函数;所述ipc消息还包括睡眠时间和ipc内存地址;
所述消息类型对应的处理函数为用于任务睡眠的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于任务睡眠的处理函数根据从所述ipc消息中解析出的ipc内存地址查找相应的任务描述符;所述任务描述符包括线程睡眠时间、线程通知句柄;
将所述睡眠时间赋给线程睡眠时间;
获取任务描述符的线程通知句柄;
生成包括所述线程通知句柄的ipc应答消息,返回给所述用于任务睡眠的接口函数。
11.如权利要求7所述的装置,其特征在于,所述处理器当所述用于任务睡眠的接口函数被调用时还执行以下操作:
在接收到所述ipc应答消息后,获取所述线程通知句柄,等待时钟中断线程发送给所述线程通知句柄的消息,并被阻塞直到收到时钟中断线程发送给所述线程通知句柄的消息;
当接收到发送给所述线程通知句柄的消息后,向接口函数的调用方返回表明睡眠结束的消息;
所述存储器还用于保存进行时钟中断的程序;
所述处理器还用于读取执行所述用于时钟中断的程序,执行以下操作:
定期遍历所有的任务描述符;对于任一任务描述符,若线程睡眠时间到期,则向用于任务睡眠的接口函数发送与该到期的线程睡眠时间对应的任务描述符对应的线程通知句柄;
所述用于任务睡眠的接口函数还用于接收发送给所述线程通知句柄的消息,并向接口函数的调用方返回表明睡眠结束的消息。
12.如权利要求7所述的装置,其特征在于,包括:
所述消息类型为页面映射或dma映射;所述接口函数为用于页面映射的接口函数或用于dma映射的接口函数;所述ipc消息还包括内存长度;
所述消息类型对应的处理函数为用于页面映射的处理函数或用于dma映射的处理函数;
所述执行相应处理,并构建ipc应答消息返回给所述被调用的接口函数包括:
所述用于页面映射的处理函数或用于dma映射的接口函数从所述ipc消息中解析出内存长度;
根据所述内存长度包含的4kb内存页面的页数n向内核申请4kb*n个连续的虚拟地址,其中n为正整数;
向内核申请n个物理页;
建立n个4kb页面的虚拟地址与n个物理页的映射关系;
生成包括n个4kb页面的虚拟地址的ipc应答消息,返回给所述用于页面映射的接口函数或用于dma映射的处理函数。
技术总结