一种链式结构消息申请及分发的方法

著录项
  • CN201210335933.7
  • 20120912
  • CN102880507A
  • 20130116
  • 科立讯通信股份有限公司
  • 蔺洋;温权;郭小娟
  • G06F9/46
  • G06F9/46

  • 广东省深圳市南山区科技园松坪山齐民道一号贝特尔大厦三到六楼
  • 广东(44)
  • 广东广和律师事务所
  • 刘敏
摘要
本发明提供了一种链式结构消息申请及分发的方法,包括步骤a:链式结构消息的产生:消息池模块根据消息的大小,一次性分配一连续的内存空间,然后将内存根据消息体的大小分成若干块,再将这些块用指针连接起来;b:链式结构消息的分发:消息链表模块根据消息优先级不同,发送给线程的消息将连接到目标线程消息队列的头或者尾。本发明提供的链式结构的消息申请及分发方法,采用消息池的申请和释放机制,链式消息的分发机制,解决了应用程序对操作系统的依赖问题、增强了应用程序的可移植性及稳定性,复用率高。同时也解决了不同操作系统入口的差异性,便于功能的扩展。
权利要求

1.一种链式结构消息申请及分发的方法,其特征在于,包括步骤:

a:链式结构消息的产生:消息池模块根据消息的大小,一次性分配一连续的内存空间,然后将内存根据消息体的大小分成若干块,再将这些块用指针连接起来;

b:链式结构消息的分发:消息链表模块根据消息优先级不同,发送给线程的消息将连接到目标线程消息队列的头或者尾。

2.如权利要求1所述的链式结构消息申请及分发的方法,其特征在于,步骤a与步骤b之间还包括:链式结构消息的释放:当用户使用分配消息的时候,直接从消息池的自由消息链表中取出一条消息,当用户用完该消息时,直接将消息挂回到消息池的自由消息链表中。

3.如权利要求1所述的链式结构消息申请及分发的方法,其特征在于,步骤b中发送给线程的消息包括:一般消息和优先消息;

所述一般消息链接到目标线程消息队列的最后,采用先进先出的顺序发送;

所述优先消息连接到目标线程消息队列的最前面,采用后进先出的顺序发送。

4.如权利要求3所述的链式结构消息申请及分发的方法,其特征在于,所述链式结构消息的接收包括:普通的接收消息、定时接收消息、接收消息的回复及定时接收消息的回复。

5.如权利要求3所述的链式结构消息申请及分发的方法,其特征在于,所述链式结构消息的发送包括:普通的发送消息、定时发送消息、发送消息的回复及定时发送消息的回复。

说明书
技术领域

 本发明涉及通信技术领域,尤其涉及一种链式结构消息申请及分发的方法。

随着科学技术的不断发展,应用在公安、消防、交通以及军事等领域的专业无线通信设备要求提供更高的安全性。在多任务抢占式的实时系统中,一项工作的完成往往要通过多个任务或多个任务与多个中断处理过程(ISRs Interrupt Service  Routine)共同完成。它们之间必须协调动作互相配合,甚至需要交换信息进行通信。如:任务和其他任务及ISRs交换数据、任务与其他任务同步。因此必须保证任务能对共享资源进行互斥的访问。

为了满足任务间通信同步和互斥的需要,同时保证资源被安全的使用,必须对多个相关任务在执行的次序上进行协调。现有的无线通信设备中,软件开发模式存在着模块间耦合性强,复用率低,稳定性不高的瓶颈问题。

本发明的目的在于提供一种链式结构消息申请及分发的方法,解决了应用程序对操作系统的依赖问题、增强了应用程序的可移植性及稳定性,复用率高。

本发明的目的是通过以下技术方案实现的。

一种链式结构消息申请及分发的方法,包括步骤:

a:链式结构消息的产生:消息池模块根据消息的大小,一次性分配一连续的内存空间,然后将内存根据消息体的大小分成若干块,再将这些块用指针连接起来;

b:链式结构消息的分发:消息链表模块根据消息优先级不同,发送给线程的消息将连接到目标线程消息队列的头或者尾。

优选的,步骤a与步骤b之间还包括:链式结构消息的释放:当用户使用分配消息的时候,直接从消息池的自由消息链表中取出一条消息,当用户用完该消息时,直接将消息挂回到消息池的自由消息链表中。

优选的,步骤b中发送给线程的消息包括:一般消息和优先消息;

所述一般消息链接到目标线程消息队列的最后,采用先进先出的顺序发送;

所述优先消息连接到目标线程消息队列的最前面,采用后进先出的顺序发送。

优选的,所述链式结构消息的接收包括:普通的接收消息、定时接收消息、接收消息的回复及定时接收消息的回复。

优选的,所述链式结构消息的发送包括:普通的发送消息、定时发送消息、发送消息的回复及定时发送消息的回复。

本发明与现有技术相比,有益效果在于:本发明提供的链式结构的消息申请及分发方法,采用消息池的申请和释放机制,链式消息的分发机制,解决了应用程序对操作系统的依赖问题、增强了应用程序的可移植性及稳定性,复用率高。同时也解决了不同操作系统入口的差异性,便于功能的扩展。

图1为本发明链式结构消息申请及分发流程图。

图2为本发明消息池分配示意图。

图3为本发明消息链表传递消息示意图。

本发明在消息同步通信机能上主要提供EventDispatcher、Semaphore、Mutex、Queue四种方式。一个基本的嵌入式操作系统消息机制包括:Task调度、Task管理、同步通信、中断管理、时间管理机能等。下面简要介绍下通信过程中的四种消息传递机制。

1 )信号量服务

信号量提供了控制应用程序临界区运行的机制。OSAL 提供范围从0~32767(BIOS)  0~4294967295(Nucleus)的计算信号量。信号量两个基本操作是Obtain/Release。Obtain信号量请求消耗信号量,Release信号量请求增加了信号量。

挂起:

获得信号量操作提供无条件挂起、时间间隙挂起、无挂起等服务。一个试图获得当前计数值为零信号量的任务可以被挂起,当释放信号量请求发生时,任务恢复是可能的(不是一定的)。

多任务挂起试图获得同一个信号量,依靠信号量创建方式,任务既可以FIFO 顺序,也可以优先级顺序挂起。如果信号量支持FIFO 挂起,任务按照它们试图获得信号量的顺序恢复;另外,如果信号量支持优先级挂起,任务从高优先级到低优先级顺序恢复。

死锁:

各任务在使用系统资源时,应注意系统产生死锁的问题。所谓死锁,是指各并发任务彼此互相等待对方所拥有的资源,且这些并发任务在得到对方的资源之前不会释放自己所拥有的资源。从而造成大家都想得到资源而又都得不到资源,各并发任务不能继续向前推进的状态。

2 )互斥锁服务

互斥锁的操作主要包括互斥锁创建、上锁、解锁、摧毁互斥锁。其中互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁,这三种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要等待挂起。快速锁是指调用线程会阻塞直到线程锁得到解锁为止;递归锁能够成功地返回并且增加调用线程在互斥上的加锁次数,比如一个链表在进行插入的操作时,可以进行查的操作;检错锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误的信息。OSAL提供第一种互斥锁。

互斥锁与信号量的区别在于:

信号量用于多线程同步;一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。   

互斥锁用于多线程互斥;一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程离开,其他的线程才开始可以利用这个资源。

互斥锁只能由加锁的线程解锁;如果互斥锁已被某线程加锁,如果此线程再去加锁则无效,也就是说互斥锁只能加锁一次。

3 )事件分发服务

事件有事件发生和事件清除二种状态,由内存中每个bit的0,1表示。0表示该事件未发生或已被清除,1表示该事件已发生。最多可以设置65535个事件(用户可配置1‑65535个最多事件)。每个线程都可以等待某一事件的发生或清除,如果该事件已经是发生或清除则线程不会阻塞,如果该事件未发生或未清除则线程阻塞,一旦该事件发生或清除则会重新换醒等待该事件产生或清除的线程。同一事件可能挂载很多任务,同一任务可可能等待很多事件。

4 )消息队列服务

队列提供了传输多个消息、消息的大小可以是变长的机制。接收消息时需要用户开辟足够的缓冲区以接收消息。

消息尺寸:

一列消息包括一个或多个位字节。固定的和长度可变的消息都支持,创建时需要指定该消息队列能存放的最大消息个数。

挂起:

试图从空队列中接收消息的任务可以被永久挂起直到消息队列中有数据为止,也可以挂起到消息队列中有数据或者超过指定的时间节拍为止。

试图发送消息至满队列的任务则会提示出错信息,但队列能够确保任务请求时挂起的任务恢复。例如,假设一个任务在队列等待接收消息时挂起。当一个消息发送到队列时,挂起的任务就恢复了。

多任务能在一个队列上挂起,依靠创建队列的任务可以以FIFO或是优先级次序被挂起。

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。

请参阅图1所示,本发明提供的链式结构的消息申请及分发,具体包括:

步骤101:链式结构消息的产生及释放;

消息池模块根据消息的大小,一次性分配一大块连续的内存空间,然后将内存根据消息体的大小分成若干块,再将这些块用指针连接起来,如图2所示。当用户使用分配消息的时候,直接从消息池的自由消息链表中取出一条消息,当用户用完该消息时,直接将消息挂回到消息池的自由消息链表中。

消息池模块可以有效地使用内存空间,分配与释放直接从链表中摘取与插入,速度迅速。

考虑到当调试时有内存泄露时,可以很快发现并跟踪它,本发明设计三个接口函数,分别为:

OSAL_AllocateBuffer()    //在消息池内申请一个内存空间

OSAL_DeallocateBuffer()  //释放消息,将消息放回到消息池中

OSAL_CloneBuffer()      //克隆消息,根据指定的消息,从对应的消息池中取一个未使用的消息体,然后将消息的内容克隆到新的消息体中

步骤102:链式结构消息的分发;

消息链表模块用于链式消息的分发,包括发送和接收消息。

消息是通过内存缓存来构建的,因此在创建一个消息的时候通过OSAL_AllocateBuffer()来实现。在OSAL里线程间的消息传递是通过OSAL_SendMsg()以及类似函数来实现的,根据消息优先级不同,发送给线程的消息将连接到目标线程消息队列的头或者是尾,如图3所示。

消息的优先级有两种:一般和优先。

一般消息通过OSAL_SendMsg()发送,并且链接到目标线程消息队列的最后,采用先进先出的顺序使用。

优先消息通过OSAL_SendPriorityMsg() 或者 OSAL_SendReply() 来发送,当然这也意味着回复的消息都是优先消息。优先消息会连接到目标线程消息队列的最前面,采用后进先出的顺序使用。

一般消息的接收是通过OSAL_ReceivetMsg()等函数来实现线程间消息的接收机制。同时线程可以使用OSAL_ReceiveReply()来代替OSAL_ReceivetMsg()获得优先消息,这种方式可以用于线程接收一个来自目标线程的已知优先消息而不先接收来自其他线程的一般消息。

消息的接收函数考虑到不同情况下有不同的应用,主要有普通的接收消息、定时接收消息、接收消息的回复、定时接收消息的回复等等。常用的有以下几种类型:

OSAL_ReceiveMsg该函数是从线程消息链表中取出第一条消息。如果消息链表为空,调用线程挂起,直到消息链表中有消息时被唤醒。且该函数接收所有类型的消息(普通类型/优先类型/回复类型);

OSAL_TimedReceiveMsg该函数是从线程消息链表中取得第一条消息。如果消息链表为空,调用线程挂起,直到超时或者有消息到达时被唤醒。

OSAL_PeekMsg(非阻塞式)该函数是从线程消息链表中取出第一条消息,但不从消息链表中将消息删除。

OSAL_ReceiveReply该函数从线程消息链表中取一条回复类型(reply_type)的消息。如果消息链表中不存在这种类型的消息时,调用该函数的线程被挂起。直到消息链表中有reply_type类型的消息时,调用线程被唤醒。

上述OSAL_ReceiveReply函数,只等待回复的消息;在解除阻塞之前,若收到非回复消息则同样接收。

比如task1在等待task2的回复消息,现在task3给task1发了一个普通消息,则该消息则会自动插入到task1消息链表的尾部,只是不激活任务task1(task1仍是挂起状态,等待reply消息)

OSAL_TimedReceiveReply该函数从线程消息链表中取一条回复类型(reply_type)的消息。如果消息链表中不存在这种类型消息时,调用该函数的线程被挂起。直到有消息链表中出现reply_type类型消息时或者超时,调线程被唤醒。

上述OSAL_TimedReceiveReply函数,只等待回复的消息;在解除阻塞之前,若收到非回复消息则同样接收。

比如task1在等待task2的回复消息,现在task3给task1发了一个普通消息,则该消息则会自动插入到task1消息链表的尾部,只是不激活任务task1(task1仍是挂起状态,等待reply消息)

消息的发送函数考虑到不同情况下有不同的应用,主要有普通的发送消息、定时发送消息、发送消息的回复、定时发送消息的回复等等。常用的有以下几种类型:

OSAL_SendMsg该函数向目标线程发送消息,该消息添加到目标线程消息链表的尾部。

其中,调用该函数发送线程消息,需要通过OSAL_AllocateBuffer()从消息池获得一个空闲消息块。

该函数需要和OSAL_AllocateBuffer()配套使用。即:每获得一个消息块只能使用一次OSAL_SendMsg()函数。如需要发送同一消息内容给不同线程,可以获得多次消息块,然后给消息块赋成相同的值(也可以使用OSAL_CloneBuffer()),再调用OSAL_SendMsg()分别发送。

OSAL_SendMsgReqReply该函数是向目标线程发送需要回复的消息,但调用线程不等待目标线程的回复。

OSAL_SendMsgAndGetReply该函数是向目标线程发送需要回复的消息,并等待目标线程回复(不接收到消息,该函数不会返回)。

OSAL_SendPriorityMsg该函数是向目标线程发送一条优先消息,该消息添加到目标线程消息链表的表头。

OSAL_SendReply该函数是回复消息。将消息发送到消息指定的回复线程的消息链表的表头。

OSAL_SetSignature该函数是设置签名,标识消息的来源。比如,task1、task2分别向task3发送消息。task3通过OSAL_ReceiveMsg无法辨别消息的来源,如果用户有这方面需求,可以通过本函数来设置消息的签名即可解决此问题。签名值需要由用户做统一规范处理。上述的例子中task1的消息和task2的消息签名值不能相同,否则无法区别消息的来源。

注:Signature的值为0x0000~0xFFFF之间,其中0xFFFF已被内部使用,在使用签名时不要再使用该值。消息的发送和接收应用在模块、ErrorTrack模块、RF Manager模块、Tone Service模块、LED模块、设备管理模块等等。应用是非常的广泛和频繁。

在发送消息之前先用OSAL_AllocateBuffer()对消息申请一块内存,然后把要发送的消息通过OSAL_SendMsg()发送到对应的线程去。接收消息通过对应的线程使用OSAL_ReceiveMsg()接收。但是如果有这种情况发生时,比如task1、task2分别向task3发送消息。task3通过OSAL_ReceiveMsg无法辨别消息的来源,如果用户有这方面需求,可以通过本函数来设置消息的签名即OSAL_SetSignature可解决此问题。签名值需要由用户做统一规范处理。上述的例子中task1的消息和task2的消息签名值不能相同,否则无法区别消息的来源。

本发明提供的链式结构的消息申请及分发方法,采用消息池的申请和释放机制,链式消息的分发机制,解决了应用程序对操作系统的依赖问题、增强了应用程序的可移植性及稳定性,复用率高。同时也解决了不同操作系统入口的差异性,便于功能的扩展。

以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

本文发布于:2024-09-22 19:43:16,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/2/85282.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议