cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G071 - Problem with rand() and random() functions always returning 0 in a FreeRTOS thread but OK in main().

SSton.1
Associate III

I have an STM32G071 running FreeRTOS CMSIS v2 compiled with STM32CubeIDE. In one of the threads I want to generate a pseudo-random number. (I don't need anything sophisticated and the STM32G071 doesn't have an RNG anyway; pseudo random is absolutely fine for my purposes).

The code snippets show calls to srandom() and random() but the results were identical with srand() and rand() too.

If I call rand() or random() from anywhere in main() before I call osKernelStart(), all is well:

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	osKernelInitialize();	// Init scheduler
 
	/* random number test  - this works */
	uint32_t x = 0;
	srandom(12345);
	x = random();        // returns a random number
 
	osKernelStart();		// Start scheduler
	
	/* We should never get here as control is now taken by the scheduler */
	/* Infinite loop */
	while (1)
	{
	}
 }

But if I call rand() or random() anywhere in a thread, it always returns 0 (even if I call srand() or srandom() with a seed immediately beforehand). Clearly, I wouldn't call srandom() each time, I'm just showing that it isn't making any difference here:

void my_thread (void *argument)
{
	UNUSED (argument);
	
	/* random number test - this fails */
	uint32_t x;
	srandom(12335);
	x = random();	// always returns 0 for any seed
 
 
	/* Infinite loop */
	for (;;)
	{
		osDelay(10;)
	}
} 

It doesn't make any difference whether the call to rand() or random() in the thread is before the infinite while loop or during it, same result.

I know that srand() and srandom() aren't re-entrant but if I'm only calling them from one point in one thread it shouldn't matter as the thread itself isn't re-entrant.

Does anyone know what the problem is?

6 REPLIES 6
SSton.1
Associate III

Update:

I can call rand() or random() in a thread if I call srand(), srandom(), rand() or random() from main first.

As far as I can tell, it doesn't matter which function so long as something calls one of those functions before attempting to call it from a thread.

That just seems weird.

Nikita91
Lead II

Something to do with newlib impure_ptr (reent management) ?

Piranha
Chief II
SSton.1
Associate III

It seems to have been cured by deleting sysmem.c which is generated by STM32CubeIDE so I think you're both on the right lines.

Occasionally (but not always) STM32CubeIDE re-creates sysmem.c - is there a way to stop it doing this?

TThan
Associate III

"is there a way to stop it doing this?"

Maybe it is better to let STM32CubeMX re-create the file and just disable it from compiliing?

This is how I manage it. A right-click on the sysmem.c in the project-explorer and then "Resource Configurations -> Exclude from Build" should do the trick.

SSton.1
Associate III

Update for future reference: I think it was finger trouble when I thought that regenerating code from the .ioc file was re-creating the 'sysmem.c' file. I have several projects in my workspace and I was looking at the wrong one.

Deleting 'sysmem.c' from the project after it is created for the first time seems to be the right answer.