/**
 *
 * @brief Fatal error handler
 *
 * This routine implements the corrective action to be taken when the system
 * detects a fatal error.
 *
 * This sample implementation attempts to abort the current thread and allow
 * the system to continue executing, which may permit the system to continue
 * functioning with degraded capabilities.
 *
 * System designers may wish to enhance or substitute this sample
 * implementation to take other actions, such as logging error (or debug)
 * information to a persistent repository and/or rebooting the system.
 *
 * @param reason fatal error reason
 * @param pEsf pointer to exception stack frame
 *
 * @return This function does not return.
 */
void __weak z_SysFatalErrorHandler(unsigned int reason,
					 const NANO_ESF *pEsf)
{
	ARG_UNUSED(pEsf);

#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
#ifdef CONFIG_STACK_SENTINEL
	if (reason == _NANO_ERR_STACK_CHK_FAIL) {
		goto hang_system;
	}
#endif
	if (reason == _NANO_ERR_KERNEL_PANIC) {
		goto hang_system;
	}
	if (k_is_in_isr() || z_is_thread_essential()) {
		printk("Fatal fault in %s! Spinning...\n",
		       k_is_in_isr() ? "ISR" : "essential thread");
		goto hang_system;
	}
	printk("Fatal fault in thread %p! Aborting.\n", _current);
	k_thread_abort(_current);
	return;

hang_system:
#else
	ARG_UNUSED(reason);
#endif

	for (;;) {
		k_cpu_idle();
	}
	CODE_UNREACHABLE;
}
Esempio n. 2
0
int usb_dc_ep_write(const u8_t ep, const u8_t *const data,
		    const u32_t data_len, u32_t * const ret_bytes)
{
	struct usb_dc_stm32_ep_state *ep_state = usb_dc_stm32_get_ep_state(ep);
	HAL_StatusTypeDef status;
	u32_t len = data_len;
	int ret = 0;

	LOG_DBG("ep 0x%02x, len %u", ep, data_len);

	if (!ep_state || !EP_IS_IN(ep)) {
		LOG_ERR("invalid ep 0x%02x", ep);
		return -EINVAL;
	}

	ret = k_sem_take(&ep_state->write_sem, K_NO_WAIT);
	if (ret) {
		LOG_ERR("Unable to get write lock (%d)", ret);
		return -EAGAIN;
	}

	if (!k_is_in_isr()) {
		irq_disable(DT_USB_IRQ);
	}

	if (ep == EP0_IN && len > USB_MAX_CTRL_MPS) {
		len = USB_MAX_CTRL_MPS;
	}

	status = HAL_PCD_EP_Transmit(&usb_dc_stm32_state.pcd, ep,
				     (void *)data, len);
	if (status != HAL_OK) {
		LOG_ERR("HAL_PCD_EP_Transmit failed(0x%02x), %d", ep,
			(int)status);
		k_sem_give(&ep_state->write_sem);
		ret = -EIO;
	}

	if (!ret && ep == EP0_IN && len > 0) {
		/* Wait for an empty package as from the host.
		 * This also flushes the TX FIFO to the host.
		 */
		usb_dc_ep_start_read(ep, NULL, 0);
	}

	if (!k_is_in_isr()) {
		irq_enable(DT_USB_IRQ);
	}

	if (ret_bytes) {
		*ret_bytes = len;
	}

	return ret;
}
Esempio n. 3
0
/**
 *
 * @brief Test some context routines from a preemptible thread
 *
 * This routines tests the k_current_get() and
 * k_is_in_isr() routines from both a preemtible thread  and an ISR (that
 * interrupted a preemtible thread). Checking those routines with cooperative
 * threads are done elsewhere.
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_ctx_task(void)
{
	k_tid_t self_thread_id;

	TC_PRINT("Testing k_current_get() from an ISR and task\n");

	self_thread_id = k_current_get();
	isr_info.command = THREAD_SELF_CMD;
	isr_info.error = 0;
	/* isr_info is modified by the isr_handler routine */
	isr_handler_trigger();
	if (isr_info.error || isr_info.data != (void *)self_thread_id) {
		/*
		 * Either the ISR detected an error, or the ISR context ID
		 * does not match the interrupted task's thread ID.
		 */
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from an ISR\n");
	isr_info.command = EXEC_CTX_TYPE_CMD;
	isr_info.error = 0;
	isr_handler_trigger();
	if (isr_info.error || isr_info.value != K_ISR) {
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from a preemtible thread\n");
	if (k_is_in_isr() || _current->base.prio < 0) {
		return TC_FAIL;
	}

	return TC_PASS;
}
Esempio n. 4
0
/**
 *
 * @brief Handler to perform various actions from within an ISR context
 *
 * This routine is the ISR handler for isr_handler_trigger().  It performs
 * the command requested in <isr_info.command>.
 *
 * @return N/A
 */
static void isr_handler(void *data)
{
	ARG_UNUSED(data);

	switch (isr_info.command) {
	case THREAD_SELF_CMD:
		isr_info.data = (void *)k_current_get();
		break;

	case EXEC_CTX_TYPE_CMD:
		if (k_is_in_isr()) {
			isr_info.value = K_ISR;
			break;
		}

		if (_current->base.prio < 0) {
			isr_info.value = K_COOP_THREAD;
			break;
		}

		isr_info.value = K_PREEMPT_THREAD;

		break;

	default:
		isr_info.error = UNKNOWN_COMMAND;
		break;
	}
}
Esempio n. 5
0
int sys_execution_context_type_get(void)
{
	if (k_is_in_isr())
		return NANO_CTX_ISR;

	if (_current->base.prio < 0)
		return NANO_CTX_FIBER;

	return NANO_CTX_TASK;
}
Esempio n. 6
0
/**
 *
 * @brief Test some context routines from a preemptible thread
 *
 * This routines tests the k_current_get() and
 * k_is_in_isr() routines from both a preemtible thread  and an ISR (that
 * interrupted a preemtible thread). Checking those routines with cooperative
 * threads are done elsewhere.
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_ctx_task(void)
{
	k_tid_t self_thread_id;

	TC_PRINT("Testing k_current_get() from an ISR and task\n");

	self_thread_id = k_current_get();
	isr_info.command = THREAD_SELF_CMD;
	isr_info.error = 0;
	/* isr_info is modified by the isr_handler routine */
	isr_handler_trigger();

	if (isr_info.error) {
		TC_ERROR("ISR detected an error\n");
		return TC_FAIL;
	}

	if (isr_info.data != (void *)self_thread_id) {
		TC_ERROR("ISR context ID mismatch\n");
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from an ISR\n");
	isr_info.command = EXEC_CTX_TYPE_CMD;
	isr_info.error = 0;
	isr_handler_trigger();

	if (isr_info.error) {
		TC_ERROR("ISR detected an error\n");
		return TC_FAIL;
	}

	if (isr_info.value != K_ISR) {
		TC_ERROR("isr_info.value was not K_ISR\n");
		return TC_FAIL;
	}

	TC_PRINT("Testing k_is_in_isr() from a preemptible thread\n");
	if (k_is_in_isr()) {
		TC_ERROR("Should not be in ISR context\n");
		return TC_FAIL;
	}
	if (_current->base.prio < 0) {
		TC_ERROR("Current thread should have preemptible priority\n");
		return TC_FAIL;
	}

	return TC_PASS;
}
Esempio n. 7
0
/**
 *
 * @brief Test the various context/thread routines from a cooperative thread
 *
 * This routines tests the k_current_get and
 * k_is_in_isr() routines from both a thread and an ISR (that interrupted a
 * cooperative thread).  Checking those routines with preemptible threads are
 * done elsewhere.
 *
 * This routine may set <thread_detected_error> to the following values:
 *   1 - if thread ID matches that of the task
 *   2 - if thread ID taken during ISR does not match that of the thread
 *   3 - k_is_in_isr() when called from an ISR is false
 *   4 - k_is_in_isr() when called from a thread is true
 *   5 - if thread is not a cooperative thread
 *
 * @return TC_PASS on success
 * @return TC_FAIL on failure
 */
static int test_kernel_thread(k_tid_t task_thread_id)
{
	k_tid_t self_thread_id;

	self_thread_id = k_current_get();
	if (self_thread_id == task_thread_id) {
		thread_detected_error = 1;
		return TC_FAIL;
	}

	isr_info.command = THREAD_SELF_CMD;
	isr_info.error = 0;
	isr_handler_trigger();
	if (isr_info.error || isr_info.data != (void *)self_thread_id) {
		/*
		 * Either the ISR detected an error, or the ISR context ID
		 * does not match the interrupted thread's thread ID.
		 */
		thread_detected_error = 2;
		return TC_FAIL;
	}

	isr_info.command = EXEC_CTX_TYPE_CMD;
	isr_info.error = 0;
	isr_handler_trigger();
	if (isr_info.error || (isr_info.value != K_ISR)) {
		thread_detected_error = 3;
		return TC_FAIL;
	}

	if (k_is_in_isr()) {
		thread_detected_error = 4;
		return TC_FAIL;
	}

	if (_current->base.prio >= 0) {
		thread_detected_error = 5;
		return TC_FAIL;
	}

	return TC_PASS;
}