예제 #1
0
/* AXP Extention handler */
static int
store_tag(AXP *axp, int when, int type, int tag,
		const char *buf, size_t len, void *u)
{
	/*
	 * note: max size of encoded text via expat is 64kirobyte.
	 * decoded binary size is 3/4 of encoded text.
	 * + 2: module bytes
	 */
	static char decbuf[AXP_BUFSIZE * 3 / 4 + 2 + 1];

	tr_ctx_t *tr_ctx = u;
	rspull_context_t *ctx = tr_ctx->arg;
	arms_context_t *res = arms_get_context();
	uint32_t mod_id = 0;
	const char *mod_ver = NULL;
	const char *mod_loc = NULL;
	static int module_added = 0;
	arms_config_cb_t func;
	int flag, err = 0;

	/* Emergency stop requested */
	if (tr_ctx->read_done) {
		return 0;
	}

	if ((func = res->callbacks.config_cb) == NULL) {
		return -1;
	}

	switch (tag) {
	case ARMS_TAG_MODULE:
		if (when != AXP_PARSE_END)
			return 0;
		/* chained to new module storage */
		mod_id = get_module_id(axp, ARMS_TAG_MODULE);
		mod_ver = get_module_ver(axp, ARMS_TAG_MODULE);
		err = add_module(mod_id, mod_ver, (const char *)buf);
		if (err < 0) {
			tr_ctx->res_result = 415;/*System Error*/
			tr_ctx->read_done = 1;
			err = 0; /* not parser err */
			break;
		}
		module_added = 1;
		break;
	case ARMS_TAG_MDCONF:
		if (module_added) {
			/* module db: new -> current */
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				break;
			}
			module_added = 0;
		}
		if (when == AXP_PARSE_START) {
			ctx->data.first_fragment = 1;
			return 0;
		}

		/* chained to md-config storage */
		mod_id = get_module_id(axp, ARMS_TAG_MDCONF);
		if (!arms_module_is_exist(mod_id)) {
			/*
			 * <md-config> found, but <module> not found.
			 */
			tr_ctx->res_result = 415;/*System Error*/
			tr_ctx->read_done = 1;
			break;
		}
		mod_ver = lookup_module_ver(mod_id);
		mod_loc = lookup_module_location(mod_id);

		if (arms_get_encoding(axp, tag) == ARMS_DATA_BINARY) {
			int newlen;
			newlen = arms_base64_decode_stream(&ctx->base64,
			    decbuf, sizeof(decbuf) - 1, buf, len);
			if (newlen < 0) {
				libarms_log(ARMS_LOG_EBASE64_DECODE,
					    "base64 decode error "
					    "srclen %d, dstlen %d",
					    len, sizeof(decbuf) - 1);
				tr_ctx->res_result = 402;/*SA Failure*/
				tr_ctx->read_done = 1;
				break;
			}
			len = newlen;
			decbuf[len] = '\0';
			buf = decbuf;
		}
		/*
		 * buf, len is prepared.
		 * if res->fragment == 0 and AXP_PARSE_CONTENT,
		 * buffered part of config.
		 */
		if (res->fragment == 0) {
			ctx->catbuf = REALLOC(ctx->catbuf, ctx->catlen + len);
			if (ctx->catbuf == NULL) {
				/*Resource Exhausted*/
				tr_ctx->result = 413;
				return -1;
			}
			memcpy(ctx->catbuf + ctx->catlen, buf, len);
			ctx->catlen += len;
			if (when == AXP_PARSE_CONTENT) {
				/* wait for next data */
				return 0;
			}
			/* AXP_PARSE_END */
			buf = ctx->catbuf;
			len = ctx->catlen;
		}
		/* CONTENT or END */
		flag = 0;
		if (ctx->data.first_fragment == 1) {
			flag |= ARMS_FRAG_FIRST;
			ctx->data.first_fragment = 0;
		}
		/* continued' config */
		if (when == AXP_PARSE_CONTENT) {
			flag |= ARMS_FRAG_CONTINUE;
		}
		/* callback it */
		do {
			int slen;
			/* call config callback */
			if (res->fragment != 0 && len > res->fragment) {
				slen = res->fragment;
			} else {
				slen = len;
				/* if last fragment */
				if (when == AXP_PARSE_END)
					flag |= ARMS_FRAG_FINISHED;
			}
			err = (*func)(mod_id,
				      mod_ver,		/* version */
				      mod_loc,		/* infostring */
				      ARMS_PULL_STORE_CONFIG,
				      buf, slen, flag, res->udata);
			if (err < 0) {
				res->trigger = "invalid config";
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				err = 0; /* not parser err */
				break;
			}
			buf += slen;
			len -= slen;
			flag &= ~ARMS_FRAG_FIRST;
			flag |= ARMS_FRAG_CONTINUE;
		} while(len > 0);
		if (ctx->catbuf != NULL) {
			/* reset for next module id */
			FREE(ctx->catbuf);
			ctx->catbuf = NULL;
			ctx->catlen = 0;
		}
		break;
	case ARMS_TAG_PUSH_ADDRESS:
		if (when != AXP_PARSE_END)
			return 0;
		if (ctx->pa_index < MAX_RS_INFO) {
			res->rs_push_address[ctx->pa_index++] = STRDUP(buf);
		}
		break;
	case ARMS_TAG_PULL_SERVER_URL:
		if (when != AXP_PARSE_END)
			return 0;
		if (ctx->pu_index < MAX_RS_INFO) {
			res->rs_pull_url[ctx->pu_index++] = STRDUP(buf);
		}
		break;
	case ARMS_TAG_MSG:
		if (when != AXP_PARSE_END)
			return 0;

		if (module_added) {
			/* care no <md-config> case. */
			configure_module_cb.udata = res;
			init_module_cb(&configure_module_cb);
			err = sync_module();
			if (err < 0) {
				tr_ctx->res_result = 415;/*System Error*/
				tr_ctx->read_done = 1;
				break;
			}
			module_added = 0;
		}
		if (acmi_get_num_server(res->acmi, ACMI_CONFIG_CONFSOL) == ctx->pu_index) {
			res->rs_pull_1st = acmi_get_current_server(res->acmi,
								   ACMI_CONFIG_CONFSOL);
		} else {
			res->rs_pull_1st = -1;
		}
		tr_ctx->read_done = 1;
		break;
	default:
		break;
	}

	return err;
}
예제 #2
0
int main(){
    struct Handler *handler_p, *next_handler;
    unsigned hid;
    unsigned oep;
    // This is NOT THE PROPER WAY!!!
    unsigned siginfo[512];
    unsigned baseaddr, memsize;
    enum __ptrace_request pr, pr2;
    //struct user_regs_struct regs;
    //char inst_str[128];
    // Test
    const char *prog = "./try";
    //char indirect = 0;
    //char manual = 0;
    //char plt = 1;
    //int pop = 0;
    //ban = 0x0804841b;
    int wait_status;
    struct user_regs_struct regs;

    init();

    pid_t pid = fork();
    if (pid == 0){
        Ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl(prog, prog, NULL);
    }else if (pid > 0){
        oep = get_entry_point(prog);
        // On loaded
        wait(&wait_status);
        if (WIFSTOPPED(wait_status)){
            // Test, wrong
            memsize = get_memsize(prog);
            baseaddr = get_baseaddr(prog);
            add_module(&whitelist, baseaddr, memsize);
            get_handler(pid, oep, get_trace_option(fopen("/tmp/trace","w"), whitelist));
            get_handler(pid, 0x8048380, get_disable_option(API_TYPE_PLT));
            Ptrace(PTRACE_CONT, pid, NULL, NULL);
        }

        wait(&wait_status);
        // Withdraw control from plugins
        while (WIFSTOPPED(wait_status)){
            Ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
            // Caused by breakpoint
            if (siginfo[2] == 0x80){
                // Discard the 0xcc int 3 instruction
                // So move the eip upper by 1
                Ptrace(PTRACE_GETREGS, pid, NULL, &regs);
                regs.eip --;
                Ptrace(PTRACE_SETREGS, pid ,NULL, &regs);
            }

            // PTRACE_CONT by default because it has the lowest priority
            pr = PTRACE_CONT;
            hid = GETID(regs.eip);

            for (handler_p=global_handler;handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = global_expire(pid, handler_p, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            for (handler_p=handlers[hid];handler_p;handler_p=next_handler){
                next_handler = handler_p->next_handler;
                pr2 = dispatch(pid, handler_p);
                pr = PRIORITY(pr, pr2);
                pr2 = expire(pid, handler_p, hid, &next_handler);
                pr = PRIORITY(pr, pr2);
            }
            Ptrace(pr, pid, NULL, NULL);
            wait(&wait_status);
        }
    }else{
        perror("Folk failed: ");
        exit(-1);
    }
    finalize();
    return 0;
}
예제 #3
0
static int ctapi_load_module(sc_context_t *ctx,
		struct ctapi_global_private_data *gpriv, scconf_block *conf)
{
	const char *val;
	struct ctapi_functions funcs;
	struct ctapi_module *mod;
	const scconf_list *list;
	scconf_block *conf_block = NULL;
	void *dlh;
	int r, i, NumUnits;
	u8 cmd[5], rbuf[256], sad, dad;
	unsigned short lr;

	list = scconf_find_list(conf, "ports");
	if (list == NULL) {
		sc_log(ctx, "No ports configured.");
		return -1;
	}

	val = conf->name->data;
	dlh = sc_dlopen(val);
	if (!dlh) {
		sc_log(ctx, "Unable to open shared library '%s': %s", val, sc_dlerror());
		return -1;
	}

	funcs.CT_init = (CT_INIT_TYPE *) sc_dlsym(dlh, "CT_init");
	if (!funcs.CT_init)
		goto symerr;
	funcs.CT_close = (CT_CLOSE_TYPE *) sc_dlsym(dlh, "CT_close");
	if (!funcs.CT_close)
		goto symerr;
	funcs.CT_data = (CT_DATA_TYPE *) sc_dlsym(dlh, "CT_data");
	if (!funcs.CT_data)
		goto symerr;

	mod = add_module(gpriv, val, dlh);
	if (!mod)
		goto symerr;
	for (; list != NULL; list = list->next) {
		int port;
		char namebuf[128];
		char rv;
		sc_reader_t *reader;
		struct ctapi_private_data *priv;

		if (sscanf(list->data, "%d", &port) != 1) {
			sc_log(ctx, "Port '%s' is not a number.", list->data);
			continue;
		}
		rv = funcs.CT_init((unsigned short)mod->ctn_count, (unsigned short)port);
		if (rv) {
			sc_log(ctx, "CT_init() failed with %d", rv);
			continue;
		}

		reader = calloc(1, sizeof(sc_reader_t));
		priv = calloc(1, sizeof(struct ctapi_private_data));
		if (!priv || !reader) {
			free(reader);
			free(priv);
			return SC_ERROR_OUT_OF_MEMORY;
		}
		reader->drv_data = priv;
		reader->ops = &ctapi_ops;
		reader->driver = &ctapi_drv;
		snprintf(namebuf, sizeof(namebuf), "CT-API %s, port %d", mod->name, port);
		reader->name = strdup(namebuf);
		priv->funcs = funcs;
		priv->ctn = mod->ctn_count;

		reader->max_send_size = SC_READER_SHORT_APDU_MAX_SEND_SIZE;
		reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;

		conf_block = sc_get_conf_block(ctx, "reader_driver", "ctapi", 1);
		if (conf_block) {
			reader->max_send_size = scconf_get_int(conf_block, "max_send_size", reader->max_send_size);
			reader->max_recv_size = scconf_get_int(conf_block, "max_recv_size", reader->max_recv_size);
			if (scconf_get_bool(conf_block, "enable_escape", 0))
				reader->flags |= SC_READER_ENABLE_ESCAPE;
		}

		r = _sc_add_reader(ctx, reader);
		if (r) {
			funcs.CT_close((unsigned short)mod->ctn_count);
			free(priv);
			free(reader->name);
			free(reader);
			break;
		}

		/* Detect functional units of the reader according to CT-BCS spec version 1.0
		(14.04.2004, http://www.teletrust.de/down/mct1-0_t4.zip) */
		cmd[0] = CTBCS_CLA;
		cmd[1] = CTBCS_INS_STATUS;
		cmd[2] = CTBCS_P1_CT_KERNEL;
		cmd[3] = CTBCS_P2_STATUS_TFU;
		cmd[4] = 0x00;
		dad = 1;
		sad = 2;
		lr = 256;

		rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
		if (rv || (lr < 4) || (rbuf[lr-2] != 0x90)) {
			sc_log(reader->ctx, "Error getting status of terminal: %d, using defaults", rv);
		}
		if (rbuf[0] != CTBCS_P2_STATUS_TFU) {
			/* Number of slots might also detected by using CTBCS_P2_STATUS_ICC.
			   If you think that's important please do it... ;) */
			sc_log(reader->ctx, "Invalid data object returned on CTBCS_P2_STATUS_TFU: 0x%x", rbuf[0]);
		}
		NumUnits = rbuf[1];
		if (NumUnits + 4 > lr) {
			sc_log(reader->ctx, "Invalid data returned: %d functional units, size %d", NumUnits, rv);
		}
		priv->ctapi_functional_units = 0;
		for(i = 0; i < NumUnits; i++) {
			switch(rbuf[i+2]) {
				case CTBCS_P1_INTERFACE1:
				case CTBCS_P1_INTERFACE2:
				case CTBCS_P1_INTERFACE3:
				case CTBCS_P1_INTERFACE4:
				case CTBCS_P1_INTERFACE5:
				case CTBCS_P1_INTERFACE6:
				case CTBCS_P1_INTERFACE7:
				case CTBCS_P1_INTERFACE8:
				case CTBCS_P1_INTERFACE9:
				case CTBCS_P1_INTERFACE10:
				case CTBCS_P1_INTERFACE11:
				case CTBCS_P1_INTERFACE12:
				case CTBCS_P1_INTERFACE13:
				case CTBCS_P1_INTERFACE14:
				/* Maybe a weak point here if multiple interfaces are present and not returned
				   in the "canonical" order. This is not forbidden by the specs, but why should
				   anyone want to do that? */
					sc_log(reader->ctx, "Found slot id 0x%x", rbuf[i+2]);
					break;

				case CTBCS_P1_DISPLAY:
					priv->ctapi_functional_units |= CTAPI_FU_DISPLAY;
					sc_log(reader->ctx, "Display detected");
					break;

				case CTBCS_P1_KEYPAD:
					priv->ctapi_functional_units |= CTAPI_FU_KEYBOARD;
					sc_log(reader->ctx, "Keypad detected");
					break;

				case CTBCS_P1_PRINTER:
					priv->ctapi_functional_units |= CTAPI_FU_PRINTER;
					sc_log(reader->ctx, "Printer detected");
					break;

				case CTBCS_P1_FINGERPRINT:
				case CTBCS_P1_VOICEPRINT:
				case CTBCS_P1_DSV:
				case CTBCS_P1_FACE_RECOGNITION:
				case CTBCS_P1_IRISSCAN:
					priv->ctapi_functional_units |= CTAPI_FU_BIOMETRIC;
					sc_log(reader->ctx, "Biometric sensor detected");
					break;

				default:
					sc_log(reader->ctx, "Unknown functional unit 0x%x", rbuf[i+2]);
			}
		}
		/* CT-BCS does not define Keyboard/Display for each slot, so I assume
		those additional units can be used for each slot */
		if (priv->ctapi_functional_units) {
			if (priv->ctapi_functional_units & CTAPI_FU_KEYBOARD)
				reader->capabilities |= SC_READER_CAP_PIN_PAD;
			if (priv->ctapi_functional_units & CTAPI_FU_DISPLAY)
				reader->capabilities |= SC_READER_CAP_DISPLAY;
		}

		ctapi_reset(reader);
		refresh_attributes(reader);
		mod->ctn_count++;
	}
	return 0;
symerr:
	sc_log(ctx, "Unable to resolve CT-API symbols.");
	sc_dlclose(dlh);
	return -1;
}
예제 #4
0
/* Read the next configuration file.  */
static void
internal_function
read_conf_file (const char *filename, const char *directory, size_t dir_len,
		void **modules, size_t *nmodules)
{
  /* Note the file is opened with cancellation in the I/O functions
     disabled.  */
  FILE *fp = fopen (filename, "rce");
  char *line = NULL;
  size_t line_len = 0;
  static int modcounter;

  /* Don't complain if a file is not present or readable, simply silently
     ignore it.  */
  if (fp == NULL)
    return;

  /* No threads reading from this stream.  */
  __fsetlocking (fp, FSETLOCKING_BYCALLER);

  /* Process the known entries of the file.  Comments start with `#' and
     end with the end of the line.  Empty lines are ignored.  */
  while (!feof_unlocked (fp))
    {
      char *rp, *endp, *word;
      ssize_t n = __getdelim (&line, &line_len, '\n', fp);
      if (n < 0)
	/* An error occurred.  */
	break;

      rp = line;
      /* Terminate the line (excluding comments or newline) by an NUL byte
	 to simplify the following code.  */
      endp = strchr (rp, '#');
      if (endp != NULL)
	*endp = '\0';
      else
	if (rp[n - 1] == '\n')
	  rp[n - 1] = '\0';

      while (__isspace_l (*rp, _nl_C_locobj_ptr))
	++rp;

      /* If this is an empty line go on with the next one.  */
      if (rp == endp)
	continue;

      word = rp;
      while (*rp != '\0' && !__isspace_l (*rp, _nl_C_locobj_ptr))
	++rp;

      if (rp - word == sizeof ("alias") - 1
	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0)
	add_alias (rp, *modules);
      else if (rp - word == sizeof ("module") - 1
	       && memcmp (word, "module", sizeof ("module") - 1) == 0)
	add_module (rp, directory, dir_len, modules, nmodules, modcounter++);
      /* else */
	/* Otherwise ignore the line.  */
    }

  free (line);

  fclose (fp);
}
예제 #5
0
TEST_F(JitCompilerTest, ThrowsOnInvalidSymbolLookup) {
  auto compiler = JitCompiler{};
  compiler.add_module(std::move(_module));
  ASSERT_THROW(compiler.find_symbol<void()>("some_nonexisting_symbol"), std::logic_error);
}
예제 #6
0
TEST_F(JitCompilerTest, CompilesAddedModules) {
  auto compiler = JitCompiler{};
  compiler.add_module(std::move(_module));
  auto add_fn = compiler.find_symbol<int32_t(int32_t, int32_t)>(_add_fn_symbol);
  ASSERT_EQ(add_fn(1, 5), 1 + 5);
}
예제 #7
0
AST_Decl *UTL_Scope::call_add()
{
   AST_Decl *result = NULL;
   AST_Decl *decl;

   UTL_ScopeActiveIterator *i;
   UTL_Scope *scope;

   i = new UTL_ScopeActiveIterator(this, UTL_Scope::IK_decls);

   while (!(i->is_done()))
   {
      decl = i->item();
      scope = 0;

      switch (decl->node_type())
      {

      case AST_Decl::NT_argument:
         result = add_argument(AST_Argument::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_array:
         result = add_array(AST_Array::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_attr:
         result = add_attribute(AST_Attribute::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_const:
         result = add_constant(AST_Constant::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_enum:
         scope = AST_Enum::narrow_from_decl(decl);
         result = add_enum(AST_Enum::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_enum_val:
         result = add_enum_val(AST_EnumVal::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_except:
         scope = AST_Exception::narrow_from_decl(decl);
         result = add_exception(AST_Exception::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_field:
         result = add_field(AST_Field::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_interface:
         scope = AST_Interface::narrow_from_decl(decl);
         result = add_interface(AST_Interface::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_interface_fwd:
         result = add_interface_fwd(AST_InterfaceFwd::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_module:
         scope = AST_Module::narrow_from_decl(decl);
         result = add_module(AST_Module::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_op:
         result = add_operation(AST_Operation::narrow_from_decl(decl));
         scope = AST_Operation::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_pre_defined:
         result =
         add_predefined_type(AST_PredefinedType::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_sequence:
         result = add_sequence(AST_Sequence::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_string:
         result = add_string(AST_String::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_struct:
         result = add_structure(AST_Structure::narrow_from_decl(decl));
         scope = AST_Structure::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_typedef:
         result = add_typedef(AST_Typedef::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_union:
         result = add_union(AST_Union::narrow_from_decl(decl));
         scope = AST_Union::narrow_from_decl(decl);
         break;

      case AST_Decl::NT_union_branch:
         result = add_union_branch(AST_UnionBranch::narrow_from_decl(decl));
         break;
         //   case AST_Decl::NT_opaque:
         //  result = add_opaque(AST_Opaque::narrow_from_decl(decl));
         // break;

      case AST_Decl::NT_value:
         result = add_valuetype (AST_Value::narrow_from_decl (decl));
         scope = AST_Value::narrow_from_decl (decl);
         break;

      case AST_Decl::NT_value_fwd:
         result = add_valuetype_fwd(AST_ValueFwd::narrow_from_decl(decl));
         break;

      case AST_Decl::NT_state_member:
         result = add_state_member(AST_StateMember::narrow_from_decl(decl));
         break;

      default:
         return NULL;
      }

      if (scope)
         scope->call_add();

      i->next();
   }

   delete i;
   return result;
}
예제 #8
0
파일: Kernel.cpp 프로젝트: bgamari/Smoothie
// The kernel is the central point in Smoothie : it stores modules, and handles event calls
Kernel::Kernel() {
    // Config first, because we need the baud_rate setting before we start serial
    this->config         = new Config();

    // Serial second, because the other modules might want to say something
    this->streams        = new StreamOutputPool();

    // Configure UART depending on MRI config
    NVIC_SetPriorityGrouping(0);
    if( !isDebugMonitorUsingUart0() ) {
        this->serial         = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
    } else {
        this->serial         = new SerialConsole(p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
    }
    this->add_module( this->config );

    this->add_module( this->serial );

    // HAL stuff
    add_module( this->slow_ticker          = new SlowTicker());
    this->step_ticker          = new StepTicker();
    this->adc                  = new Adc();

    // LPC17xx-specific
    NVIC_SetPriorityGrouping(0);
    NVIC_SetPriority(TIMER0_IRQn, 2);
    NVIC_SetPriority(TIMER1_IRQn, 1);
    NVIC_SetPriority(TIMER2_IRQn, 3);

    // Set other priorities lower than the timers
    NVIC_SetPriority(ADC_IRQn, 4);
    NVIC_SetPriority(USB_IRQn, 4);

    // If MRI is enabled
    if( MRI_ENABLE ) {
        if( NVIC_GetPriority(UART0_IRQn) > 0 ) {
            NVIC_SetPriority(UART0_IRQn, 4);
        }
        if( NVIC_GetPriority(UART1_IRQn) > 0 ) {
            NVIC_SetPriority(UART1_IRQn, 4);
        }
        if( NVIC_GetPriority(UART2_IRQn) > 0 ) {
            NVIC_SetPriority(UART2_IRQn, 4);
        }
        if( NVIC_GetPriority(UART3_IRQn) > 0 ) {
            NVIC_SetPriority(UART3_IRQn, 4);
        }
    } else {
        NVIC_SetPriority(UART0_IRQn, 4);
        NVIC_SetPriority(UART1_IRQn, 4);
        NVIC_SetPriority(UART2_IRQn, 4);
        NVIC_SetPriority(UART3_IRQn, 4);
    }

    // Configure the step ticker
    int base_stepping_frequency          =  this->config->value(base_stepping_frequency_checksum      )->by_default(100000)->as_number();
    double microseconds_per_step_pulse   =  this->config->value(microseconds_per_step_pulse_checksum  )->by_default(5     )->as_number();

    this->step_ticker->set_reset_delay( microseconds_per_step_pulse / 1000000L );

    this->step_ticker->set_frequency(   base_stepping_frequency );

    // Core modules
    this->add_module( this->gcode_dispatch = new GcodeDispatch() );
    this->add_module( this->robot          = new Robot()         );
    this->add_module( this->stepper        = new Stepper()       );
    this->add_module( this->planner        = new Planner()       );
    this->add_module( this->conveyor       = new Conveyor()      );
    this->add_module( this->pauser         = new Pauser()        );

}