Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atmega based boards freeze when main thread is over #6526

Closed
kYc0o opened this issue Jan 31, 2017 · 21 comments
Closed

atmega based boards freeze when main thread is over #6526

kYc0o opened this issue Jan 31, 2017 · 21 comments
Assignees
Labels
Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Comments

@kYc0o
Copy link
Contributor

kYc0o commented Jan 31, 2017

While testing gnrc_minimal with arduino-mega2560 + XBee, the board seems to freeze when the main thread is over, as the examples behaves. However, if an infinite loop is used to avoid the thread to finish, the board doesn't freeze and it answers to pings.

I think it's related to the way threading works on this platform, maybe only task switching, but I didn't investigate further.

@kYc0o kYc0o added Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) labels Jan 31, 2017
@smlng
Copy link
Member

smlng commented Mar 6, 2017

@kYc0o I doubt this is a bug. I mean the main of gnrc_minimal states:


    /* main thread exits */
    return 0;

So I'd say this is not a problem in general, I understand (and checked) that other platforms do not stop answering pings after main thread completes. But then, whats the use of that? If main (and any other thread) are done, the node wouldn't do anything anymore.

@OlegHahm
Copy link
Member

OlegHahm commented Mar 6, 2017

Not sure I understand your point, but in GNRC the main thread is not responsible for responding to ICMP echo requests. Hence, it should reply with pongs whether the main thread terminates or not.

P.S. remember the main thread has no particular role or function in RIOT, except that it serves as an entry point.

@smlng
Copy link
Member

smlng commented Mar 9, 2017

I don't have an xbee shield available. However, I ran tests/thread_msg on board arduino duemilanove and changed the loop to run 100 times (instead of 3). In this tests 3 threads are created by main and exchange messages for some time (i.e., 100x). The point is main exits after creating the 3 threads, but the threads run - so it does not freeze. So the cause is not that main is over.

Maybe if every thread is done it finally freezes, but then: whats the problem with that --other than its different to other platforms? However again: if the app (and all it threads) terminates, what use does it have to answer pings? Typically an IoT app will have some infinite loop driving the system, hence the problem should not arise?

@smlng
Copy link
Member

smlng commented Mar 9, 2017

I also added a xtimer_sleep(3) in thread1 forcing the system to go into idle thread. I observed a problem with power management on cc2538 recently, which wasn't able to get out of idle after a sleep, I thought this might be a problem here, too -- however, the tests suggests it is not the case here.

@smlng
Copy link
Member

smlng commented Mar 9, 2017

so basically that agrees with @OlegHahm, stating:

remember the main thread has no particular role or function in RIOT

So either there is no interrupt from the network device/driver or something blocks the system from handling such interrupt and switch to the network threads responsible to answer pings.

@kYc0o
Copy link
Contributor Author

kYc0o commented Mar 9, 2017

However it doesn't explain why adding an infinite loop at the end keeps the board alive...

@smlng
Copy link
Member

smlng commented Mar 9, 2017

what do you do in your infinite loop? What happens if you add (if not already done that way) something like xtimer_sleep(0xFFFF) instead at the end of main? Basically sleep very long ...

@smlng
Copy link
Member

smlng commented Mar 9, 2017

and can you share your application code?

@kYc0o
Copy link
Contributor Author

kYc0o commented Mar 9, 2017

Well the application is basically the gnrc_minimal example:

int main(void)
{
    kernel_pid_t ifs[GNRC_NETIF_NUMOF];

    puts("RIOT network stack example application");

    /* get the first IPv6 interface and prints its address */
    size_t numof = gnrc_netif_get(ifs);
    if (numof > 0) {
        gnrc_ipv6_netif_t *entry = gnrc_ipv6_netif_get(ifs[0]);
        for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
            if ((ipv6_addr_is_link_local(&entry->addrs[i].addr)) && !(entry->addrs[i].flags & GNRC_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST)) {
                char ipv6_addr[IPV6_ADDR_MAX_STR_LEN];
                ipv6_addr_to_str(ipv6_addr, &entry->addrs[i].addr, IPV6_ADDR_MAX_STR_LEN);
                printf("My address is %s\n", ipv6_addr);
            }
        }
    }

    while(1);

    /* main thread exits */
    return 0;
}

@smlng
Copy link
Member

smlng commented Mar 9, 2017

ah okay, simple while(1); - what about xtimer_sleep instead?

@smlng
Copy link
Member

smlng commented Mar 9, 2017

what helped me in solving #6419 in #6692 was to enable debug output in core/sched.c. Please try this, too - and post the output here, that way we should see which thread is schedules last and where it hangs ...

@smlng
Copy link
Member

smlng commented Mar 9, 2017

without your infinite loop, that is!a

@kaspar030
Copy link
Contributor

@kYc0o Please check if main uses too much stack.

@kaspar030
Copy link
Contributor

@kYc0o Please check if main uses too much stack.

The idle thread's stack is defined right after the main thread's stack, in core/kernel_init.h. So if the main thread overuses it's stack, it overwrites the idle thread's stack space. That will most probably lead to immediate mess-up when jumping to the idle thread.

@smlng
Copy link
Member

smlng commented Mar 9, 2017

default stack size is 256B for atmegas, so @kaspar030 could be right, that main stack is smallish. The mega2560 has 8K, gnrc_minimal require something less than 3K (at least thats what my compiler says) so you could enlarge stack size for main by adding to the Makefile:

CFLAGS += -DTHREAD_STACKSIZE_MAIN=1024

@kYc0o
Copy link
Contributor Author

kYc0o commented Mar 9, 2017

Well I tested with different stack sizes and the problem persists. I'll take a look to the scheduler to see if something gets wrong there.

@kaspar030
Copy link
Contributor

I tested with different stack sizes and the problem persists.

Which ones did you test?

@kYc0o
Copy link
Contributor Author

kYc0o commented Mar 9, 2017

512 and 1024 for now. You think I should increase more?

@ZetaR60
Copy link
Contributor

ZetaR60 commented Apr 10, 2018

@kYc0o Please try #8904 if you get a chance. I had a similar problem in #8842 that I think is caused by #8896.

@ZetaR60
Copy link
Contributor

ZetaR60 commented May 7, 2018

@kYc0o Please retest now that #8904 has been merged. Other very similar problems have been fixed by #8904, like #9058 for instance.

@kYc0o
Copy link
Contributor Author

kYc0o commented May 11, 2018

@ZetaR60 your PRs solved this part of the problem, closing.

@kYc0o kYc0o closed this as completed May 11, 2018
@cladmi cladmi added this to the Release 2018.07 milestone Jul 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

No branches or pull requests

7 participants