博通Broadcom SDK源码学习与开发5——ECOS系统层剖析

声明:原创作品,严禁用于商业目的。 本系列文章将全面剖析以Bcm33xxx芯片开发Cablemodem产品的SDK源码为例,从编译系统到各个功能模块进行分析与探讨。

0.写在前篇

本系列文章来自于博通公司相关项目开发中的学习资料和开发总结,是企业或者公司项目开发过程中必备的网络相关知识,主要涉及到ecos和linux系统编译、内存管理、接口管理、HAL抽象层、以及IPV6、DHCP、TR069等网络相关协议。为维护版权和相关知识产权,请购买官方SDK和相关服务,此系列文章仅为个人学习使用,如有不妥之处和技术相关知识,请私信留言!
博通Broadcom SDK源码学习与开发1——SDK源码探究与Cable Modem 系统编译
博通Broadcom SDK源码学习与开发2——Bootloader功能和编译过程
博通Broadcom SDK源码学习与开发3——Cable Modem Docsis3.0
博通Broadcom SDK源码学习与开发4——ECOS系统数据流
博通Broadcom SDK源码学习与开发5——ECOS系统层剖析
博通Broadcom SDK源码学习与开发6——支持Linux系统
博通Broadcom SDK源码学习与开发7——HAL硬件抽象层分析
博通Broadcom SDK源码学习与开发8——内存与参数管理
博通Broadcom SDK源码学习与开发9——Interface接口管理
博通Broadcom SDK源码学习与开发10——Cable Modem IPv6地址
博通Broadcom SDK源码学习与开发11——Cable Modem DHCP管理
博通Broadcom SDK源码学习与开发12终结篇——TR069网管协议

1. Operating System Layer

Operating System Layer 是将thread使用到的与系统相关的资源,抽象出一些基类,在thread中通过基类的virtual方法调用不同系统子类的方法,目的是方便thread在各种系统的移植,下图列出了这些基类之间的关系:
基类之间的关系

2. BcmOperatingSystem类

系统中存在 BcmOperatingSystemFactory 类,thread可以使用该类创建各种不同系统的BcmOperatingSystem, BcmMutexSemaphore and BcmCountingSemaphore子类,BcmOperatingSystemFactory类不存在实体,使用"!BcmOperatingSystemFactory::"的方式直接调用它的方法,例: BcmThread的构造函数中使用BcmOperatingSystemFactory::NewOperatingSystem(),为每个thread创建一个相应系统的OpertaingSystem子类实体,NewOperatingSystem()函数如下:

BcmOperatingSystem *BcmOperatingSystemFactory::NewOperatingSystem(void)
{
    // Create the correct derived class.
    #if defined(WIN32)
        return new BcmWin32OperatingSystem();
    #elif defined(PSOS)
        return new BcmPSOSOperatingSystem();
    #elif defined(TARGETOS_vxWorks)
        return new BcmVxOperatingSystem();
    //#elif defined(__QNX__)
    #elif defined(TARGETOS_Qnx6)
        return new BcmQnxOperatingSystem();
    #elif defined(__linux__)
        
        return new BcmLnxOperatingSystem();

    #elif defined(TARGETOS_eCos)
        return new BcmEcosOperatingSystem();  // ecos 系统使用
    #endif
}

使用 BcmOperatingSystemFactory 创建 BcmMutexSemaphore/BcmCountingSemaphore 的原因:
1.从代码看,通过BcmOperatingSystem创建时,会先检查fTaskId,fTaskId会在调用BcmEcosOperatingSystem的BeginThread方法中赋值,所以只有在thread启动之后才能创建BcmMutexSemaphore/BcmCountingSemaphore
2.有些thread可能不需要创建BcmOperatingSystem instance,但可能需要使用BcmMutexSemaphore/BcmCountingSemaphore保护数据。

3. BcmEvent 事件

BcmEvent只用于线程间通知事件发生,不使用BcmEvent传递信息(such as how many times it occurred, when it occurred, who sent it, or any other data associated with the event)
在创建BcmEvent时,设置事件名称和事件栏位,如果所有事件栏位都被使用,返回fail,目前ecos中事件栏位使用的是uint32 !fEventBit,所以一个线程最多可以创建32种事件
接收线程创建Event,如果有多个事件,就将事件加入到EventSet中,然后等待事件发生,并且提供public的成员函数,封装Event的send(void)方法,所以其它线程可以通过接收线程提供的成员函数发送事件
Event的wait方法有两个参数WaitMode mode 和 unsigned long timeoutMS,通过mode指定kForever或者kTimeout,如果是kTimeout方式,通过timeoutMS设置timeout时间。
Event时序图

3.1 BcmEventSet 事件处理

thread创建BcmEventSet,并将它创建的event加入到eventset的vector list中,将event’s bit添加到evnet set的fEventBits中,fEventBits在wait时使用:

bool BcmEcosEventSet::DerivedAdd(BcmEvent *pEvent)
{
    // Add this event's bit to the set.
    fEventBits |= ((BcmEcosEvent *) pEvent)->EventBit();
    return true;
}

使用wait方法block thread,eventset中的任何事件触发send后,wait返回thread unblock
使用BcmEventSet的bool Occurred(BcmEvent *pEvent, bool clearEvent = true, bool peekEvent = false);检查eventset中pEvent是否被触发。

3.2 BcmEventPublisher 方法

Class BcmEventPublisher defines an interface that can be used to publish asynchronous event notifications to multiple subscribers
这个类没有定义与系统相关的子类,所以各个系统中使用的都是这个类,这个类是event的一种使用方法,提供Subscribe方法注册事件和事件的处理方法,提供PublishEvent方法,处理事件:

class BcmEventPublisher
{
public:
    ...
    Subscribe( const unsigned int event_code, BcmCompletionHandlerACT* pACT ); //给subscribers用来注册事件和对应的处理类,可以注册多个事件
    PublishEvent( unsigned int event_code ); //调用pACT->!HandleEvent(  event_code )
protected:
    ...
    typedef multimap< unsigned int, BcmCompletionHandlerACT*, less<unsigned int> > SubscriberMmap;
    typedef SubscriberMmap::iterator SubscriberMmapIt;
    SubscriberMmap fSubscriberMmap; //保存事件和事件处理的类
}

4. BcmTimer 线程定时器

创建BcmTimer的线程使用BcmTimer定时器,定时器创建时,会创建一个timer事件与定时器绑定,timeout后触发事件的send(),通知创建定时器的线程:
Timer时序图

5. BcmMutexSemaphore 互斥机制

创建互斥信号类是为了防止不同的thread同时操作share data, BcmMutexSemaphore类是为了保护数据,并不绑定事件
在thread中的使用方法: thread类的成员函数中使用mutex的lock … unlock,保护成员变量,不被同时操作。
互斥时序图

6. BcmCountingSemaphore 统计信号

统计信号,具有event和mutex的特性,在创建BcmCountingSemaphore时,传递maxCount参数设置允许访问的最大值,构造函数如下:

BcmEcosCountingSemaphore::BcmEcosCountingSemaphore(bool isBounded, //是否需要设置最大值,如果false,代表无限大
                                                   unsigned int maxCount,//最大值,isBounded为true时使用
                                                   unsigned int initialCount, //初始值
                                                   BcmEvent *pEvent, //通过BcmOperatingSystem创建会绑定事件,通过BcmOperatingSystemFactory 创建,传入NULL,不绑定事件
                                                   const char *pName) :
    BcmCountingSemaphore(pName),
    fIsBounded(isBounded),
    fMaxCount(maxCount)
{
    // Override the class name given by my parent.
    fMessageLogSettings.SetModuleName("BcmEcosCountingSemaphore");
    // Just store this.
    pfEventToTrigger = pEvent;
    if (isBounded)
    {
        // Make sure that the initial count is less than or equal to the max.
        if (initialCount > maxCount)
        {
            initialCount = maxCount;
        }
    }
    // Create the counting semaphore.
    cyg_semaphore_init(&fSemaphore, initialCount);
}

BcmEcosCountingSemaphore的get方法,检查thread是否需要lock,调用get时, count减1,如果count为0,thread会lock, get方法有参数设置模式(kTimeout或者kForever),如果timeout模式timout之后返回false
BcmEcosCountingSemaphore的realase方法,将count加1,如果设置了maxCount,检查如果大于maxCount返回fail,如果绑定event,触发event的send,通知有count释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kcyuan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值