This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RTX tiny and radio interrupt of NRF24LE1

Hello to everyone.
I write code for NRF24LE1 using KEIL and rtx tiny. But i have some problems.

When i first create a task and run it, everythink looks good but when i delete it and then created again the task start runs but when call a radio func with radio interrupt never return.

The problem is that i delete the task and then created again maybe but why........;

thanks.

  • It's rather hard to debug source code you aren't allowed to see, given that most people can't even debug their own code they just wrote...

    Does the thread own any locks or other resources when you delete it?

  • Here is my code, the problem is is func "RF_GATEWAYTxString (msgpayload)" , when SUPERVISOR runs and delete and then create FIND_NRF_DEVICES, the func RF_GATEWAYTxString (msgpayload) never returns. And here is all my project
    drive.google.com/folderview
    thanks for answer.

    void find_nrf_devices ()  _task_ FIND_NRF_DEVICES  {
    
            xdata int id=100;
            xdata int i=0;
            UART_TxString("i START NRF FINDING");
      radio_enable ();                                                                      /*RFCKEN = 1U(Enable the radio clock),RF = 1U(Enable RF interrupt)*/
            os_wait (K_TMO, 100, 0);          /* wait for timeout: 100 ticks ~ 1sec   */
            os_wait (K_TMO, 100, 0);          /* wait for timeout: 100 ticks ~ 1sec   */
            os_wait (K_TMO, 100, 0);          /* wait for timeout: 100 ticks ~ 1sec   */
    
                                    do
                                    {
                                    sprintf(msgpayload,"N%d                         \r\n",id);
                                    msgpayload[31]='\0';
                                    UART_TxString(msgpayload);
                                    if (RF_GATEWAYTxString (msgpayload)==1)
                                    {
                                            sprintf(uarttxbuffer,"ndevice N%d joined\r\n",id);
                                            UART_TxString(uarttxbuffer);
                                            ndevices_map [i]='1';
                                            os_wait (K_TMO, 100, 0);          /* wait for timeout: 1000 ticks ~ 1sec   */
                                    }
                                    else
                                    {
                                            sprintf(uarttxbuffer,"ndevice N%d out of range or closed\r\n",id);
                                            UART_TxString(uarttxbuffer);
                                            delay_ms(60);
                                            ndevices_map [i]='0';
                                    }
                                    id++;
                                    i++;
                            }while (id<110);
    
                            UART_TxString("i CREATE SUPERVISOR");
                            os_create_task (SUPERVISOR);
                            UART_TxString("ndevices_map\r\n");
                            UART_TxString(ndevices_map);
                            UART_TxString("\r\n");
    
                            UART_TxString(memset(ndevices_map, '0', 100));
                            UART_TxString("\r\n");
                            os_send_signal(SUPERVISOR);
                            while(1)
                            {
                                    if (RF_GATEWAYRxString (msgpayload)==1 )
                                    {
                                            UART_TxString(msgpayload);
                                    }
                                    else
                                    {
                                            sprintf(uarttxbuffer,"ndevice N%d out of range or closed\r\n",id);
                                            UART_TxString(uarttxbuffer);
                                    }
    
                            }
    
    
    }
    
    
    void supervisor () _task_ SUPERVISOR  {
            while(1){
                    os_wait (K_SIG, 0, 0);          /* RTX-51 call: wait for signal         */
                    UART_TxString("i receive signal");
                    os_wait (K_TMO, 100, 0);          /* wait for timeout: 1000 ticks ~ 1sec   */
                    os_delete_task (FIND_NRF_DEVICES);\ 
                    os_wait (K_TMO, 100, 0);          /* wait for timeout: 1000 ticks ~ 1sec   */
                    os_create_task (FIND_NRF_DEVICES);/* create task FIND_NRF_DEVICES to find all powered on devices        */
                    while(1)
                    os_delete_task (os_running_task_id ());
            }
    }
    

  • Are you aware that in good software design, you should basically never delete a thread? You don't need the thread anymore, you let the thread end itself instead of having someone else kill it while the thread is in a random, unknown, state.

    Think about a trivial piece of code like:

        char *s = malloc(buf);
        do_something();
        free(s);
    

    What would happen if the above sequence is part of a thread, and someone kills the thread after malloc() has allocate a block of memory, but before free() has released it? You think the memory will ever be reclaimed?

    So maybe you don't use dynamic memory? But you are most likely using other resoures that has alloc/free, lock/unlock, inc/dec, open/close, ... behavior and where it is important to match the two operations to not create some form of leak.

    If your software works so badly, that a supervisor needs to kill a thread, then it's time to consider a full reboot. And debugging/rewriting to solve the issues the supervisor noticed.

    So - what are the exit requirements for your receive function? That should give you some indication why it might fail to return. Maybe it fails to return because it is waiting for a resource that is already locked by a thread you have already killed - then there are no thread in existence that will release that resource so your function will never manage to claim it.

    In the end - how are your calls to os_delete_task() taking into account all possible state changes of the state machine(s) that is formed by your program? How do you prove that you always move from one valid state into another valid state when you kill a task?

  • Your answer is a very big lesson for me!Special thanks from me i
    was really confused! have a nice day............