FreeRTOS SDK uxCriticalNesting[uxPsrId] == ~0UL Error



  • Hi, I'm in the process of porting/testing ESP_AT_Lib for use with external ESP8285/ESP8266 WiFi SoC with the K210. But unfortunately I'm running in to an issue where when a task is created to call various ESP_AT_Lib API for initialization I get the serial debug console error:

    E (612082966) FreeRTOS: (/home/user/kendryte/kendryte-freertos-sdk/lib/freertos/portable/port.c:143) uxCriticalNesting[uxPsrId] == ~0UL
    

    This seems to happen whenever I nest xTaskCreate() calls.
    I was able to create a workaround for now where if I initialize the ESP_AT_Lib from a function called from main() - it initializes properly without that error.

    It should be noted that the library once initialized also creates tasks under FreeRTOS to manage communications with WiFi chip - a nested xTaskCreate scenario.

    My use case looks like this:

    void init_wifi(void const* arg) {
    
        espr_t res;
    
        /* Initialize ESP with default callback function */
        printf("Initializing ESP-AT Lib\r\n");
        if (esp_init(esp_callback_func, 1) != espOK) {
            printf("Cannot initialize ESP-AT Lib!\r\n");
        } else {
            printf("ESP-AT Lib initialized!\r\n");
        }
    
        /*
         * Connect to access point.
         *
         * Try unlimited time until access point accepts up.
         * Check for station_manager.c to define preferred access points ESP should connect to
         */
    
         esp_sw_version_t v_min, v_curr;
    
         esp_get_min_at_fw_version(&v_min);
         esp_get_current_at_fw_version(&v_curr);
    
         printf("Minimum required AT version is: %d.%d.%d\r\n", (int)v_min.major, (int)v_min.minor, (int)v_min.patch);
         printf("Current AT version is: %d.%d.%d\r\n", (int)v_curr.major, (int)v_curr.minor, (int)v_curr.patch);
    
         espr_t err = connect_to_preferred_access_point(1);
         printf("Completed preferred connect\r\n");
    
         vTaskDelete(NULL);
       
    }
    
    void main() {
       ...
        xCreateTask(init_wifi,...);
       ...
    }
    

    If anyone has any insight or a solution that would be great.
    Thanks.



  • @sunnycase said in FreeRTOS SDK uxCriticalNesting[uxPsrId] == ~0UL Error:

    @loboris According to ISO/IEC 9899:1999

    5.1.2.2.3 Program termination
    If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;10)reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

    If you return from main, the program calls exit and terminates. You should not rely on the FreeRTOS SDK implementation details to assume the rest of the tasks will contiune to run.

    @sunnycase thanks for the clarification. Currently, I'm still running a loop at the end of main() with a vTaskDelay() to yield to other tasks inside the loop. But what I am seeing now after updating to the latest toolchain and develop branch of Kendryte-FreeRTOS-SDK is improved behavior where I can now successfully run wifi_init() task that then terminates correctly after initializing WiFi. But a subsequent call to vTaskCreate() to run MQTT task fails with uxCriticalNesting[uxPsrId] == ~0UL.


  • |  Mod

    @loboris According to ISO/IEC 9899:1999

    5.1.2.2.3 Program termination
    If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;10)reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

    If you return from main, the program calls exit and terminates. You should not rely on the FreeRTOS SDK implementation details to assume the rest of the tasks will contiune to run.



  • @loboris I've tested with toolchain v8.2.0-20190213 and the latest develop branch of Kendryte-FreeRTOS-SDK. I was able to get the init_wifi() task to now work but the subsequent task that performs MQTT comms gets the same uxCrtiticalNesting error. Running the MQTT task as a function call from main works fine.

    So updating definitely helped with the wifi_init task but there still is an underlying issue with creating tasks. Will investigate further on my end.



  • Hi @loboris good point - running a tight while loop at the end of main is wasteful. Usually I add a vTaskDelay() in the loop to yield to other tasks but still wastes cycles. I will update to the latest toolchain and SDK to see if the issue goes away. Thanks!



  • @sunnycase said in FreeRTOS SDK uxCriticalNesting[uxPsrId] == ~0UL Error:

    main function should not exit. Add while(1) or call block functions at the end of main to prevent exiting.

    Hi @sunnycase, I didn't include the remainder of the main.c code but it did have a loop at the end. The init_wifi() task only runs until it completes initialization and then terminates with vTaskDelete(NULL); to save resources.



  • @sunnycase said in FreeRTOS SDK uxCriticalNesting[uxPsrId] == ~0UL Error:

    main function should not exit. Add while(1) or call block functions at the end of main to prevent exiting.

    main function can exit, if you end it with vTaskDelete(NULL); and some other task(s) is(are) still running.
    I'm using dozens of tasks in my application, which also creates another tasks, and had no issues. It would make no sense leaving the loop at the end of main, wasting the processor time.
    You should use the latest develop branch of FreeRTOS-SDK and the latest Kendryte GNU Toolchain v8.2.0-20190213.
    I've also fixed couple of bugs in FreeRTOS tasks.c which may be causing this issue. I'll try to report them or make a PR when I'll find some time.


  • |  Mod

    main function should not exit. Add while(1) or call block functions at the end of main to prevent exiting.