pppos_client example hangs when I loop it
Posted: Thu Apr 23, 2020 1:40 pm
I am trying to use a sim800 circuit and am fooling around with the pppos example. I am using esp-idf 4.0.
The example works fine, but when I add a loop to take down and up the PPP connection it freezes waiting for a semaphore in tcpip.c.
What I've done:
Started a new project with the visualgdb wizard in Visual Studio
Setup correct APN, TXD and RXD pin in example configuration.
Tested the base project without any changes, works fine.
Modified app_main() in pppos_client_main.c thusly:
This ought to init ppp, do stuff, close ppp again and again.
On the second loop it freezes waitning for a semaphore in tcpip_api_call(), this specific line:
If I modify the timeout 0 to 10000 it timeouts and continues and on every following loop the code works as I envisioned it would, it does not get stuck on that semaphore on laps 1 and 3-eternity.
This seems to be because the TCP/IP stack is not in the expected location on the second lap. It is itself already stuck on that semaphore. Stepping through the code it seems like the TCP/IP stack normally waits for an mbox, sent by tcpip_api_call I presume, but somehow it gets "out of sync" on lap 2 in the loop.
It seems to get out of sync in esp_modem_exit_ppp() inbetween the following two lines:
I've tried all my 1337 ninja skills on finding clues as to why, but I have been unsuccessful. Anyone else recognize this?
The example works fine, but when I add a loop to take down and up the PPP connection it freezes waiting for a semaphore in tcpip.c.
What I've done:
Started a new project with the visualgdb wizard in Visual Studio
Setup correct APN, TXD and RXD pin in example configuration.
Tested the base project without any changes, works fine.
Modified app_main() in pppos_client_main.c thusly:
- ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, NULL));
- /* create dce object */
- #if CONFIG_EXAMPLE_MODEM_DEVICE_SIM800
- modem_dce_t *dce = sim800_init(dte);
- #elif CONFIG_EXAMPLE_MODEM_DEVICE_BG96
- modem_dce_t *dce = bg96_init(dte);
- #else
- #error "Unsupported DCE"
- #endif
- ESP_ERROR_CHECK(dce->set_flow_ctrl(dce, MODEM_FLOW_CONTROL_NONE));
- ESP_ERROR_CHECK(dce->store_profile(dce));
- while (1)
- {
- /* Print Module ID, Operator, IMEI, IMSI */
- ESP_LOGI(TAG, "Module: %s", dce->name);
- ESP_LOGI(TAG, "Operator: %s", dce->oper);
- ESP_LOGI(TAG, "IMEI: %s", dce->imei);
- ESP_LOGI(TAG, "IMSI: %s", dce->imsi);
- /* Get signal quality */
- uint32_t rssi = 0, ber = 0;
- ESP_ERROR_CHECK(dce->get_signal_quality(dce, &rssi, &ber));
- ESP_LOGI(TAG, "rssi: %d, ber: %d", rssi, ber);
- /* Get battery voltage */
- uint32_t voltage = 0, bcs = 0, bcl = 0;
- ESP_ERROR_CHECK(dce->get_battery_status(dce, &bcs, &bcl, &voltage));
- ESP_LOGI(TAG, "Battery voltage: %d mV", voltage);
- /* Setup PPP environment */
- esp_modem_setup_ppp(dte);
- /* Wait for IP address */
- xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- /* Config MQTT */
- esp_mqtt_client_config_t mqtt_config = {
- .uri = BROKER_URL,
- .event_handle = mqtt_event_handler,
- };
- esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config);
- esp_mqtt_client_start(mqtt_client);
- xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- esp_mqtt_client_destroy(mqtt_client);
- /* Exit PPP mode */
- ESP_ERROR_CHECK(esp_modem_exit_ppp(dte));
- xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- #if CONFIG_EXAMPLE_SEND_MSG
- const char *message = "Welcome to ESP32!";
- ESP_ERROR_CHECK(example_send_message_text(dce, CONFIG_EXAMPLE_SEND_MSG_PEER_PHONE_NUMBER, message));
- ESP_LOGI(TAG, "Send send message [%s] ok", message);
- #endif
- }
- /* Power down module */
- ESP_ERROR_CHECK(dce->power_down(dce));
On the second loop it freezes waitning for a semaphore in tcpip_api_call(), this specific line:
Code: Select all
sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
This seems to be because the TCP/IP stack is not in the expected location on the second lap. It is itself already stuck on that semaphore. Stepping through the code it seems like the TCP/IP stack normally waits for an mbox, sent by tcpip_api_call I presume, but somehow it gets "out of sync" on lap 2 in the loop.
It seems to get out of sync in esp_modem_exit_ppp() inbetween the following two lines:
Code: Select all
MODEM_CHECK(dte->change_mode(dte, MODEM_COMMAND_MODE) == ESP_OK, "enter command mode failed", err);
/* Hang up */
MODEM_CHECK(dce->hang_up(dce) == ESP_OK, "hang up failed", err);