Пример #1
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();
}
Пример #2
0
/**
 * @brief System main loop called by the ETS
 *
 * This function is called by ETS after all initializations has been
 * finished to start periodic processing of defined ETS tasks. We
 * overwrite this ETS function to take over the control and to start RIOT.
 */
void ets_run(void)
{
    #if ENABLE_DEBUG
    register uint32_t *sp __asm__ ("a1");
    ets_uart_printf("_stack      %p\n", sp);
    ets_uart_printf("_bss_start  %p\n", &_bss_start);
    ets_uart_printf("_bss_end    %p\n", &_bss_end);
    ets_uart_printf("_heap_start %p\n", &_sheap);
    ets_uart_printf("_heap_end   %p\n", &_eheap);
    ets_uart_printf("_heap_free  %lu\n", get_free_heap_size());
    #endif

    /* init min task priority */
    ets_task_min_prio = 0;

    #ifdef MODULE_NEWLIB_SYSCALLS_DEFAULT
    _init();
    #endif

    ets_tasks_init();

    /* enable interrupts used by ETS/SDK */
    #ifndef MODULE_ESP_SDK_INT_HANDLING
    ets_isr_unmask(BIT(ETS_FRC2_INUM));
    ets_isr_unmask(BIT(ETS_WDEV_INUM));
    ets_isr_unmask(BIT(ETS_WDT_INUM));
    #endif

    #ifdef MODULE_ESP_GDBSTUB
    gdbstub_init();
    #endif

    #if ENABLE_DEBUG==0
    /* disable SDK messages */
    system_set_os_print(0);
    #endif

    #ifdef CONTEXT_SWITCH_BY_INT
    extern void IRAM thread_yield_isr(void* arg);
    ets_isr_attach(ETS_SOFT_INUM, thread_yield_isr, NULL);
    ets_isr_unmask(BIT(ETS_SOFT_INUM));
    #endif

    /* initialize dummy lwIP library to link it even if esp_wifi is not used */
    extern void esp_lwip_init(void);
    esp_lwip_init();

    thread_create(ets_task_stack, sizeof(ets_task_stack),
            ETS_TASK_PRIORITY,
            THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
            ets_task_func, NULL, "ets");


    /* does not return */
    kernel_init();
}
Пример #3
0
void IRAM NORETURN panic_arch(void)
{
    #if defined(DEVELHELP)
    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);
    ets_printf("                                                          \n");
    ets_printf("                                                          \n");
    #endif

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

    UNREACHABLE();
}
Пример #4
0
static int IRAM _send(netdev_t *netdev, const iolist_t *iolist)
{
    ESP_WIFI_DEBUG("%p %p", netdev, iolist);

    assert(netdev != NULL);
    assert(iolist != NULL);

    if (_in_send) {
        return 0;
    }
    _in_send = true;

    esp_wifi_netdev_t *dev = (esp_wifi_netdev_t*)netdev;

    critical_enter();
    if (dev->state != ESP_WIFI_CONNECTED) {
        ESP_WIFI_DEBUG("WiFi is still not connected to AP, cannot send");
        _in_send = false;
        critical_exit();
        return -EIO;
    }

    if (wifi_get_opmode() != ESP_WIFI_MODE) {
        ESP_WIFI_DEBUG("WiFi is not in correct mode, cannot send");
        _in_send = false;
        critical_exit();
        return -EIO;
    }

    const iolist_t *iol = iolist;
    size_t iol_len = 0;

    /* determine the frame size */
    while (iol) {
        iol_len += iol->iol_len;
        iol = iol->iol_next;
    }

    /* limit checks */
    if (iol_len > ETHERNET_MAX_LEN) {
        ESP_WIFI_DEBUG("frame length exceeds the maximum (%u > %u)",
                       iol_len, ETHERNET_MAX_LEN);
        _in_send = false;
        critical_exit();
        return -EBADMSG;
    }

    if (iol_len < sizeof(ethernet_hdr_t)) {
        ESP_WIFI_DEBUG("frame length is less than the size of an Ethernet"
                       "header (%u < %u)", iol_len, sizeof(ethernet_hdr_t));
        _in_send = false;
        critical_exit();
        return -EBADMSG;
    }

    struct netif *sta_netif = (struct netif *)eagle_lwip_getif(ESP_WIFI_STATION_IF);
    netif_set_default(sta_netif);

    struct pbuf *pb;

    if (get_free_heap_size() < ESP_WIFI_HEAP_MARGIN ||
        (pb = pbuf_alloc(PBUF_LINK, iol_len, PBUF_RAM)) == NULL ||
        (pb->tot_len < iol_len)) {
        ESP_WIFI_LOG_ERROR("could not allocate buffer to send %d bytes ", iol_len);
        /*
         * The memory of EPS8266 is quite small. Therefore, it may happen on
         * heavy network load that we run into out of memory and we have
         * to wait until lwIP pbuf has been flushed. We slow down sending a bit.
         */
        critical_exit();
        /* wait 20 ms */
        xtimer_usleep(20 * US_PER_MS);

        _in_send = false;
        return -EIO;
    }

    struct pbuf *pbi = pb;
    uint8_t *pbi_payload = pb->payload;
    size_t pbi_pos = 0;

    /* prepare lwIP packet buffer direct from iolist without any buffer */
    for (const iolist_t *iol = iolist; iol && pbi; iol = iol->iol_next) {
        uint8_t *iol_base = iol->iol_base;
        for (unsigned i = 0; i < iol->iol_len && pbi; i++) {
            pbi_payload[pbi_pos++] = iol_base[i];
            if (pbi_pos >= pbi->len) {
                pbi = pbi->next;
            }
        }
    }

#if ENABLE_DEBUG
    pbi = pb;
    pbi_pos = 0;

    for (; pbi; pbi = pbi->next) {
        memcpy(_send_pkt_buf + pbi_pos, pbi->payload, pbi->len);
        pbi_pos += pbi->len;
    }

    const ethernet_hdr_t* hdr = (const ethernet_hdr_t *)_send_pkt_buf;

    ESP_WIFI_DEBUG("send %u byte to " MAC_STR,
                   (unsigned)iol_len, MAC_STR_ARG(hdr->dst));
#if MODULE_OD
    od_hex_dump(_send_pkt_buf, iol_len, OD_WIDTH_DEFAULT);
#endif /* MODULE_OD */
#endif /* ENABLE_DEBUG */

    critical_exit();
    /* sta_netif->linkoutput = ieee80211_output_pbuf */
    err_t res = sta_netif->linkoutput(sta_netif, pb);
    pbuf_free(pb);

    if (res == ERR_OK) {
        /* There was no ieee80211_output_pbuf error and no send timeout. */
        netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
        _in_send = false;
        return iol_len;
    }
    else {
        /* There was either a ieee80211_output_pbuf error or send timed out. */
        _in_send = false;
        return -EIO;
    }
}
Пример #5
0
void print_meminfo (void)
{
    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);
}