Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:ccdea31d8eba, committed 2019-08-23
- Comitter:
- gawas
- Date:
- Fri Aug 23 16:43:44 2019 +0000
- Commit message:
- init funtion;
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Aug 23 16:43:44 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blink.cpp	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,14 @@
+#include "mbed.h"
+
+
+DigitalOut myled(LED1);
+
+
+int blink() {
+     {
+        myled = 1; // LED is ON
+        wait(1.2); // 200 ms
+        myled = 0; // LED is OFF
+        wait(1.0); // 1 sec
+    }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/blink.h Fri Aug 23 16:43:44 2019 +0000 @@ -0,0 +1,2 @@ +#include "mbed.h" +int blink(); \ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/main.cpp	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+#include "blink.h"
+//------------------------------------
+// Hyperterminal configuration
+// 9600 bauds, 8-bit data, no parity
+//------------------------------------
+
+Serial pc(SERIAL_TX, SERIAL_RX);
+
+int main()
+{
+    int i = 1;
+    printf("\nAnalogIn example\n");
+    DigitalOut myled(LED1);
+    pc.printf("Hello World !\n");
+    while(1) {
+        wait(1);
+        pc.printf("This program runs since %d seconds.\n", i++);
+        blink();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/ports.h	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,112 @@
+#ifndef PORTS_H
+#define PORTS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <apex_queuing.h>
+#include <apex_sampling.h>
+
+#include "circular_buffer.h"
+
+
+struct queuing_port {
+    QUEUING_PORT_STATUS_TYPE;
+    circBuf_t                 circ_buf;
+    uint8_t                   *buffer;
+};
+
+struct sampling_port {
+    SAMPLING_PORT_STATUS_TYPE;
+    uint8_t                   *buffer;
+};
+
+typedef struct {
+    bool                      is_queuing_port;
+    union {
+        struct queuing_port   q_buf;
+        struct sampling_port  s_buf;
+    };
+    bool                      activated;
+    void                      *channel_link;
+    NAME_TYPE                 portname;
+} port_t;
+
+typedef struct{
+    uint8_t                   id;
+    NAME_TYPE                 channelname;
+    APEX_INTEGER              nb_ports;
+    port_t                    **ports;
+} channel_t;
+
+
+void init_queuing_ports(void);
+void init_sampling_ports(void);
+
+void create_queuing_port(
+    /*in */ QUEUING_PORT_NAME_TYPE   QUEUING_PORT_NAME,
+    /*in */ MESSAGE_SIZE_TYPE        MAX_MESSAGE_SIZE,
+    /*in */ MESSAGE_RANGE_TYPE       MAX_NB_MESSAGE,
+    /*in */ PORT_DIRECTION_TYPE      PORT_DIRECTION,
+    /*in */ QUEUING_DISCIPLINE_TYPE  QUEUING_DISCIPLINE,
+    /*out*/ QUEUING_PORT_ID_TYPE     *QUEUING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE);
+
+void send_queuing_message(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*in */ MESSAGE_ADDR_TYPE        MESSAGE_ADDR,       /* by reference */
+    /*in */ MESSAGE_SIZE_TYPE        LENGTH,
+    /*in */ SYSTEM_TIME_TYPE         TIME_OUT,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE);
+
+void recieve_queuing_message(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*in */ SYSTEM_TIME_TYPE         TIME_OUT,
+    /*out*/ MESSAGE_ADDR_TYPE        MESSAGE_ADDR,
+    /*out*/ MESSAGE_SIZE_TYPE        *LENGTH,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE);
+
+void get_queuing_port_id(
+    /*in */ QUEUING_PORT_NAME_TYPE   QUEUING_PORT_NAME,
+    /*out*/ QUEUING_PORT_ID_TYPE     *QUEUING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE);
+
+void get_queuing_port_status(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*out*/ QUEUING_PORT_STATUS_TYPE *QUEUING_PORT_STATUS,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE);
+
+void create_sampling_port(
+    /*in */ SAMPLING_PORT_NAME_TYPE    SAMPLING_PORT_NAME,
+    /*in */ MESSAGE_SIZE_TYPE          MAX_MESSAGE_SIZE,
+    /*in */ PORT_DIRECTION_TYPE        PORT_DIRECTION,
+    /*in */ SYSTEM_TIME_TYPE           REFRESH_PERIOD,
+    /*out*/ SAMPLING_PORT_ID_TYPE      *SAMPLING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE);
+
+void write_sampling_message(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*in */ MESSAGE_ADDR_TYPE          MESSAGE_ADDR,    /* by reference */
+    /*in */ MESSAGE_SIZE_TYPE          LENGTH,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE);
+
+void read_sampling_message(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*out*/ MESSAGE_ADDR_TYPE          MESSAGE_ADDR,
+    /*out*/ MESSAGE_SIZE_TYPE          *LENGTH,
+    /*out*/ VALIDITY_TYPE              *VALIDITY,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE);
+
+void get_sampling_port_id(
+    /*in */ SAMPLING_PORT_NAME_TYPE    SAMPLING_PORT_NAME,
+    /*out*/ SAMPLING_PORT_ID_TYPE      *SAMPLING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE);
+
+void get_sampling_port_status(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*out*/ SAMPLING_PORT_STATUS_TYPE  *SAMPLING_PORT_STATUS,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE);
+
+
+#endif /* PORTS_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/process.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,97 @@
+#include <stm32f4xx_hal.h>
+
+#include "process.h"
+#include "kernel/context.h"
+#include "kernel/part_scheduler.h"
+#include "types.h"
+
+
+static size_t find_dormant_process(process_t *processes, size_t nb_proc)
+{
+    for (size_t i = 0; i < nb_proc; ++i) {
+        if(processes[i].PROCESS_STATE == DORMANT) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+
+void create_process(partition_t *partition, uint32_t memoryAddress, PROCESS_ATTRIBUTE_TYPE* attributes, PROCESS_ID_TYPE* processId, RETURN_CODE_TYPE *RETURN_CODE)
+{
+    /* TODO: memoryAddress should be calculated and not given */
+    const int i = find_dormant_process(partition->processes, MAX_PROCESSES_PER_PARTITIONS);
+
+    if (i == -1) {
+        *RETURN_CODE = NOT_AVAILABLE;
+        return;
+    }
+    *RETURN_CODE = NO_ERROR;
+
+    *processId = i;
+    process_t *process = &partition->processes[i];
+
+    process->ATTRIBUTES  = *attributes;
+    process->CURRENT_PRIORITY = attributes->BASE_PRIORITY;
+    attributes->STACK_SIZE = 1024;
+    /* Should it maybe be "-" sizeof(ARM_context_state) on the following line? */
+    process->stackpointer = memoryAddress + sizeof(ARM_context_state);
+    process->exc_return_value = 0xFD;
+    process->tickStamp = HAL_GetTick();
+
+    context_setup(attributes->ENTRY_POINT, (void *) process->stackpointer);
+
+    process->PROCESS_STATE = READY;
+}
+
+
+void runtime_create_process(PROCESS_ATTRIBUTE_TYPE *attributes, PROCESS_ID_TYPE *processId, RETURN_CODE_TYPE *RETURN_CODE)
+{
+    partition_t *partition = getActivePartition();
+    int32_t id = partition->id;
+
+    /* Find overall memmory structure for this partition. */
+    part_mem_t *p_mem = {0};
+    const uint32_t nb_mems = sizeof(partition_memory) / sizeof(part_mem_t);
+    for (size_t i = 0; i < nb_mems; i++) {
+        if (partition_memory[i].id == id) {
+            p_mem = &partition_memory[i];
+        }
+    }
+
+
+    /* If not found data is missing, return error. */
+    if (p_mem->id == 0) {
+        *RETURN_CODE = INVALID_CONFIG;
+        return;
+    }
+
+    /* Get the DATA memory requirements for this partition. */
+    mem_req_t *data_mem = {0};
+    for (size_t i = 0; i < p_mem->arr_size; i++) {
+        if (p_mem->memory_arr[i].type == DATA) {
+            data_mem = &p_mem->memory_arr[i];
+        }
+    }
+
+    /* Data is invalid or missing, return error. */
+    if (data_mem->size == 0) {
+        *RETURN_CODE = INVALID_CONFIG;
+        return;
+    }
+
+    const uint32_t mem_size = attributes->STACK_SIZE;
+    /* Not enough space, return error. */
+    if ((mem_size + p_mem->mem_offset) > data_mem->size) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+
+    p_mem->mem_offset += mem_size;
+    const uint32_t addr = data_mem->address + p_mem->mem_offset;
+
+    create_process(partition, addr, attributes, processId, RETURN_CODE);
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/kernel/process.h Fri Aug 23 16:43:44 2019 +0000 @@ -0,0 +1,26 @@ +#ifndef PROCESS_H +#define PROCESS_H + + +#include <stdint.h> + +#include <apex_process.h> + +#include "types.h" + + +void create_process ( + partition_t* partition, + uint32_t memoryAddress, + /*in */ PROCESS_ATTRIBUTE_TYPE *ATTRIBUTES, + /*out*/ PROCESS_ID_TYPE *PROCESS_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); + +void runtime_create_process( + PROCESS_ATTRIBUTE_TYPE *attributes, + PROCESS_ID_TYPE *processId, + RETURN_CODE_TYPE *RETURN_CODE); + + +#endif /* PROCESS_H */ +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/queuing_port.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,210 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <apex_queuing.h>
+
+#include "ports.h"
+#include "../xml_data.h"
+#include "kernel/part_scheduler.h"
+
+
+void init_queuing_ports(void)
+{
+    const size_t nb_partitions =  sizeof(partitions) / sizeof(partition_t);
+    for (size_t i = 0; i < nb_partitions; ++i) {
+        port_t *ports = (port_t *)partitions[i].ports;
+
+        for (APEX_INTEGER n = 0; n < partitions[i].nb_ports; ++n) {
+            ports[n].activated = false;
+
+            if (ports[n].is_queuing_port) {
+                ports[n].q_buf.circ_buf.buffer = ports[n].q_buf.buffer;
+                ports[n].q_buf.NB_MESSAGE = 0;
+            } else {
+                /* TODO: Need to setup ports for the sampling ports as well. */
+            }
+        }
+    }
+
+    const size_t nb_channels = sizeof(connection_table) / sizeof(channel_t);
+    for (size_t i = 0; i < nb_channels; i++) {
+        channel_t *channel = &connection_table[i];
+        port_t **port_list = connection_table[i].ports;
+
+        for (APEX_INTEGER n = 0; n < channel->nb_ports; ++n) {
+            port_list[n]->channel_link = channel;
+        }
+    }
+}
+
+
+void create_queuing_port(
+    /*in */ QUEUING_PORT_NAME_TYPE   QUEUING_PORT_NAME,
+    /*in */ MESSAGE_SIZE_TYPE        MAX_MESSAGE_SIZE,
+    /*in */ MESSAGE_RANGE_TYPE       MAX_NB_MESSAGE,
+    /*in */ PORT_DIRECTION_TYPE      PORT_DIRECTION,
+    /*in */ QUEUING_DISCIPLINE_TYPE  QUEUING_DISCIPLINE,
+    /*out*/ QUEUING_PORT_ID_TYPE     *QUEUING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE)
+{
+    (void) QUEUING_DISCIPLINE;
+
+    partition_t *this_partition = getActivePartition();
+    port_t *ports = this_partition->ports;
+
+    for (APEX_INTEGER n = 0; n < this_partition->nb_ports; ++n) {
+        if (!strcmp(ports[n].portname, QUEUING_PORT_NAME) &&
+        ports[n].q_buf.MAX_MESSAGE_SIZE == MAX_MESSAGE_SIZE &&
+        ports[n].q_buf.MAX_NB_MESSAGE == MAX_NB_MESSAGE &&
+        ports[n].q_buf.PORT_DIRECTION == PORT_DIRECTION)
+        {
+            ports[n].activated = true;
+            *QUEUING_PORT_ID = n;
+            *RETURN_CODE = NO_ERROR;
+            return;
+        }
+    }
+
+    *RETURN_CODE = INVALID_PARAM;
+}
+
+
+void send_queuing_message(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*in */ MESSAGE_ADDR_TYPE        MESSAGE_ADDR,       /* by reference */
+    /*in */ MESSAGE_SIZE_TYPE        LENGTH,
+    /*in */ SYSTEM_TIME_TYPE         TIME_OUT,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE)
+{
+    (void)TIME_OUT; /* Unused parameter */
+
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid QUEUING_PORT_ID */
+    if (QUEUING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t *port = &this_partition->ports[QUEUING_PORT_ID];
+    channel_t *chan = port->channel_link;
+
+    /*	If the message is never recieved by at least one,
+    'message_sent' will stay false. */
+    bool message_sent = false;
+
+    port_t **ports = chan->ports;
+    for (APEX_INTEGER i = 0; i < chan->nb_ports; i++) {
+        port_t *port = ports[i];
+
+        if (!port->is_queuing_port ||
+            !port->activated ||
+            !(port->q_buf.PORT_DIRECTION == DESTINATION))
+        {
+                /* Not a valid destination */
+                continue;
+        }
+
+        if (port->q_buf.NB_MESSAGE >= port->q_buf.MAX_NB_MESSAGE) {
+            /* Too many messages in buffer. */
+            continue;
+        }
+
+        if (LENGTH > port->q_buf.MAX_MESSAGE_SIZE) {
+            /* Message too long. */
+            continue;
+        }
+
+        if (push_item(&port->q_buf.circ_buf, (uint8_t *)MESSAGE_ADDR, LENGTH)) {
+            /*	We should get clear on the action to take
+            when destination buffer is full. */
+            continue;
+        }
+
+        ++port->q_buf.NB_MESSAGE;
+        message_sent = true;
+    }
+
+    if (message_sent) {
+        *RETURN_CODE = NO_ERROR;
+    } else {
+        /* No destination ports */
+        *RETURN_CODE = NO_ACTION;
+    }
+}
+
+
+void recieve_queuing_message(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*in */ SYSTEM_TIME_TYPE         TIME_OUT,
+    /*out*/ MESSAGE_ADDR_TYPE        MESSAGE_ADDR,
+    /*out*/ MESSAGE_SIZE_TYPE        *LENGTH,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE)
+{
+    (void)TIME_OUT; /* Unused parameter */
+
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid QUEUING_PORT_ID */
+    if (QUEUING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t *port = &this_partition->ports[QUEUING_PORT_ID];
+
+    if (pop_item(&port->q_buf.circ_buf, MESSAGE_ADDR, (size_t *)LENGTH)) {
+        *RETURN_CODE = NO_ACTION;
+    } else {
+        --port->q_buf.NB_MESSAGE;
+        *RETURN_CODE = NO_ERROR;
+    }
+}
+
+
+void get_queuing_port_id(
+    /*in */ QUEUING_PORT_NAME_TYPE   QUEUING_PORT_NAME,
+    /*out*/ QUEUING_PORT_ID_TYPE     *QUEUING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+    port_t *ports = this_partition->ports;
+
+    for (APEX_INTEGER n = 0; n < this_partition->nb_ports; ++n) {
+        if (!strcmp(ports[n].portname, QUEUING_PORT_NAME)) {
+            *QUEUING_PORT_ID = n;
+            *RETURN_CODE = NO_ERROR;
+            return;
+        }
+    }
+
+    *RETURN_CODE = INVALID_PARAM;
+}
+
+
+void get_queuing_port_status(
+    /*in */ QUEUING_PORT_ID_TYPE     QUEUING_PORT_ID,
+    /*out*/ QUEUING_PORT_STATUS_TYPE *QUEUING_PORT_STATUS,
+    /*out*/ RETURN_CODE_TYPE         *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid QUEUING_PORT_ID */
+    if (QUEUING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t port = this_partition->ports[QUEUING_PORT_ID];
+
+    QUEUING_PORT_STATUS->NB_MESSAGE = port.q_buf.NB_MESSAGE;
+    QUEUING_PORT_STATUS->MAX_NB_MESSAGE = port.q_buf.MAX_NB_MESSAGE;
+    QUEUING_PORT_STATUS->MAX_MESSAGE_SIZE = port.q_buf.MAX_MESSAGE_SIZE;
+    QUEUING_PORT_STATUS->PORT_DIRECTION = port.q_buf.PORT_DIRECTION;
+
+    /* A procedure is needed for QUEUING_PORT_STATUS->WAITING_PROCESSES */
+
+    *RETURN_CODE = NO_ERROR;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/sampling_port.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,179 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <apex_sampling.h>
+
+#include "ports.h"
+#include "../xml_data.h"
+#include "kernel/part_scheduler.h"
+
+
+void init_sampling_ports(void)
+{
+    const size_t nb_channels = sizeof(connection_table) / sizeof(channel_t);
+    for (size_t i = 0; i < nb_channels; i++) {
+        channel_t *channel = &connection_table[i];
+        port_t **port_list = connection_table[i].ports;
+
+        for (APEX_INTEGER n = 0; n < channel->nb_ports; ++n) {
+            port_list[n]->channel_link = channel;
+        }
+    }
+}
+
+
+void create_sampling_port(
+    /*in */ SAMPLING_PORT_NAME_TYPE    SAMPLING_PORT_NAME,
+    /*in */ MESSAGE_SIZE_TYPE          MAX_MESSAGE_SIZE,
+    /*in */ PORT_DIRECTION_TYPE        PORT_DIRECTION,
+    /*in */ SYSTEM_TIME_TYPE           REFRESH_PERIOD,
+    /*out*/ SAMPLING_PORT_ID_TYPE      *SAMPLING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+    port_t *ports = this_partition->ports;
+
+    for (APEX_INTEGER n = 0; n < this_partition->nb_ports; ++n) {
+        if (!strcmp(ports[n].portname, SAMPLING_PORT_NAME) &&
+        ports[n].s_buf.MAX_MESSAGE_SIZE == MAX_MESSAGE_SIZE &&
+        ports[n].s_buf.REFRESH_PERIOD == REFRESH_PERIOD &&
+        ports[n].s_buf.PORT_DIRECTION == PORT_DIRECTION)
+        {
+            ports[n].activated = true;
+            *SAMPLING_PORT_ID = n;
+            *RETURN_CODE = NO_ERROR;
+            return;
+        }
+    }
+
+    *RETURN_CODE = INVALID_PARAM;
+}
+
+
+void write_sampling_message(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*in */ MESSAGE_ADDR_TYPE          MESSAGE_ADDR,    /* by reference */
+    /*in */ MESSAGE_SIZE_TYPE          LENGTH,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid SAMPLING_PORT_ID */
+    if (SAMPLING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t *port = &this_partition->ports[SAMPLING_PORT_ID];
+    channel_t *chan = port->channel_link;
+
+    /*	If the message is never recieved by at least one,
+    'message_sent' will stay false. */
+    bool message_sent = false;
+
+    port_t **ports = chan->ports;
+    for (APEX_INTEGER i = 0; i < chan->nb_ports; i++) {
+        port_t *port = ports[i];
+
+        if (port->is_queuing_port ||
+            !port->activated ||
+            !(port->s_buf.PORT_DIRECTION == DESTINATION))
+        {
+            /* Not a valid destination */
+            continue;
+        }
+
+        if (LENGTH > port->s_buf.MAX_MESSAGE_SIZE) {
+            /* Message too long. */
+            continue;
+        }
+
+        port->s_buf.MAX_MESSAGE_SIZE = LENGTH;
+        for (int32_t i = 0; i < LENGTH; ++i) {
+            port->s_buf.buffer[i] = ((uint8_t *)MESSAGE_ADDR)[i];
+        }
+
+        message_sent = true;
+    }
+
+    if (message_sent) {
+        *RETURN_CODE = NO_ERROR;
+    } else {
+        /* No destination ports */
+        *RETURN_CODE = NO_ACTION;
+    }
+}
+
+
+void read_sampling_message(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*out*/ MESSAGE_ADDR_TYPE          MESSAGE_ADDR,
+    /*out*/ MESSAGE_SIZE_TYPE          *LENGTH,
+    /*out*/ VALIDITY_TYPE              *VALIDITY,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE)
+{
+    (void)VALIDITY;
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid SAMPLING_PORT_ID */
+    if (SAMPLING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t *port = &this_partition->ports[SAMPLING_PORT_ID];
+    *LENGTH = port->s_buf.MAX_MESSAGE_SIZE;
+    for (int32_t i = 0; i < *LENGTH; i++) {
+        MESSAGE_ADDR[i] = port->s_buf.buffer[i];
+    }
+
+    *RETURN_CODE = NO_ERROR;
+}
+
+
+void get_sampling_port_id(
+    /*in */ SAMPLING_PORT_NAME_TYPE    SAMPLING_PORT_NAME,
+    /*out*/ SAMPLING_PORT_ID_TYPE      *SAMPLING_PORT_ID,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+    port_t *ports = this_partition->ports;
+
+    for (APEX_INTEGER n = 0; n < this_partition->nb_ports; ++n) {
+        if (!strcmp(ports[n].portname, SAMPLING_PORT_NAME)) {
+            *SAMPLING_PORT_ID = n;
+            *RETURN_CODE = NO_ERROR;
+            return;
+        }
+    }
+
+    *RETURN_CODE = INVALID_PARAM;
+}
+
+
+void get_sampling_port_status(
+    /*in */ SAMPLING_PORT_ID_TYPE      SAMPLING_PORT_ID,
+    /*out*/ SAMPLING_PORT_STATUS_TYPE  *SAMPLING_PORT_STATUS,
+    /*out*/ RETURN_CODE_TYPE           *RETURN_CODE)
+{
+    partition_t *this_partition = getActivePartition();
+
+    /* Return error if invalid SAMPLING_PORT_ID */
+    if (SAMPLING_PORT_ID >= this_partition->nb_ports) {
+        *RETURN_CODE = INVALID_PARAM;
+        return;
+    }
+
+    port_t port = this_partition->ports[SAMPLING_PORT_ID];
+
+    SAMPLING_PORT_STATUS->LAST_MSG_VALIDITY = port.s_buf.LAST_MSG_VALIDITY;
+    SAMPLING_PORT_STATUS->REFRESH_PERIOD = port.s_buf.REFRESH_PERIOD;
+    SAMPLING_PORT_STATUS->MAX_MESSAGE_SIZE = port.s_buf.MAX_MESSAGE_SIZE;
+    SAMPLING_PORT_STATUS->PORT_DIRECTION = port.s_buf.PORT_DIRECTION;
+
+    /* A procedure is needed for SAMPLING_PORT_STATUS->WAITING_PROCESSES */
+
+    *RETURN_CODE = NO_ERROR;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/svc_handler.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,161 @@
+#include <stm32f4xx_hal.h>
+#include <apex_types.h>
+#include <apex_queuing.h>
+
+#include "context.h"
+#include "drivers/time_get.h"
+#include "process.h"
+#include "part_scheduler.h"
+
+#include "ports.h"
+
+
+static uint32_t pop(uint32_t *p)
+{
+    const uint32_t ret = *(uint32_t *)(*p);
+    *p += 4;
+    return ret;
+}
+
+
+void SVC_Handler(void)
+{
+    ARM_HW_context_state* stack;
+
+    __ASM volatile (
+        "TST	LR, #0x4    	\n\t"		// Test bit 2 of EXC_RETURN
+        "ITE	EQ      		\n\t"		// Which stack pointer was used?
+        "MRSEQ  %0, MSP         \n\t"       // Move MSP into pointer if EQ flag is set
+        "MRSNE  %0, PSP         \n\t"       // Move SSP into pointer if NE flag is set
+        : "=r"  (stack)
+        : :
+    );
+
+    /* Disable sysTick */
+    SysTick->CTRL =
+        SysTick_CTRL_CLKSOURCE_Msk |
+        SysTick_CTRL_ENABLE_Msk;
+
+    switch (stack->R0) {
+    case 0xc0ffee0a:
+    {
+        uint8_t argc = 3;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        runtime_create_process(
+            (PROCESS_ATTRIBUTE_TYPE *) argv[0],
+            (PROCESS_ID_TYPE *) argv[1],
+            (RETURN_CODE_TYPE *) argv[2]);
+        break;
+    }
+    case 0xc0ffee0b:
+    {
+        uint64_t time = TIME_Get_Total();
+        stack->R0 = NO_ERROR;
+        stack->R1 = (uint32_t) time;
+        stack->R2 = (uint32_t) (time >> 32);
+        break;
+    }
+    case 0xc0ffee0c:
+    {
+        uint8_t argc = 7;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        create_queuing_port(
+            (char *) argv[0],
+            (MESSAGE_SIZE_TYPE) argv[1],
+            (MESSAGE_RANGE_TYPE) argv[2],
+            (PORT_DIRECTION_TYPE) argv[3],
+            (QUEUING_DISCIPLINE_TYPE) argv[4],
+            (QUEUING_PORT_ID_TYPE *) argv[5],
+            (RETURN_CODE_TYPE *) argv[6]);
+        break;
+    }
+    case 0xc0ffee0d:
+    {
+        uint8_t argc = 5;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        recieve_queuing_message(
+            (QUEUING_PORT_ID_TYPE) argv[0],
+            (SYSTEM_TIME_TYPE) argv[1],
+            (MESSAGE_ADDR_TYPE) argv[2],
+            (MESSAGE_SIZE_TYPE *) argv[3],
+            (RETURN_CODE_TYPE *) argv[4]);
+        break;
+    }
+    case 0xc0ffee0e:
+    {
+        uint8_t argc = 5;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        send_queuing_message(
+            (QUEUING_PORT_ID_TYPE) argv[0],
+            (MESSAGE_ADDR_TYPE) argv[1],
+            (MESSAGE_SIZE_TYPE) argv[2],
+            (SYSTEM_TIME_TYPE) argv[3],
+            (RETURN_CODE_TYPE *) argv[4]);
+        break;
+    }
+    case 0xc0ffee0f:
+    {
+        uint8_t argc = 3;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        get_queuing_port_id(
+            (char *) argv[0],
+            (QUEUING_PORT_ID_TYPE *) argv[1],
+            (RETURN_CODE_TYPE *) argv[2]);
+        break;
+    }
+    case 0xc0ffee10:
+    {
+        uint8_t argc = 3;
+        uint32_t argv[argc];
+
+        while(argc--) {
+            argv[argc] = pop(&stack->R2);
+        }
+
+        get_queuing_port_status(
+            (QUEUING_PORT_ID_TYPE) argv[0],
+            (QUEUING_PORT_STATUS_TYPE *) argv[1],
+            (RETURN_CODE_TYPE *) argv[2]);
+        break;
+    }
+    case 0xc0ffee11:
+    {
+        process_stop_self();
+        break;
+    }
+    default:
+        break;
+    }
+
+    /* Enable sysTick */
+    SysTick->CTRL =
+        SysTick_CTRL_CLKSOURCE_Msk |
+        SysTick_CTRL_TICKINT_Msk |
+        SysTick_CTRL_ENABLE_Msk;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/syscalls.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,113 @@
+#include <stm32f4xx.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "drivers/uart.h"
+
+#define STACK_POINTER (__get_MSP())
+#define UART_AUTO_ECHO
+
+
+int _close(int file)
+{
+    UNUSED(file);
+    return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+    UNUSED(file);
+    st->st_mode = S_IFCHR;
+    return 0;
+}
+
+
+int _isatty(int file)
+{
+    switch(file) {
+    case 1: // stdio
+    case 2: // stderr
+    return 1;
+
+    default: return 0;
+    }
+}
+
+
+int _lseek(int file, int ptr, int dir)
+{
+    UNUSED(file); UNUSED(ptr); UNUSED(dir);
+    return 0;
+}
+
+
+int _open(const char *name, int flags, int mode)
+{
+    UNUSED(name); UNUSED(flags); UNUSED(mode);
+    return -1;
+}
+
+
+int _read(int file, char *ptr, int len)
+{
+    UNUSED(file);
+    int i;
+    for (i = 0; i < len; i++) {
+        ptr[i] = _uart_getc();
+        #ifdef UART_AUTO_ECHO
+        _uart_putc(ptr[i]);
+        #endif
+        /* Return partial buffer if we get EOL */
+        if ('\r' == ptr[i]) {
+            ++i;
+            ptr[i] = '\n';
+            return i;
+        }
+    }
+
+    ptr[i-1] = '\r';
+    ptr[i] = '\n';
+    return  i;
+}
+
+
+caddr_t _sbrk(int incr)
+{
+    extern char _end;		/* Defined by the linker */
+    static char *heap_end;
+    char *prev_heap_end;
+
+    if (heap_end == 0) {
+        heap_end = &_end;
+    }
+    prev_heap_end = heap_end;
+    if ((unsigned)(heap_end + incr) > STACK_POINTER) {
+        /* Heap and stack collision */
+        return (caddr_t)0;
+    }
+
+    heap_end += incr;
+    return (caddr_t) prev_heap_end;
+}
+
+
+int _write(int file, char *ptr, int len)
+{
+    if (!isatty(file)) {
+        return BSP_UARTx_transmit((uint8_t*)ptr, len) == 0 ? len : 0;
+    }
+
+    int todo;
+    for (todo = 0; todo < len; todo++) {
+        const char c = *ptr++;
+        if (c == '\n') BSP_UARTx_transmit((uint8_t*)&(char){'\r'}, 1);
+        if (BSP_UARTx_transmit((uint8_t*)&c, 1) != 0) break;
+    }
+
+    return todo;
+}
+
+
+void _init(void) {}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/types.h	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,106 @@
+#ifndef TYPES_H
+#define TYPES_H
+
+#include <stdbool.h>
+
+#include <apex_types.h>
+#include <apex_partition.h>
+#include "ports.h"
+
+#include "circular_buffer.h"
+
+/*
+* This macro simplifies the generation of message buffers.
+* It sets the maximum message size, maximum message number
+* and the buffer to hold them.
+*/
+#define Q_MESSAGE_BUFFER(nb_message, message_size) \
+    .MAX_MESSAGE_SIZE = message_size, \
+    .MAX_NB_MESSAGE = nb_message, \
+    .buffer = (uint8_t [(message_size * nb_message) + \
+    (message_size * sizeof(size_t))]) {0}, \
+    .circ_buf = {0, 0, 0, (message_size * nb_message) + \
+    (message_size * sizeof(size_t))}
+
+#define S_MESSAGE_BUFFER(message_size) \
+    .MAX_MESSAGE_SIZE = message_size, \
+    .buffer = (uint8_t [message_size]) {0}
+
+#define MAX_PROCESSES_PER_PARTITIONS 3
+
+typedef enum {
+    LEVEL_A,
+    LEVEL_B,
+    LEVEL_C,
+    LEVEL_D,
+    LEVEL_E,
+} CRITICALITY;
+
+typedef enum {
+    CODE,
+    DATA,
+    INPUT_OUTPUT,
+} mem_type_t;
+
+typedef enum {
+    READ_ONLY,
+    WRITE_ONLY,
+    READ_WRITE,
+} mem_access_t;
+
+typedef struct {
+    uint32_t                  stackpointer;
+    uint8_t                   exc_return_value;
+    uint32_t				  tickStamp;
+    PROCESS_STATUS_TYPE; /* unamed struct with -fms-extensions */
+} process_t;
+
+typedef struct {
+    uint8_t                   id;
+    NAME_TYPE                 partitionname;
+    CRITICALITY	              criticality; /* Not used */
+    bool                      systempartion; /* Not used*/
+    void                      (*entrypoint)(void);
+    APEX_INTEGER              nb_ports;
+    port_t                    *ports;
+    uint32_t                  nb_processes;
+    uint32_t                  index_running_process;
+    process_t                 processes[MAX_PROCESSES_PER_PARTITIONS];
+} partition_t;
+
+typedef struct {
+    mem_type_t                type;
+    uint32_t                  size;
+    mem_access_t              access;
+    uint32_t                  address;
+} mem_req_t;
+
+typedef struct{
+    uint8_t                   id;
+    NAME_TYPE                 partitionname;
+    uint32_t                  arr_size;
+    mem_req_t                 *memory_arr;
+
+    /* This value could be calculated every time we make a new process,
+    but this is just way easier... */
+    uint32_t                  mem_offset;
+} part_mem_t;
+
+typedef struct {
+    uint8_t id;
+    uint32_t windowstartmilliseconds;
+    uint32_t windowdurationmilliseconds;
+    bool partitionperiodstart;
+} window_schedule;
+
+typedef struct {
+    uint8_t id;
+    char partitionname[32];
+    float peroidseconds;
+    float perioddurationseconds;
+    const uint8_t numWindows;
+    const window_schedule *window_arr;
+} partition_schedule;
+
+#endif // !TYPES_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/kernel/window.h	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,12 @@
+#ifndef WINDOW_H
+
+#include "partition.h"
+
+typedef struct {
+    partition_t*        partition;
+    uint32_t            frameStartTimeMillis;
+    uint32_t            durationMillis;
+} window_t;
+
+#endif // !WINDOW_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/xml_data.c	Fri Aug 23 16:43:44 2019 +0000
@@ -0,0 +1,250 @@
+#include <stdint.h>
+
+#include "xml_data.h"
+#include "kernel/circular_buffer.h"
+#include "kernel/ports.h"
+
+port_t p_yellow_toggler[1] = {{
+    .is_queuing_port = true,
+    .q_buf = {
+        .WAITING_PROCESSES = 0,
+        .PORT_DIRECTION = SOURCE,
+        Q_MESSAGE_BUFFER(32, 32),
+    },
+    .portname = "yellow_print",
+},};
+
+port_t p_red_toggler[1] = {{
+    .is_queuing_port = true,
+    .q_buf = {
+        .WAITING_PROCESSES = 0,
+        .PORT_DIRECTION = SOURCE,
+        Q_MESSAGE_BUFFER(32, 32),
+    },
+    .portname = "red_print",
+},};
+
+port_t p_stio_sys[1] = {{
+    .is_queuing_port = true,
+    .q_buf = {
+        .WAITING_PROCESSES = 0,
+        .PORT_DIRECTION = DESTINATION,
+        Q_MESSAGE_BUFFER(32, 32),
+    },
+    .portname = "sys_stio",
+},};
+
+port_t p_evil[1] = {{
+    .is_queuing_port = true,
+    .q_buf = {
+        .WAITING_PROCESSES = 0,
+        .PORT_DIRECTION = DESTINATION,
+        Q_MESSAGE_BUFFER(1, 1),
+    },
+    .portname = "temp",
+},};
+
+partition_t partitions[5] = {{
+    .id = 0,
+    .partitionname = "idle",
+    .criticality = LEVEL_E,
+    .systempartion = false,
+    .entrypoint = &idle_main,
+    .nb_ports = 0,
+    .ports = 0,
+},{
+    .id = 1,
+    .partitionname = "yellow_toggler",
+    .criticality = LEVEL_A,
+    .systempartion = false,
+    .entrypoint = &yellow_toggler_main,
+    .nb_ports = 1,
+    .ports = p_yellow_toggler,
+},{
+    .id = 2,
+    .partitionname = "red_toggler",
+    .criticality = LEVEL_A,
+    .systempartion = false,
+    .entrypoint = &red_toggler_main,
+    .nb_ports = 1,
+    .ports = p_red_toggler,
+},{
+    .id = 3,
+    .partitionname = "stio_sys",
+    .criticality = LEVEL_A,
+    .systempartion = true,
+    .entrypoint = &stdio_sys_main,
+    .nb_ports = 1,
+    .ports = p_stio_sys,
+},{
+    .id = 4,
+    .partitionname = "evil",
+    .criticality = LEVEL_A,
+    .systempartion = false,
+    .entrypoint = &evil_main,
+    .nb_ports = 1,
+    .ports = p_evil,
+},};
+
+mem_req_t memoryp_dummy_1[2] = {{
+    .type = CODE,
+    .size = 8000,
+    .access = READ_ONLY,
+    .address = 0x8010000,
+},{
+    .type = DATA,
+    .size = 8000,
+    .access = READ_WRITE,
+    .address = 0x20010000,
+},};
+
+mem_req_t memoryp_dummy_2[2] = {{
+    .type = CODE,
+    .size = 8000,
+    .access = READ_ONLY,
+    .address = 0x8012000,
+},{
+    .type = DATA,
+    .size = 8000,
+    .access = READ_WRITE,
+    .address = 0x20012000,
+},};
+
+mem_req_t memoryp_stio_sys[2] = {{
+    .type = CODE,
+    .size = 8000,
+    .access = READ_ONLY,
+    .address = 0x8014000,
+},{
+    .type = DATA,
+    .size = 8000,
+    .access = READ_WRITE,
+    .address = 0x20014000,
+},};
+
+mem_req_t memoryp_evil[2] = {{
+    .type = CODE,
+    .size = 8000,
+    .access = READ_ONLY,
+    .address = 0x8016000,
+},{
+    .type = DATA,
+    .size = 8000,
+    .access = READ_WRITE,
+    .address = 0x20016000,
+},};
+
+part_mem_t partition_memory[4] = {{
+    .id = 1,
+    .partitionname = "dummy_1",
+    .arr_size = 2,
+    .memory_arr = memoryp_dummy_1,
+    .mem_offset = 1024,
+},{
+    .id = 2,
+    .partitionname = "dummy_2",
+    .arr_size = 2,
+    .memory_arr = memoryp_dummy_2,
+    .mem_offset = 1024,
+},{
+    .id = 3,
+    .partitionname = "stio_sys",
+    .arr_size = 2,
+    .memory_arr = memoryp_stio_sys,
+    .mem_offset = 1024,
+},{
+    .id = 4,
+    .partitionname = "evil",
+    .arr_size = 2,
+    .memory_arr = memoryp_evil,
+    .mem_offset = 1024,
+},};
+
+const uint32_t majorFrameSeconds = 20000;
+
+const window_schedule windowp_yellow_toggler[2] = {{
+    .id = 1,
+    .windowstartmilliseconds = 0,
+    .windowdurationmilliseconds = 2000,
+    .partitionperiodstart = true,
+},{
+    .id = 2,
+    .windowstartmilliseconds = 10000,
+    .windowdurationmilliseconds = 2000,
+    .partitionperiodstart = true,
+},};
+
+const window_schedule windowp_red_toggler[2] = {{
+    .id = 1,
+    .windowstartmilliseconds = 3000,
+    .windowdurationmilliseconds = 1000,
+    .partitionperiodstart = true,
+},{
+    .id = 2,
+    .windowstartmilliseconds = 13000,
+    .windowdurationmilliseconds = 1000,
+    .partitionperiodstart = true,
+},};
+
+const window_schedule windowp_stio_sys[2] = {{
+    .id = 1,
+    .windowstartmilliseconds = 4000,
+    .windowdurationmilliseconds = 3000,
+    .partitionperiodstart = true,
+},{
+    .id = 2,
+    .windowstartmilliseconds = 14000,
+    .windowdurationmilliseconds = 3000,
+    .partitionperiodstart = true,
+},};
+
+const window_schedule windowp_evil[1] = {{
+    .id = 1,
+    .windowstartmilliseconds = 18000,
+    .windowdurationmilliseconds = 2000,
+    .partitionperiodstart = true,
+},};
+
+const partition_schedule partition_schedules[4] = {{
+    .id = 1,
+    .partitionname = "yellow_toggler",
+    .peroidseconds = 100,
+    .perioddurationseconds = 20,
+    .numWindows = 2,
+    .window_arr = windowp_yellow_toggler,
+},{
+    .id = 2,
+    .partitionname = "red_toggler",
+    .peroidseconds = 100,
+    .perioddurationseconds = 10,
+    .numWindows = 2,
+    .window_arr = windowp_red_toggler,
+},{
+    .id = 3,
+    .partitionname = "stio_sys",
+    .peroidseconds = 100,
+    .perioddurationseconds = 30,
+    .numWindows = 2,
+    .window_arr = windowp_stio_sys,
+},{
+    .id = 4,
+    .partitionname = "evil",
+    .peroidseconds = 200,
+    .perioddurationseconds = 20,
+    .numWindows = 1,
+    .window_arr = windowp_evil,
+},};
+
+port_t *stio_channel_ports[3] = {
+    &p_red_toggler[0],
+    &p_yellow_toggler[0],
+    &p_stio_sys[0],};
+
+channel_t connection_table[1] = {{
+    .id = 1,
+    .channelname = "stio_channel",
+    .nb_ports = 3,
+    .ports = stio_channel_ports,
+},};
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xml_data.h Fri Aug 23 16:43:44 2019 +0000 @@ -0,0 +1,20 @@ +#ifndef XML_DATA_H +#define XML_DATA_H + + +#include "kernel/types.h" + +void idle_main(void); +void yellow_toggler_main(void); +void red_toggler_main(void); +void stdio_sys_main(void); +void evil_main(void); + +extern partition_t partitions[5]; +extern part_mem_t partition_memory[4]; +extern const uint32_t majorFrameSeconds; +extern const partition_schedule partition_schedules[4]; +extern channel_t connection_table[1]; + + +#endif