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

Infinite Reboot loop in Constructor C++ #23998

Closed
hakkimakki opened this issue Apr 1, 2020 · 12 comments
Closed

Infinite Reboot loop in Constructor C++ #23998

hakkimakki opened this issue Apr 1, 2020 · 12 comments
Labels
area: C++ bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug

Comments

@hakkimakki
Copy link

hakkimakki commented Apr 1, 2020

Dear Zephyr Community

I discovered a stange behavior within the code in a C++ Constructor. The below initialisation works if it is placed outside the ctor in a seperate function. But if included in the ctor it ends up in an infinite reboot of zephyr.

class Radio
{
public:
	u8_t payload[254];			 // Containing Tx or Rx Payload
	u8_t len;					 // Length of actual Payload to send or Received
	Channel BLE_CH[40];			 // List of BLE Channels
	Channel IEEE802_15_4_CH[16]; // List of IEEE802.15.4 Channels
	// Init the Radio
	Radio()
	{
	          // Init the BLE Channels
		int freq = 2404;
		for (int i = 0; i <= 39; i++)
		{
			freq = freq + 2;
			if (i == 11)
			{
				freq = 2428;
			}
			else if (i == 37)
			{
				freq = 2402;
			}
			else if (i == 38)
			{
				freq = 2426;
			}
			else if (i == 39)
			{
				freq = 2480;
			}
			BLE_CH[i].freq = freq;
		}
		// Init the IEEE802.15.4 Channels		
		for (int k = 0; k <= 15; k++)
		{
			IEEE802_15_4_CH[k].freq = 2405 + k * 5;
		}
	}
}

The class is included in the main.cpp and after calling the constructor with:

Radio radio;

The nRF52840 keeps on rebooting infinitly:

*** Booting Zephyr OS build v2.1.99-ncs1-2-g30f47eace36c  ***
Started
*** Booting Zephyr OS build v2.1.99-ncs1-2-g30f47eace36c  ***
Started
*** Booting Zephyr OS build v2.1.99-ncs1-2-g30f47eace36c  ***
Started
........
........
........

Enviroment used for reproduction:

nRF52840 (PCA10056) Board
cmake version 3.16.2
arm-none-eabi-c++ (GNU Tools for Arm Embedded Processors 8-2019-q3-update) 8.3.1 2019070 (release) [gcc-8-branch revision 273027]

However if the critical code is included in a seperate function it works fine:

void initCHs(Radio radio)
{
	          // Init the BLE Channels
		int freq = 2404;
		for (int i = 0; i <= 39; i++)
		{
			freq = freq + 2;
			if (i == 11)
			{
				freq = 2428;
			}
			else if (i == 37)
			{
				freq = 2402;
			}
			else if (i == 38)
			{
				freq = 2426;
			}
			else if (i == 39)
			{
				freq = 2480;
			}
			radio.BLE_CH[i].freq = freq;
		}
		// Init the IEEE802.15.4 Channels		
		for (int k = 0; k <= 15; k++)
		{
			radio.IEEE802_15_4_CH[k].freq = 2405 + k * 5;
		}
}

void main(void)
{
	// Init
	printk("Started\n");

	Radio radio;

	initCHs(radio);

	//printk("RSSI: %d\n", radio.RSSI(0));
}

Could somebody help me with this behavoir if this is my fault or the fault of the Zephyr RTOS somehow.

Thanks a lot.

@hakkimakki hakkimakki added the bug The issue is a bug, or the PR is fixing a bug label Apr 1, 2020
@carlescufi
Copy link
Member

@hakkimakki could you enable CONFIG_ASSERT=y and run the test again?

@carlescufi
Copy link
Member

@vanwinkeljan do you have any suggestions here?

@carlescufi carlescufi added the priority: medium Medium impact/importance bug label Apr 7, 2020
@vanwinkeljan
Copy link
Member

@carlescufi Not really except to step through the code with gdb

Actually a complete prj.conf would be welcome, is the bug seen with newlibc or minallibc, ...

@hakkimakki
Copy link
Author

Thanks for your responses my proj.conf is:

CONFIG_SERIAL=y
CONFIG_NRFX_TIMER0=y
CONFIG_UART_0_NRF_UARTE=y
CONFIG_CONSOLE_HANDLER=y
CONFIG_SHELL=y
CONFIG_FLASH_SHELL=y
CONFIG_DYNAMIC_INTERRUPTS=y
CONFIG_ASSERT=y

CONFIG_NEWLIB_LIBC=y
CONFIG_CPLUSPLUS=y
CONFIG_LIB_CPLUSPLUS=y

@hakkimakki
Copy link
Author

hakkimakki commented Apr 8, 2020

However I just found the problem. The reboot loop is caused by the two variable declarations before the declaration of the array of objects (see code below). If the two other variables are commentet out the ctor works fine. This is my main.cpp file:

#include <string.h>
#include <zephyr.h>
#include <sys/printk.h>

class Channel
{
public:
	int freq = 2400;   // Frequency [Mhz]
	int Pnoise = 174;  // Noise [-dbm]
	int Psignal = 174; // Siganl [-dbm]
};

class Radio
{
public:
	// Comment these Variables out and it is working ---------------
	u8_t payload[254];			 // Containing Tx or Rx Payload
	u8_t len;					 // Length of actual Payload to send or Received
	// END Comment -----------------
	Channel BLE_CH[40];			 // List of BLE Channels
	Channel IEEE802_15_4_CH[16]; // List of IEEE802.15.4 Channels
	// Init the Radio
	Radio()
	{
		// ---------------- Not Working Code Start ------------------------
		// Init the BLE Channels
		for (int i = 0; i <= 10; i++)
		{
			BLE_CH[i].freq = 2404 + i * 2;
		}
		for (int i = 0; i <= 25; i++)
		{
			BLE_CH[i + 11].freq = 2428 + i * 2;
		}
		BLE_CH[37].freq = 2402;
		BLE_CH[38].freq = 2426;
		BLE_CH[39].freq = 2480;
		// Init the IEEE802.15.4 Channels
		for (int i = 0; i <= 15; i++)
		{
			IEEE802_15_4_CH[i].freq = 2405 + i * 5;
		}
		// ----------------- Not Working Code END --------------------------
	}
};


void main(void)
{
	// Init
	printk("Started\n");
	Radio radio;
}

@vanwinkeljan
Copy link
Member

vanwinkeljan commented Apr 8, 2020

Looks like a potential stack issue, could you create the object on the heap?

@hakkimakki
Copy link
Author

It looks like the object is allocated on the heap because i can step through the whole ctor just fine. However while leaving the main thread there is an assert failure.

I just figured out by enabling CONFIG_DEBUG=y resolves the issue aswell. So maybee its related to optimaziations (see: https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_DEBUG.html?highlight=config_debug#cmdoption-arg-config-debug)

@carlescufi
Copy link
Member

@hakkimakki if you think this is solved, please close the issue. If you need more information let us know.

@pabigot
Copy link
Collaborator

pabigot commented Apr 14, 2020

I can't reproduce this with either the referenced ARM-Embedded toolchain or the Zephyr 0.11.1. It may be specific to the NCS fork.

@hakkimakki
Copy link
Author

hakkimakki commented Apr 27, 2020

Sorry for the delay. I could create the object on the heap with and it worked fine:

Radio * radio = new Radio;

so @vanwinkeljan I guess you are right.

However I just setup a pure zephyr enviroment without the ncs fork and it looks like the same behavior. The code stucks after done and doesnt reboot like in the ncs fork (@pabigot) .

*** Booting Zephyr OS build zephyr-v2.2.0-1466-g1f3c014a1ad3  ***
Started
Done

however i could get along by changeing the ctor to not loop over for initializing the channels instead hard coding the channels.

For me its fine but the issue stays somewhere in the stack.

@pabigot
Copy link
Collaborator

pabigot commented Apr 27, 2020

I remain unable to reproduce this at the specified Zephyr commit and toolchains using nrf52840dk_nrf52840.

https://gist.github.com/pabigot/8057774cc407f5e7b6d04801c4c4743d contains the sample code, showing that the main routine continues after the object has been constructed, and confirms successful construction.

@hakkimakki
Copy link
Author

hakkimakki commented Apr 27, 2020

sorry I made a mistake by testing the code. The stuck mentoined above means that it worked. So it is the nRFConnect SDK fork causing this issue.

I will close this one. Thanks anyway guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: C++ bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug
Projects
None yet
Development

No branches or pull requests

4 participants