Hello ,
I would like to test creating FreeRTOS tasks in embedded swift.
I found the wrapper below that should run in Swift. However, String is not available in embedded swift.
Any help will be welcome.

BaseType_t xTaskCreateWrapper(TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask);

// SWIFT
//import Foundation

func createTask(taskCode: @escaping @convention(c) (UnsafeMutableRawPointer?) -> Void, name: String, stackDepth: UInt16, parameters: UnsafeMutableRawPointer?, priority: UInt32, taskHandle: UnsafeMutablePointer<TaskHandle_t?>) -> BaseType_t {
return xTaskCreateWrapper(taskCode, name, stackDepth, parameters, priority, taskHandle)
}

2 Likes

You might not actually need String for this particular scenario. If you define name as UnsafePointer<CChar>, i.e.

func createTask(name: UnsafePointer<CChar>, stackDepth: UInt16, parameters: UnsafeMutableRawPointer?, priority: UInt32, taskHandle: UnsafeMutablePointer<TaskHandle_t>?, taskCode: @escaping @convention(c) (UnsafeMutableRawPointer?) -> Void) -> BaseType_t {
    xTaskCreateWrapper(taskCode, name, stackDepth, parameters, priority, taskHandle)
}

you should still be able to pass in a string literal. Also, in the above example, I moved taskCode to the end, so you should be able to use trailing closure syntax, e.g.:

let result = createTask(name: "MyTaskName", stackDepth: 128, parameters: nil, priority: 1, taskHandle: &myTaskHandle) {
   // inline task code goes here.
}

Thanks for the feedback @rhx. :grinning:

String recently was made available (in the nightly toolchains) in Embedded Swift. What exact problem are you seeing around trying to use strings?

Thanks for the information @kubamracek

I'm testing a FreeRTOS task create wrapper to run on espressif esp32c6.
portBASE_TYPE xTaskCreate(
pdTASK_CODE pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pvCreatedTask
);
For the pcName parameter @rhx suggested UnsafePointer type.
Best regards

There's certainly multiple options how to design your wrapper, but if you want to, you can totally use a String argument to represent the task name. Strings allow conversion into a pointer for C API calls, but you want to make sure that the API is not going to stash the received pointer beyond the duration of the API call.

Alternatively, you can also only accept StaticString, if you want users of the wrapper to only ever use compile-time constant strings as task names.

1 Like