2020-06-18 03:02 AM
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?
2020-06-18 04:07 AM
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.
2020-06-18 10:36 AM
Something to do with newlib impure_ptr (reent management) ?
2020-06-19 12:57 PM
2020-06-23 07:02 AM
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?
2020-06-28 10:56 AM
"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.
2020-07-06 02:34 AM
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.