2020-06-18 3: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 4: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 7: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 2: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.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.