eCos内核API与内核实现的衔接

来源:互联网 发布:esp8266单片机程序 编辑:程序博客网 时间:2024/05/01 09:12

mingdu.zheng <at> gmail <dot> com
http://blog.csdn.net/zoomdy/article/details/8884815


eCos内核API是以C函数以及C结构体的形式提供的,eCos的内核是使用C++类实现的, kernel/.../src/common/kapi.cxx 将C++类实现衔接到C函数及C结构体,实现C和C++衔接的秘诀在于重构new操作符, new操作符重载的注释称之为 Magic new function,确实挺Magic的。

new操作符重载(kernel/.../src/common/kapi.cxx:82

inline void *operator new(size_t size, void *ptr){    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );    return ptr;}

这个神奇函数的实现看起来一点都不神奇,仅仅是将它的第二个参数照搬返回。 new操作符的第一个函数总是被new对象的大小,这里的第二个参数 ptr 是重载附加的。 常规的new实现将会在这里调用malloc函数分配内存空间,然后返回malloc分配的内存空间指针。 仅仅观察这个神奇函数的本身并看不出它的神奇之处,再看看对它的引用吧,以比较简单的互斥量为例。

互斥量初始化函数(kernel/.../src/common/kapi.cxx:1050

externC void cyg_mutex_init(    cyg_mutex_t        *mutex          /* Mutex to init                      */) __THROW{    CYG_ASSERT_SIZES( cyg_mutex_t, Cyg_Mutex );    Cyg_Mutex *m = new((void *)mutex) Cyg_Mutex;    m=m;}

应用程序在调用cyg_mutex_init前,首先定义一个全局的cyg_mutex_t的结构体,然后将该结构体的地址传递给cyg_mutex_init函数。 也就是说,mutex指针指向一块内存,该内存大小等于cyg_mutex_t结构体的大小。 观察cyg_mutex_init函数的第2行代码,这里的new操作符引用的是上面重载过的new操作符,new操作符的第1个参数总是size而且是自动传入的, 就像C++类成员函数的this参数一样,第2个参数,也就是代码中的第1个参数是指向cyg_mutex_t的指针,再回顾一下重载的new操作符代码, 你看出来了吗?新建的Cyg_Mutex类实例被存储在传入的cyg_mutex_t结构体实例的存储空间内,也就是说Cyg_Mutex实例和cyg_mutex_t实例是重叠的, 我怀疑我是否已经解释清楚,但是我只能解释到这里啦。然后再看这个函数的第1行代码,这行代码检查cyg_mutex_t类型和Cyg_Mutex类型的大小是否一致, 这是必须的,如果Cyg_Mutex类型所需的存储空间比cyg_mutex_t类型多显然会产生内存破坏,不仅大小要一致,连对应的成员变量排列次序都要求是一致的, 但是没有办法让编译器检查两个类型的成员变量排列次序。 可以查看Cyg_Mutex类定义(kernel/.../include/mutex.hxx:66)和cyg_mutex_t结构体定义 (kernel/.../include/kapidata.h:515)手动检查一下这两个类型的成员变量排列次序。

互斥量加锁函数(kernel/.../src/common/kapi.cxx:1066

externC cyg_bool_t cyg_mutex_lock( cyg_mutex_t *mutex ) __THROW{    return ((Cyg_Mutex *)mutex)->lock();}

API传入的是cyg_mutex_t结构体指针,将这个指针转换成Cyg_Mutex类指针, 然后使用该Cyg_Mutex类指针引用Cyg_Mutex类成员函数实现具体的加锁。


原创粉丝点击