Пример #1
0
/*
 * xtos low level exception handler (in rom)
 * populates an xtos_regs structure with (most) registers
 * present at the time of the exception and passes it to the
 * high-level handler.
 *
 * Note that the a1 (sp) register is clobbered (bug? necessity?),
 * however the original stack pointer can be inferred from the address
 * of the saved registers area, since the exception handler uses the same
 * user stack. This might be different in other execution modes on the
 * quite variegated xtensa platform family, but that's how it works on ESP8266.
 */
IRAM NOINSTR void esp_exception_handler(struct xtensa_stack_frame *frame) {
  uint32_t cause = RSR(EXCCAUSE);
  uint32_t vaddr = RSR(EXCVADDR);
  fprintf(stderr, "\nTrap %d: pc=%p va=%p\n", cause, (void *) frame->pc,
          (void *) vaddr);
  memcpy(&regs.a[2], frame->a, sizeof(frame->a));

  regs.a[0] = frame->a0;
  regs.a[1] = (uint32_t) frame + ESP_EXC_SP_OFFSET;
  regs.pc = frame->pc;
  regs.sar = frame->sar;
  regs.ps = frame->ps;
  regs.litbase = RSR(LITBASE);

  handle_exception(&regs);

  fprintf(stderr, "rebooting\n");
  fs_flush_stderr();

  /*
   * Documented `system_restart` does a lot of things (cleanup) which (seems)
   * cannot be done from exc handler and only after cleanup it calls
   * `system_restart_local`.
   */
  system_restart_local();
}
Пример #2
0
void IRAM NORETURN exception_handler (void *arg)
{
    (void)arg;
    uint32_t excsave1;
    uint32_t excvaddr;
    uint32_t exccause;
    RSR(excsave1, excsave1);
    RSR(excvaddr, excvaddr);
    RSR(exccause, exccause);
    (void)exception_names;

    ets_printf("EXCEPTION!! exccause=%d (%s) @%08lx excvaddr=%08lx\n",
               exccause, exception_names[exccause],
               excsave1, excvaddr);

    #if defined(DEVELHELP)
    #if defined(MODULE_PS)
    ps();
    #endif
    struct mallinfo minfo = mallinfo();
    ets_printf("heap: %lu (free %lu) byte\n", &_eheap - &_sheap, get_free_heap_size());
    ets_printf("sysmem: %d (used %d, free %d)\n", minfo.arena, minfo.uordblks, minfo.fordblks);
    #endif
    /* flushing the buffer */
    ets_printf("                                                          \n");
    ets_printf("                                                          \n");
    ets_printf("                                                          \n");

    /* hard reset */
    __asm__ volatile (" call0 0x40000080 ");

    UNREACHABLE();
}
Пример #3
0
/* Dump exception information from special function registers */
static void dump_excinfo(void) {
    uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1;
    uint32_t excinfo[8];

    RSR(exccause, exccause);
    printf("Fatal exception (%d): \n", (int)exccause);
    RSR(epc1, epc1);
    RSR(epc2, epc2);
    RSR(epc3, epc3);
    RSR(excvaddr, excvaddr);
    RSR(depc, depc);
    RSR(excsave1, excsave1);
    printf("%s=0x%08x\n", "epc1", epc1);
    printf("%s=0x%08x\n", "epc2", epc2);
    printf("%s=0x%08x\n", "epc3", epc3);
    printf("%s=0x%08x\n", "excvaddr", excvaddr);
    printf("%s=0x%08x\n", "depc", depc);
    printf("%s=0x%08x\n", "excsave1", excsave1);
    sdk_system_rtc_mem_read(0, excinfo, 32); // Why?
    excinfo[0] = 2;
    excinfo[1] = exccause;
    excinfo[2] = epc1;
    excinfo[3] = epc2;
    excinfo[4] = epc3;
    excinfo[5] = excvaddr;
    excinfo[6] = depc;
    excinfo[7] = excsave1;
    sdk_system_rtc_mem_write(0, excinfo, 32);
}
Пример #4
0
static void unity_run_single_test_by_index_parse(const char* filter, int index_max)
{
    if (s_invert)
    {
        printf("Inverse is not supported for that kind of filter\n");
        return;
    }
    int test_index = strtol(filter, NULL, 10);
    if (test_index >= 1 && test_index <= index_max)
    {
        uint32_t start;
        RSR(CCOUNT, start);
        unity_run_single_test_by_index(test_index - 1);
        uint32_t end;
        RSR(CCOUNT, end);
        uint32_t ms = (end - start) / (XT_CLOCK_FREQ / 1000);
        printf("Test ran in %dms\n", ms);
    }
}
Пример #5
0
/* Dump normal registers that were stored above 'sp'
   by the exception handler preamble
*/
void dump_registers_in_exception_handler(uint32_t *sp) {
    uint32_t excsave1;
    uint32_t *saved = sp - (0x50 / sizeof(uint32_t));
    printf("Registers:\n");
    RSR(excsave1, excsave1);
    printf("a0 %08x ", excsave1);
    printf("a1 %08x ", (intptr_t)sp);
    for(int a = 2; a < 14; a++) {
        printf("a%-2d %08x%c", a, saved[a+3], a == 3 || a == 7 || a == 11 ? '\n':' ');
    }
    printf("SAR %08x\n", saved[0x13]);
}
Пример #6
0
void pp_soft_wdt_feed_local()
{
	struct rst_info rst_info;
	rst_info.exccause = RSR(EXCCAUSE);
	rst_info.epc1 = RSR(EPC1);
	rst_info.epc2 = RSR(EPC2);
	rst_info.epc3 = RSR(EPC3);
	rst_info.excvaddr = RSR(EXCVADDR);
	rst_info.depc = RSR(DEPC);
	if(wdt_flg == true) {
		rst_info.reason = REASON_SOFT_WDT_RST; // =3
		system_rtc_mem_write(0, &rst_info, sizeof(rst_info));
		ets_intr_lock();
		Wait_SPI_Idle(flashchip);
		Cache_Read_Enable_New();
		system_restart_local();
	}
	else {
		rst_info.reason = REASON_WDT_RST; // =1
		system_rtc_mem_write(0, &rst_info, sizeof(rst_info));
#if DEF_SDK_VERSION >= 1119
		wDev_MacTim1Arm(soft_wdt_interval);
#else
		ets_timer_disarm(SoftWdtTimer);
		ets_timer_arm_new(SoftWdtTimer, soft_wdt_interval, 0, 1);
#endif
		wdt_flg = true;
		pp_post(12);
	}
}
Пример #7
0
void pp_soft_wdt_feed()
{
	struct rst_info rst_info;
	rst_info.exccause = RSR(EXCCAUSE);
	rst_info.epc1 = RSR(EPC1);
	rst_info.epc2 = RSR(EPC2);
	rst_info.epc3 = RSR(EPC3);
	rst_info.excvaddr = RSR(EXCVADDR);
	rst_info.depc = RSR(DEPC);
	rst_info.reason = WDT_RST_FLAG;
	system_rtc_mem_write(0, &rst_info, sizeof(rst_info));
	if(wdt_flg == true) {
		Cache_Read_Disable();
		Cache_Read_Enable_New();
		system_restart_local();
	}
	else {
#if SDK_VERSION >= 1119
		wDev_MacTim1Arm(soft_wdt_interval);
#else
		ets_timer_disarm(SoftWdtTimer);
		ets_timer_arm_new(SoftWdtTimer, soft_wdt_interval, 0, 1);
#endif
		wdt_flg = true;
		pp_post(12);
	}
}
Пример #8
0
/* Task:
   - Waits for 'trigger' variable to be set
   - Reads the cycle count on this CPU
   - Pushes it into a queue supplied as a param
   - Busy-waits until the main task terminates it
*/
static void task_send_to_queue(void *param)
{
    QueueHandle_t queue = (QueueHandle_t) param;
    uint32_t ccount;

    while(!trigger) {}

    RSR(CCOUNT, ccount);
    flag = true;
    xQueueSendToBack(queue, &ccount, 0);
    /* This is to ensure that higher priority task
       won't wake anyhow, due to this task terminating.

       The task runs until terminated by the main task.
    */
    while(1) {}
}
Пример #9
0
void store_exception_error(uint32_t errn)
{
		uint32_t *ptr = (uint32_t *)(RTC_MEM_BASE);
			*ptr++ = errn;
			*ptr++ = RSR(EXCCAUSE);
			*ptr++ = RSR(EPC1);
			*ptr++ = RSR(EPC2);
			*ptr++ = RSR(EPC3);
			*ptr++ = RSR(EXCVADDR);
			*ptr++ = RSR(DEPC);
		if(errn > RST_EVENT_WDT) _ResetVector();
}
Пример #10
0
void unity_exec_time_stop(void)
{
    RSR(CCOUNT, s_test_stop);
}
Пример #11
0
void unity_exec_time_start(void)
{
    RSR(CCOUNT, s_test_start);
}