Skip to main content
Explorer
June 18, 2020
Question

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

  • June 18, 2020
  • 6 replies
  • 5347 views

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?

    This topic has been closed for replies.

    6 replies

    SSton.1Author
    Explorer
    June 18, 2020

    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.

    Explorer II
    June 18, 2020

    Something to do with newlib impure_ptr (reent management) ?

    Graduate II
    June 19, 2020
    SSton.1Author
    Explorer
    June 23, 2020

    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?

    Explorer II
    June 28, 2020

    "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.1Author
    Explorer
    July 6, 2020

    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.