wtodd wrote on Tuesday, July 09, 2019:
Can you please give me a line number (from the file I posted).
Line 666
If I understand you correctly here - that you are describing something
it is not valid to do. Normally scheduled windows threads cannot access
FreeRTOS scheduler operations, and Windows threads that are running
FreeRTOS tasks cannot make Windows system calls - the two are just not
compatible logically.
We call vPortGenerateSimulatedInterrupt from Windows threads, which I guess is not the intended use case, but like I say later on in my post, this works well with our fixes.
Perhaps it would be less confusing about what is allowed or not if there were some standard way of interacting between Windows and FreeRTOS threads. We’ve been using the following function for that purpose, with good results:
typedef struct
{
int32_t (*func)(void* arg);
void* arg;
int32_t result;
StaticSemaphore_t wait_buf;
SemaphoreHandle_t wait;
} sys_exec_state_t;
VOID CALLBACK sys_exec_func_cb(PTP_CALLBACK_INSTANCE instance, PVOID context)
{
sys_exec_state_t* state = (sys_exec_state_t*)context;
BaseType_t yield = pdFALSE;
// call the function
state->result = state->func(state->arg);
// tell the task that we're done
taskENTER_CRITICAL();
xSemaphoreGiveFromISR(state->wait, &yield);
if (yield == pdTRUE)
{
portYIELD();
}
taskEXIT_CRITICAL();
}
int32_t sys_exec_func(int32_t (*func)(void* arg), void* arg)
{
int32_t result = 0;
sys_exec_state_t state;
state.func = func;
state.arg = arg;
state.result = 0;
state.wait = xSemaphoreCreateBinaryStatic(&state.wait_buf);
BOOL submitted = FALSE;
taskENTER_CRITICAL();
submitted = TrySubmitThreadpoolCallback(sys_exec_func_cb, &state, NULL);
taskEXIT_CRITICAL();
if (submitted == TRUE)
{
xSemaphoreTake(state.wait, portMAX_DELAY);
result = state.result;
}
else
{
result = -EWOULDBLOCK;
}
vSemaphoreDelete(&state.wait);
return result;
}
This allows you to synchronously execute a function outside of the FreeRTOS context from a FreeRTOS task. For example we can safely do something like this:
typedef struct
{
const void* ptr;
size_t size_of_elements;
size_t number_of_elements;
FILE* file;
} fwrite_args_t;
int32_t do_fwrite(void* arg)
{
fwrite_args_t* args = (fwrite_args_t*)arg;
return fwrite(args->ptr, args->size_of_elements, args->number_of_elements, args->file);
}
int32_t safe_fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *file)
{
fwrite_args_t args;
args.ptr = ptr;
args.size_of_elements = size_of_elements;
args.number_of_elements = number_of_elements;
args.file = file;
return sys_exec_func(do_fwrite, &args);
}
void freertos_task(void* arg)
{
FILE* f;
uint8_t buffer[10];
// ...
safe_fwrite(buffer, 10, 1, f);
// ...
}