CAmkES:CAmkES 是一个为嵌入式平台构建组件化系统的平台,CAmkES的主要目标平台是seL4微内核。学习CAmkES的前提是读者已经阅读了 seL4 编程参考,并且熟悉此内核的工作原理及其提供的机制。
关于CAmkES的各种术语,这些内容要先忽略,咱们直接进入一些基本构件的学习过程中。
运行一个简单的示例
在apps/simple下有一个示例应用程序,它涉及两个组件,echo和客户端,通过单个接口进行通信。
运行它:
mkdir build
cd build
../init-build.sh -DPLATFORM=sabre -DCAMKES_APP=simple -DSIMULATE=1
ninja
./simulate
创建应用程序
让我们使用 CAmkES 中提供的不同接口类型创建一些简单的 hello world 应用程序。创建具有两种组件类型的新应用程序目录:
mkdir -p apps/helloworld/components/Hello
mkdir -p apps/helloworld/components/Client
功能接口(称为过程)由一组方法组成。定义一个组件将通过其进行通信的接口,并将其保存在 apps/helloworld/interfaces/MyInterface.idl4 下:
/* apps/helloworld/interfaces/MyInterface.idl4 */
procedure MyInterface {
void print(in string message);
}
此接口由单个方法 print 组成,该方法采用 string 类型的输入参数。每个组件都需要用所谓的架构描述语言描述它公开或需要的接口的描述。在 apps/helloworld/components/Hello/Hello.camkes 和 apps/helloworld/components/Client/Client.camkes 中创建这些。
/* apps/helloworld/components/Hello/Hello.camkes */
import "../../interfaces/MyInterface.idl4";
component Hello {
provides MyInterface inf;
}
/* apps/helloworld/components/Client/Client.camkes */
import "../../interfaces/MyInterface.idl4";
component Client {
control;
uses MyInterface iface;
}
请注意,每个组件描述都需要从应用程序/helloworld/interfaces导入我们上面创建的接口文件。Hello 组件将包含 MyInterface 的实现,而 Client 组件将期望提供 MyInterface 的实现。该关键字指示客户端是所谓的活动组件。这意味着它将包含一个 main 函数,并具有一个活动的控制线程。#include
control
run
创建一个文件来描述应用程序/helloworld/helloworld.camkes上的系统的实例化和结构。
/* apps/helloworld/helloworld.camkes */
import <std_connector.camkes>;
import "components/Hello/Hello.camkes";
import "components/Client/Client.camkes";
assembly {
composition {
component Hello h;
component Client c;
connection seL4RPCCall conn(from c.iface, to h.inf);
}
}
此文件以引用其他文件的多个 import 语句开头。Hello.camkes 和 Client.camkes 是我们上面创建的文件,而 std_connector.camkes 是一个内置文件,定义了标准的 CAmkES 连接器类型。现在用于组件的实现。为 Hello as apps/helloworld/components/Hello/src/hello.c 创建单个源文件:
/* apps/helloworld/components/Hello/src/hello.c */
#include <camkes.h>
#include <stdio.h>
void inf__init(void) {
}
void inf_print(const char *message) {
printf("Client says: %s\n", message);
}
camkes.h 由 CAmkES 构建系统生成,包含此组件需要实现的与 MyInterface 相关的函数的原型。在本例中,我们没有要执行的初始化:inf_init
将 Client 的源文件创建为 apps/helloworld/components/Client/src/client.c该文件调用这些函数:
/* apps/helloworld/components/Client/src/client.c */
#include <camkes.h>
int run(void) {
const char *s = "hello world";
iface_print(s);
return 0;
}
CAmkES 组件的入口点是 :run
最后一件事是添加一些构建系统样板,以便能够构建系统。从另一个应用程序复制其中一个文件或从头开始创建:
cmake_minimum_required(VERSION 3.7.2)
project(helloworld C)
DeclareCAmkESComponent(Client SOURCES components/Client/src/client.c)
DeclareCAmkESComponent(Hello SOURCES components/Hello/src/hello.c)
DeclareCAmkESRootserver(helloworld.camkes)
现在,您可以通过在 cmake 配置 GUI 中输入值来编译并运行此应用程序:
cd build
cmake . -DCAMKES_APP=helloworld # set `helloworld` as CAMKES_APP
ninja
./simulate
如果一切顺利,您应该看到:
Client says: hello world