您的位置:首页 > 其它

Bcm96xx 系列芯片 SDK介绍(二)

2014-08-29 17:33 447 查看
3 启动过程分析
这里所要分析的是linux系统起来之后的过程,因为在这之前相比于其他linux系统,它并没有什么不同之处。

1 busybox 的init中会执行 etc/inittab
2 inittab 中调用 "bcm_boot_launcher start"
3 bcm_boot_lanucher 是userspace中的一个应用程序,其作用是调用 /etc/rc3.d/ 中的全部脚本
4 rc3.d中的脚本创建 loopback 接口,挂载文件系统,创建/var 目录,加载驱动模块,最后启动了 smd 应用程序
5 smd 是此 SDK 的核心应用程序,它通过 /etc/cms_entity_info.d/ 下的 EID 配置文件将其他应用程序依次启动。

以上过程对应的代码和脚本如下:
1:
userspace/gpl/apps/busybox/init/init.c 部分代码截取

parser_t *parser = config_open2("/etc/inittab", fopen_for_read);  //分析 inittab 文件

run_actions(SYSINIT); // 执行 SYSINIT 的命令

2:
/etc/inittab 中有一句:
::sysinit:/bin/sh -l -c "bcm_boot_launcher start"   // 执行 bcm_boot_launcher 应用程序,传入 start的参数

3:
userspace/public/apps/bcm_boot_launcher/bcm_boot_launcher.c 部分代码截取

char *dir = "/etc/rc3.d"; // 定义脚本所在目录

snprintf(cmdline, sizeof(cmdline)-1, "%s/%s start", dir, curr->filename); // 构造执行脚本的命令

if (0 != (rc = system(cmdline))) // 调用system系统函数执行脚本

4:
rc3.d中的脚本:
S45bcm-base-drivers  	//加载各个驱动模块 insmod *.ko
S35system-config     	//创建 loopback 接口 lo 127.0.0.1
S25mount-fs		   	//挂载文件系统,创建 var/ 下各个子目录
S63save-dmesg		//保存linux内核启动日志
S65smd			//启动 smd 应用程序

5:
userspace/private/apps/smd/main.c
userspace/public/include/cms_params.h
部分代码截取:

#define CMS_EID_DIR  "/etc/cms_entity_info.d"  //定义 Eid 配置文件所在路径

rval = parse_eid_file(fullpathname); 	     //解析 Eid 配置文件

launchApp(dInfo);                              //根据 Eid 配置文件,启动应用程序

EID配置文件截取:
BEGIN
eid         = EID_EPON_APP                   //其EID为 EID_EPON_APP ,非常重要
name        = eponapp				     //应用程序名称
flags       = EIF_MDM|EIF_LAUNCH_ON_BOOT|EIF_MESSAGING_CAPABLE //smd是否启动此应用程序的标志
END

4 系统架构剖析
此 SDK 的应用层,是一些彼此独立的应用程序,应用程序之间本身没有依赖和关联关系。
但整个系统的运作却需要这些应用程序的交互来完成,这又是如何做到的呢,答案在于此 SDK 中维护的一套 CMS 机制。
而最核心的就是 smd 这个应用程序。

前面已经说过了,其他应用程序的启动都是 smd 做的,除此之外 smd 还维护各个应用程序之间的通信。
大致原理如下:
A应用程序要和B应用程序通信,则A应用程序首先发送消息给 smd,smd收到A的消息后解析消息头,发现是发往B应用程序的,则smd将消息发给应用程序B。
当然这个过程对于应用程序A和B是不透明的,它们毫不知情,完全感觉不到 smd 的存在,就好像他俩之间在直接通信。

这须要每个应用程序都调用cmsMsg_init的接口才行,例如
cmsReturn = cmsMsg_init(EID_OMCIPMD, &msgHandle); //这是 OMCI 应用程序调用的

此函数创建一个 AF_LOCAL 的socket,并与 smd 建立连接,smd会保存它的 EID 和 socket连接文件描述符,以便做消息转发。
EID就是表示这个应用程序的标识,需要与 /etc/cms_entity_info.d/ 中的 EID配置文件保持一致。

例:
omci 应用程序调用cmsMsg_send 接口发送给 httpd应用程序
msgInfo.src = EID_OMCIPMD;  // 表示消息来源是 omci 进程
msgInfo.dst = EID_HTTPD;    // 表示消息发往 httpd 进程
cmsMsg_send(msgHandle, &msgInfo)

由于 omci 调用 cmsMsg_init 接口初始化的 socket 是与 smd 应用程序建立的连接,那么显然这里 cmsMsg_send 发送出去的消息会被 smd 收到。
smd 收到消息后会层次调用接口:
routeMessage
sendMessageByState
oalMsg_send
将消息转发给 httpd 进程

httpd 调用 oalMsg_receive 接口收到消息
到此:omci 与 httpd 进程完成通信

最后整个 CMS 机制可以归纳为:
EID 的配置文件 + smd 的应用程序 + cmsMsg相关的自定义数据结构和接口

5 应用层开发示例
目的:创建一个能够被 smd 启动的应用程序my_app,并且能够与其他的应用程序之间互相通信
需要这样几个步骤:
1 定义 EID,并配置 EID配置文件
在 enum CmsEntityId(userspace/public/include/cms_eid.h) 中添加一个表示 my_app 的枚举常量
EID_MY_APP=300,

在 userspace/public/libs/cms_util/scripts/eid_bcm_base.txt 中添加 my_app 的eid配置
BEGIN
eid         = EID_MY_APP
name        = my_app
flags       = EIF_MDM|EIF_LAUNCH_ON_BOOT|EIF_MESSAGING_CAPABLE
END

2 编辑源代码
在 userspace/private/apps/ 目录下创建 my_app 子目录
在 userspace/private/apps/my_app 子目录下创建两个文件,main.c 和 Makefile

main.c 中必须要有标示 C应用程序 main() 入口函数的实现,cmsMsg_init 接口的调用,以及消息接收和处理。
在本例中,专门起了2个pthread 线程,一个负责消息的接受,一个负责消息的发送。

Makefile 编辑如下:
大概模样可以参考其 userspace/private/app 下的其他用程序的 Makefile
但这样几个地方需要修改:
EXE = my_app
OBJS = main.o
LIBS = -lpthread

最后上层Makefile中还要添加对于此Makefile的调用
在 userspace/private/apps/Makefile 中添加

make_all_subdirs: my_app
my_app:
$(MAKE) -C $@
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: