CAmkES Tutorial

CAmkES Tutorial

强烈推荐阅读

https://github.com/seL4/camkes-tool/blob/master/docs/index.md

中的Terminology章节,下面就对我的阅读和理解做一个记录

Terminology

Abstract Syntax Tree (AST)

抽象语法树:用形式化语言书写的文本的一个语法结构

这段代码可以变成下面这棵AST

与AST相对的是一个C(oncrete)ST,区别就是CST是在编译的过程中得到的一个Parce Tree,就会比AST要增加一些上下文相关的分析。

Architecture Description Language (ADL) 体系描述语言

这里是特指CAmkES input sepecification language

Assembly 概括

作为一个系统中的成分,作用是概括一个系统的组成。

可以被想做是对整个系统的完全的描述。一个系统至少需要包括一个Assembly. 如果一个系统有多个assembly,也就相当于有一个Assembly把所有的assembly中的组成和配置全部包括进来。

Attribute 参数

对于组成 (Component) 和连接器 (Connector) 都会有一些相关的规定了类型的额外数据。

在定义组成和连接时需要描述这些参数的名称和类型。

这些参数的数值会在实例化的时候状态,这样一个填写就称作setting。

如果没有初始化,那么就会使用默认值,如果有别名,而且别名的默认不同,那么就会使用别名的默认。

Component 组成成分

一个功能性的实体,在这里Component更像class,作为一个概念而不是一个实例存在

component foo f,描述了一个实例f,它的类型是foo

Composition

一个Component和Connector的实例组成一个系统。它们合在一起就是一个Composition。它在形式化规范中是必要的。会放在概要块中,并包含一个可选的配置。

Compound Component 复合组成成分

一个具有Coposition节的Component,同时可能有一个配置的节

Configuration

一个描述setting的容器。是一个放置给定系统的参数分配的句法的元素

Connection

一个Connector的实例,一个Connection会连接两个实例。Connector的实例并不会在任何具体的方式上特殊化这个Connector,所以很容易混淆这两个概念。

Connector

在两个实例之间的连接的类型。类似Component的概念,是一个理论的抽象,而Connection是具体的实现。

Consumes

一个Component接收事件的接口。如果说一个组成部分Consume了一个具体的事件,表示这个组成部分可以接收和处理这个事件。

Dataport

Component使用的端口接口。一个Component的数据端口在其运行时可以作为共享内存的区域。

Direction

参数传递的方向,in:调用者传给被调用者,out:被调用者传给调用者

Inout:双向传递,refin: 等价于in,不过在C的后端会被优化成pass-by-reference(引用传递)

Emits

Component发出事件的接口。如果一个Component释放了一个事件,就说明它产生了一个这个类型的事件。

Event

一个Component的异步的信号。完完全全由它们的identifier来做解释,它本身只是一个数字的值,有点像中断号的传递。

Exported Interface

对于内部的一个组成部分的实现来说,它的接口就是内部的Component实现的同一个名字的接口。

外部的接口,就是去暴露出一些接口,同时潜在的在内部来完善这些接口。

Instance

具体的实现,这里特指Component的实现。

Interface

一个抽象的交互point。interface的子类包括了procedure,event 和 port

Internal Connection

在一个复合类型中声明的连接两个实例的接口的连接。

Maybe

接口可以使用maybe关键字来声明这个接口是可选的(optional)。

可选的接口不需要与其他的接口相连,C语言中与可选的接口相连的部分(函数以及dataport的指针)称为弱符号,如果可选的接口没有任何相连,那么这些相关的Symbol就会缺乏定义,就会在运行的时候取NULL的值

Method 方法

函数

Parameter 参数

一个函数方法引用的数据。相当于函数的参数。

Port

一种在语义上代表共享内存的接口。

Procedure

一个在语义上表示函数调用的接口。包括了一系列可以被单独调用的方法。

Setting

把一组参数赋值的分配。它不负责定义类型,这些类型会在Component和Connector中定义

Struct

可以作为参数类型的一种复合类型

Uses

一个Component所调用的程序接口。一个Component包括并实现了这个程序中所有对函数的调用。

Virtual Interface

一个复合的组成部分的接口,但是没有被其实现,而是其内部的某个Component的接口的别名。

Example

struct cat {
    int paws;
    string name;
}

procedure thing {
  int func(in int x);
}

component foo {
  control;
  uses thing t1;
  emits sig s1;
  dataport buffer b1;
  attribute cat kitty;
}

component bar {
  provides thing t2;
  consumes sig s2;
  dataport buffer b2;
}

assembly {
  composition {
    component foo f;
    component bar b;

    connection RPC c1(from f.t1, to b.t2);
    connection Notification c2(from f.s1, to b.s2);
    connection SharedData c3(from f.b1, to b.b2);
  }
  configuration {
      f.kitty = {"name": "meows", "paws": 4};
  }
}

CAmkES Tutorial 实验部分

CAmkES-0

camkes hello world

hello.camkes文件:只有一个Component Client

/*
 * CAmkES tutorial part 0: just a component.
 */

component Client {
    control;
}

assembly {
    composition {
        component Client client;
    }
}

CMakeLists.txt中的相关核心代码:

find_package(camkes-tool REQUIRED)
camkes_tool_setup_camkes_build_environment()

DeclareCAmkESComponent(Client SOURCES client.c)

DeclareCAmkESRootserver(hello.camkes)

GenerateCAmkESRootserver()

# utility CMake functions for the tutorials (not required in normal, non-tutorial applications)
set(FINISH_COMPLETION_TEXT "Hello CAmkES World")
set(START_COMPLETION_TEXT "Hello CAmkES World")
configure_file(${SEL4_TUTORIALS_DIR}/tools/expect.py ${CMAKE_BINARY_DIR}/check @ONLY)

这章节没有什么需要修改的地方,就是按照指令执行就可以了。

不过还是可以看到比如说这里不再是RootTask而是RootServer

CAmkES-1

Background

介绍了Component和Connection和Interface的概念。

Component是逻辑上的代码和资源的组。他们只能通过静态定义的接口来与其他的Component交流。

Connection是一种两个Component之间交流方法的表示。实现的方法有共享内存、同步IPC、notification或者其他提供的操作。在这个lab中,会使用同步的IPC。在实现的语句中,他们被压缩成了seL4_Call这个系统调用。

Interface就是别的Component访问自己时,自己所开放的方法。具体分为Dataport, Procedural interfaces, Notifications. 这个lab中使用的时Procedure的方式。

Exercise

第一步是修改assembly,就直接找猫画虎,把Empty给改成需要的两个

第二步是增加一个Connection,提示我们去查看github上面的readme,可以看到Connection的定义方式是通过seL4RPCCall这个函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jl7f5wrB-1653277951600)(C:\Users\user\AppData\Roaming\Typora\typora-user-images\image-20220426204859802.png)]

hello-1.camkes文件:

component EmptyComponent {
 }
 
 component Client {
     control;
     uses HelloSimple hello;
 }
 
 component Echo {
     provides HelloSimple hello;
 }
 
 
 assembly {
     composition {
     	 // Exercise1: 删除Empty,增加Client和Echo
          component Client client;
          component Echo echo;
          /* hint 1: use seL4RPCCall as the connector (or you could use seL4RPC if   you prefer)
          * hint 2: look at
          * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating- an-application
		*/
		connection seL4RPCCall hello_con(from client.hello, to echo.hello);
          }
}

第三步是补充HelloSimple这个程序段,根据提示,需要写一个函数say_hello,没有返回值,传入一个string作为参数

interface/HelloSimple.idl4

/* Simple RPC interface */
procedure HelloSimple {
    /* TODO define RPC functions */
    /* hint 1: define at least one function that takes a string as input parameter. call it say_hello. no return value
     * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
     */
     void say_hello(in string str);
};

第四步是实现RPC的hello程序(但实际上已经实现了,这里需要注意一下这个函数名 = 接口名_接口中的函数名)

components/Echo/echo.c

/*
 * CAmkES tutorial part 1: components with RPC. Server part.
 */
#include <stdio.h>

/* generated header for our component */
#include <camkes.h>
/* TASK 5: implement the RPC function. */
/* hint 1: the name of the function to implement is a composition of an interface name and a function name:
 * i.e.: <interface>_<function>
 * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes
 * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4
 * hint 4: so the function would be: hello_say_hello()
 * hint 5: the CAmkES 'string' type maps to 'const char *' in C
 * hint 6: make the function print out a mesage using printf
 * hint 7: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
 */
void hello_say_hello(const char *str) {
    printf("Component %s saying: %s\n", get_instance_name(), str);
}

第五步是在Client中调用

/*
 * CAmkES tutorial part 1: components with RPC. Client part.
 */

#include <stdio.h>

/* generated header for our component */
#include <camkes.h>

/* run the control thread */
int run(void) {
    printf("Starting the client\n");
    printf("-------------------\n");
    /* TODO: invoke the RPC function */
    /* hint 1: the name of the function to invoke is a composition of an interface name and a function name:
     * i.e.: <interface>_<function>
     * hint 2: the interfaces available are defined by the component, e.g. in hello-1.camkes
     * hint 3: the function name is defined by the interface definition, e.g. in interfaces/HelloSimple.idl4
     * hint 4: so the function would be:  hello_say_hello()
     * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
     */
    char *shello = "hello world";
    hello_say_hello(shello);

    printf("After the client\n");
    return 0;
}
CAmkES-2

这个Lab的任务是放在代码中的

TASK 1,2

在Client.camkes中:

定义一个事件,这里事件和函数不一样,它不需要像上面一样去实现一个HelloSimple类,而是直接写一个类名就可以,而不需要实现,提示中你写一个string类型也可以,在这里我们还是写一个自己编造的类名。而在Procedure中想要释放一个事件就是 时间名_emit() 就可以了。

component Client {
    /* include definitions of typedefs for the dataports */
    include "str_buf.h";

    /* this component has a control thread */
    control;

    /* TASK 1: the event interfaces */
    /* hint 1: specify 2 interfaces: one "emits" and one "consumes"
     * hint 2: you can use an arbitrary string as the interface type (it doesn't get used)
     * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
	emits MyEvent ce;
    consumes MyEvent cs;

    /* TASK 2: the dataport interfaces */
    /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t"
     * hint 2: for the definition of these types see "str_buf.h".
     * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     */
 	dataport Buf d1;
    dataport str_buf_t d2;
    dataport ptr_buf_t d3;

}

TASK2要实现一个dataport的接口,其实和普通的接口很类似只是把interface改成了dataport。只是这里特指可以传数据的接口,同时也在str_buf.h中定义了相关的数据类型:

/*
 * CAmkES tutorial part 2: events and dataports
 */

#ifndef __STR_BUF_H__
#define __STR_BUF_H__

#include <camkes/dataport.h>

#define NUM_STRINGS 5
#define STR_LEN 256

/* for a typed dataport containing strings */
typedef struct {
    int n;
    char str[NUM_STRINGS][STR_LEN];
} str_buf_t;

#define MAX_PTRS 20

/* for a typed dataport containing dataport pointers */
typedef struct {
    int n;
    dataport_ptr_t ptr[MAX_PTRS];
} ptr_buf_t;

#endif
TASK 3,4

都在Echo.camkes中,和1,2类似就不多讲了

component Echo {
    /* include definitions of typedefs for the dataports */
    include "str_buf.h";

    /* TASK 3: the event interfaces */
    /* hint 1: specify 2 interfaces: one "emits" and one "consumes"
     * hint 2: you can use an arbitrary string as the interface type (it doesn't get used)
     * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
	emits MyEvent ee;
    consumes MyEvent es;


    /* TASK 4: the dataport interfaces */
    /* hint 1: specify 3 interfaces: one of type "Buf", one of type "str_buf_t" and one of type "ptr_buf_t"
     * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     */
    dataport Buf d1;
    dataport str_buf_t d2;
    dataport ptr_buf_t d3;

}
TASK 5,6,7,8

修改 hello-2.camkes,大概就是使用一些函数来把之前的定义连接起来,同时给之前的访问加上控制的权限和限制。

/*
 * CAmkES tutorial part 2: events and dataports
 */

import <std_connector.camkes>;

/* import component defintions */
import "components/Client/Client.camkes";
import "components/Echo/Echo.camkes";

assembly {
    composition {
        /* component instances */
        component Client client;
        component Echo echo;

        /* TASK 5: Event connections */
        /* hint 1: connect each "emits" interface in a component to the "consumes" interface in the other
         * hint 2: use seL4Notification as the connector
         * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
         */
		connection seL4Notification channel(from client.ce, to echo.es);
        connection seL4Notification channel(from echo.ee, to client.cs);

        /* TASK 6: Dataport connections */
        /* hint 1: connect the corresponding dataport interfaces of the components to each other
         * hint 2: use seL4SharedData as the connector
         * hint 3: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
         */
		connection seL4SharedData channel1(from client.d1, to echo.d1);
        connection seL4SharedData channel2(from client.d2, to echo.d2);
        connection seL4SharedData channel3(from client.d3, to echo.d3);

    }
    configuration {
        /* TASK 7: set component priorities */
        /* hint 1: component priority is specified as an attribute with the name <component name>.priority
         * hint 2: the highest priority is represented by 255, the lowest by 0
         */
		client.priority = 100;
        echo.priority = 90;

        /* TASK 8: restrict access to dataports */
        /* hint 1: use attribute <component>.<interface_name>_access for each component and interface
         * hint 2: appropriate values for the to_access and from_access attributes are: "R" or "W"
         * hint 4: make the "Buf" dataport read only for the Echo component
         * hint 3: make the "str_buf_t" dataport read only for the Client component
         */
		echo.d1_access = "R";
        client.d2_access = "R";
    }
}
TASK 9-16

client.c 中
主要是根据提示写入一些内容,可以对照str_buf.h中的内容,先放入字符串的数量,然后放入字符串的内容。
其中d1表示Client写入的dataport,d2表示Echo写入的dataport,分别进行一次Client的写入,和Client的读取,以及一次错误的尝试

/*
 * CAmkES tutorial part 2: events and dataports
 */

#include <stdio.h>
#include <string.h>

#include <camkes/dataport.h>

/* generated header for our component */
#include <camkes.h>

/* strings to send across to the other component */
char *s_arr[NUM_STRINGS] = { "hello", "world", "how", "are", "you?" };

/* run the control thread */
int run(void) {
    printf("%s: Starting the client\n", get_instance_name());

    /* TASK 9: copy strings to an untyped dataport */
    /* hint 1: use the "Buf" dataport as defined in the Client.camkes file
     * hint 2: to access the dataport use the interface name as defined in Client.camkes.
     * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C.
     * hint 3: first write the number of strings (NUM_STRINGS) to the dataport
     * hint 4: then copy all the strings from "s_arr" to the dataport.
     * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     */
	*(int *)d1 = NUM_STRINGS;
    int p = 4;
    for(int i = 0; i < NUM_STRINGS; ++i){
		strncpy((char*)d1 + p, s_arr[i], 10);
        p += STR_LEN;
    }

    /* TASK 10: emit event to signal that the data is available */
    /* hint 1: use the function <interface_name>_emit
     * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
	ce_emit();

    /* TASK 11: wait to get an event back signalling that the reply data is avaialble */
    /* hint 1: use the function <interface_name>_wait
     * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
	cs_wait();

    /* TASK 12: read the reply data from a typed dataport */
    /* hint 1: use the "str_buf_t" dataport as defined in the Client.camkes file
     * hint 2: to access the dataport use the interface name as defined in Client.camkes.
     * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C.
     * hint 3: for the definition of "str_buf_t" see "str_buf.h".
     * hint 4: use the "n" field to determine the number of strings in the dataport
     * hint 5: print out the specified number of strings from the "str" field
     * hint 6: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     */
	printf("%d\n", d2->n);
    for(int i = 0; i < d2->n; ++i){
		printf("%s\n", d2->str[i]);
    }

    /* TASK 13: send the data over again, this time using two dataports, one
     * untyped dataport containing the data, and one typed dataport containing
     * dataport pointers pointing to data in the untyped, dataport.
     */
    /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Client.camkes file
     * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Client.camkes file
     * hint 3: for the definition of "ptr_buf_t" see "str_buf.h".
     * hint 4: copy all the strings from "s_arr" into the untyped dataport
     * hint 5: use the "n" field of the typed dataport to specify the number of dataport pointers (NUM_STRINGS)
     * hint 6: use the "ptr" field of the typed dataport to store the dataport pointers
     * hint 7: use the function "dataport_wrap_ptr()" to create a dataport pointer from a regular pointer
     * hint 8: the dataport pointers should point into the untyped dataport
     * hint 9: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md
     */
    d3->n = 1;
    d3->ptr[0] = dataport_wrap_ptr(d1);

    /* TASK 14: emit event to signal that the data is available */
    /* hint 1: we've already done this before */
	ce_emit();

    /* TASK 15: wait to get an event back signalling that data has been read */
    /* hint 1: we've already done this before */
	cs_wait();

    printf("%s: the next instruction will cause a vm fault due to permissions\n", get_instance_name());

    /* TASK 16: test the read and write permissions on the dataport.
     * When we try to write to a read-only dataport, we will get a VM fault.
     */
    /* hint 1: try to assign a value to a field of the "str_buf_t" dataport */

    d2->n = 3;

    return 0;
}
TASK 17-25

在echo.c中增加相应的内容

/*
 * CAmkES tutorial part 2: events and dataports
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <camkes/dataport.h>
#include <sel4utils/sel4_zf_logif.h>

/* generated header for our component */
#include <camkes.h>

/* hepler function to modify a string to make it all uppercase */
void uppercase(char *str) {
    while (*str != '\0') {
        *str = toupper(*str);
        str++;
    }
}

void callback_handler_2(void *a);

/* this callback handler is meant to be invoked when the first event
 * arrives on the "consumes" event interface.
 * Note: the callback handler must be explicitly registered before the
 * callback will be invoked.
 * Also the registration is one-shot only, if it wants to be invoked
 * when a new event arrives then it must re-register itself.  Or it can
 * also register a different handler.
 */
void callback_handler_1(void *a) {
    /* TASK 19: read some data from the untyped dataport */
    /* hint 1: use the "Buf" dataport as defined in the Echo.camkes file
     * hint 2: to access the dataport use the interface name as defined in Echo.camkes.
     * For example if you defined it as "dataport Buf d" then you would use "d" to refer to the dataport in C.
     * hint 3: first read the number of strings from the dataport
     * hint 4: then print each string from the dataport
     * hint 5: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     */


    /* TASK 20: put a modified copy of the data from the untyped dataport into the typed dataport */
    /* hint 1: modify each string by making it upper case, use the function "uppercase"
     * hint 2: read from the "Buf" dataport as above
     * hint 3: write to the "str_buf_t" dataport as defined in the Echo.camkes file
     * hint 4: to access the dataport use the interface name as defined in Echo.camkes.
     * For example if you defined it as "dataport str_buf_t d_typed" then you would use "d_typed" to refer to the dataport in C.
     * hint 5: for the definition of "str_buf_t" see "str_buf.h"
     * hint 6: use the "n" field to specify the number of strings in the dataport
     * hint 7: copy the specified number of strings from the "Buf" dataport to the "str" field
     * hint 8: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-dataports
     * hint 9: you could combine this TASK with the previous one in a single loop if you want
     */

     d2->n = *(int*)d1;
     char* p = (char*)d1 + 4;
     for(int i = 0; i < d2->n; ++i){
        strncpy(d2->str[i], p, 10);
        p += STR_LEN;
     }


    /* TASK 21: register the second callback for this event. */
    /* hint 1: use the function <interface name>_reg_callback()
     * hint 2: register the function "callback_handler_2"
     * hint 3: pass NULL as the extra argument to the callback
     * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
    if(es_reg_callback(&callback_handler_2, NULL) != 0)
        printf("callback fail");

    /* TASK 22: notify the client that there is new data available for it */
    /* hint 1: use the function <interface_name>_emit
     * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
    ee_emit();
}

/* this callback handler is meant to be invoked the second time an event
 * arrives on the "consumes" event interface.
 * Note: the callback handler must be explicitly registered before the
 * callback will be invoked.
 * Also the registration is one-shot only, if it wants to be invoked
 * when a new event arrives then it must re-register itself.  Or it can
 * also register a different handler.
 */
void callback_handler_2(void *a) {
    /* TASK 23: read some data from the dataports. specifically:
     * read a dataport pointer from one of the typed dataports, then use
     * that pointer to access data in the untyped dataport.
     */
    /* hint 1: for the untyped dataport use the "Buf" dataport as defined in the Echo.camkes file
     * hint 2: for the typed dataport use the "ptr_buf_t" dataport as defined in the Echo.camkes file
     * hint 3: for the definition of "ptr_buf_t" see "str_buf.h".
     * hint 4: the "n" field of the typed dataport specifies the number of dataport pointers
     * hint 5: the "ptr" field of the typed dataport contains the dataport pointers
     * hint 6: use the function "dataport_unwrap_ptr()" to create a regular pointer from a dataport pointer
     * hint 7: for more information about dataport pointers see: https://github.com/seL4/camkes-tool/blob/master/docs/index.md
     * hint 8: print out the string pointed to by each dataport pointer
     */
    dataport_ptr_t dp = d3->ptr[0];
    void* vp = dataport_unwrap_ptr(dp);
    
    int n = *(int*)vp;
    char* p = (char*)vp + 4;
    for(int i = 0; i < n; ++i){
        char tmp[10];
        strncpy(tmp, p, 10);
        p += STR_LEN;
        printf("%s ", tmp);
    }
    printf("\n");
    

    /* TASK 24: register the original callback handler for this event */
    /* hint 1: use the function <interface name>_reg_callback()
     * hint 2: register the function "callback_handler_1"
     * hint 3: pass NULL as the extra argument to the callback
     * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */

    if(es_reg_callback(&callback_handler_1, NULL) != 0)
        printf("callback fail");

    /* TASK 25: notify the client that we are done reading the data */
    /* hint 1: use the function <interface_name>_emit
     * hint 2: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */
     ee_emit();

}

/* this function is invoked to initialise the echo event interface before it
 * becomes active. */
/* TASK 17: replace "echo" with the actual name of the "consumes" event interface */
/* hint 1: use the interface name as defined in Echo.camkes.
 * For example if you defined it as "consumes TheEvent c_event" then you would use "c_event".
 */
void es__init(void) {
    /* TASK 18: register the first callback handler for this interface */
    /* hint 1: use the function <interface name>_reg_callback()
     * hint 2: register the function "callback_handler_1"
     * hint 3: pass NULL as the extra argument to the callback
     * hint 4: look at https://github.com/seL4/camkes-tool/blob/master/docs/index.md#an-example-of-events
     */

    if(es_reg_callback(&callback_handler_1, NULL) != 0)
        printf("callback fail");

}
CAmkES-3
/*
 * CAmkES device driver tutorial.
 */

import <std_connector.camkes>;

/* import the component definitions */
import "components/Client/Client.camkes";
import "components/Timer/Timer.camkes";


/* A valid CAmkES assembly must have at least one component. As the starting point for
 * this tutorial does not have any valid components we declare an empty one that does nothing
 * just to construct a valid spec. Once you have added some components to the composition
 * you can remove this if you want, although it will cause no harm being left in */
component EmptyComponent {
}


assembly {
    composition {

        component EmptyComponent empty;

        /* Part 1, TASK 1: component instances */
        /* hint 1: one hardware component and one driver component
         * hint 2: look at
         * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
         */
        component Timerbase hardware; 	// 硬件类
        component Timer timer;			// 驱动类

        /* Part 2, TASK 1: component instances */
        /* hint 1: a single TimerDTB component
         * hint 2: look at
         * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
         */
		component TimerDTB timerDTB;


        /* this is the component interface. This starts commented out as there it must have
         * its 'hello' interface connected, which initially we cannot do. Uncomment this once
         * you can uncomment the 'timer interface connection' below */
        component Client client;


        /* Part 1, TASK 2: connections */
        /* hint 1: use seL4HardwareMMIO to connect device memory
         * hint 2: use seL4HardwareInterrupt to connect interrupt
         * hint 3: look at
         * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
         */

        /* Part 2, TASK 2: connections */
        /* hint 1: connect the dummy_source and timer interfaces
         * hint 2: the dummy_source should be the 'from' end
         * hint 3: look at
         * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#creating-an-application
         */


        /* timer interface connection */

        /* uncomment this (and the insantiation of 'client' above) once there is a timer component,
         * note that you may need to rename timer in 'to timer.hello' to match the name of the timer
         * component above
         */
//        connection seL4RPCCall hello_timer(from client.hello, to timer.hello);

    }
    configuration {
        /* Part 1, TASK 3: hardware resources */
        /* Timer and Timerbase:
         * hint 1: find out the device memory address and IRQ number from the hardware data sheet
         * hint 2: look at
         * https://github.com/seL4/camkes-tool/blob/master/docs/index.md#hardware-components
         */

        /* Part 2, TASK 3: hardware resources */
        /* TimerDTB:
         * check components/Timer/Timer.camkes
         */


        /* assign an initial value to semaphore */

//        timer.sem_value = 0;

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值