Skip to content

Commit

Permalink
Move to new static task
Browse files Browse the repository at this point in the history
  • Loading branch information
FranciscoLlobet committed Jan 14, 2024
1 parent 9e4eb88 commit c25e63f
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ zig-out
*.bin
*.sig
*.der
venv
12 changes: 9 additions & 3 deletions src/boot.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ export fn vApplicationIdleHook() void {
pub export const miso_nvm3_handle = &nvm.miso_nvm3;
pub export const miso_nvm3_init_handle = &nvm.miso_nvm3_init;

var timerTask: freertos.StaticTask(config.rtos_stack_depth_timer_task) = undefined;
var idleTask: freertos.StaticTask(config.rtos_stack_depth_idle_task) = undefined;
var timerTask: freertos.StaticTask(@This(), config.rtos_stack_depth_timer_task, "timer", dummyTask) = undefined;
var idleTask: freertos.StaticTask(@This(), config.rtos_stack_depth_idle_task, "idle", dummyTask) = undefined;

fn dummyTask(self: *@This()) void {
_ = self;
unreachable;
}

export fn vApplicationGetTimerTaskMemory(ppxTimerTaskTCBBuffer: **freertos.StaticTask_t, ppxTimerTaskStackBuffer: **freertos.StackType_t, pulTimerTaskStackSize: *c_uint) callconv(.C) void {
ppxTimerTaskTCBBuffer.* = &timerTask.staticTask;
Expand Down Expand Up @@ -155,7 +160,8 @@ pub const microzig_options = struct {
};
};

pub export fn SVC7_Handler() callconv(.C) void {
pub export fn SVC7_Handler() callconv(.Naked) void {
asm volatile ("nop");
//microzig.cpu.regs.CONTROL.modify(.{ .nPRIV = 0 });
}

Expand Down
7 changes: 3 additions & 4 deletions src/boot/app.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const update_phase = enum(usize) {
backup_restored,
};

task: freertos.StaticTask(2000),
task: freertos.StaticTask(@This(), 2000, "bootApp", taskFunction),

fn firmwareUpdate() !firmware_update_outcome {
return firmwareUpdateStateMachine(update_phase.check);
Expand Down Expand Up @@ -233,8 +233,7 @@ fn firmwareUpdateStateMachine(start_phase: ?update_phase) !firmware_update_outco
return outcome;
}

fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.Task.getAndCastPvParameters(@This(), pvParameters);
fn taskFunction(self: *@This()) void {
_ = self;

_ = nvm.init() catch 0;
Expand Down Expand Up @@ -281,7 +280,7 @@ fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
}

pub fn init(self: *@This()) void {
self.task.create(taskFunction, "BootApp", self, config.rtos_prio_boot_app) catch unreachable;
self.task.create(self, config.rtos_prio_boot_app) catch unreachable;
self.task.suspendTask();
}

Expand Down
43 changes: 38 additions & 5 deletions src/freertos.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,20 @@ pub fn xTimerPendFunctionCall(xFunctionToPend: PendedFunction_t, pvParameter1: ?
}

/// Create a Static Task
pub fn StaticTask(comptime stackSize: usize) type {
pub fn StaticTask(comptime T: type, comptime stackSize: usize, comptime pcName: [*:0]const u8, comptime taskRunnerFn: *const fn (*T) void) type {
return struct {
/// Inner Task object
task: Task = undefined,
/// Static stack
stack: [stackSize]StackType_t = undefined,
/// Static task object for FreeRTOS
staticTask: StaticTask_t = undefined,

pub inline fn create(self: *@This(), comptime pxTaskCode: TaskFunction_t, comptime pcName: [*:0]const u8, pvParameters: ?*anyopaque, uxPriority: UBaseType_t) !void {
self.task = try Task.createStatic(pxTaskCode, pcName, pvParameters, uxPriority, self.stack[0..], &self.staticTask);
fn run(pvParameters: ?*anyopaque) callconv(.C) void {
taskRunnerFn(@as(*T, @ptrCast(@alignCast(pvParameters))));
}
pub inline fn create(self: *@This(), pvParameters: *T, uxPriority: UBaseType_t) !void {
self.task = try Task.createStatic(run, pcName, @ptrCast(pvParameters), uxPriority, self.stack[0..], &self.staticTask);
}
pub inline fn resumeTask(self: *const @This()) void {
self.task.resumeTask();
Expand Down Expand Up @@ -150,7 +156,9 @@ pub fn StaticTask(comptime stackSize: usize) type {
};
}

/// FreeRTOS Task wrapper as Zig struct
pub const Task = struct {
/// Notify action
pub const eNotifyAction = enum(u32) {
eSetBits = c.eSetBits,
eIncrement = c.eIncrement,
Expand All @@ -159,6 +167,7 @@ pub const Task = struct {
eNoAction = c.eNoAction,
};

/// FreeRTOS task handle
handle: TaskHandle_t = undefined,

pub fn initFromHandle(task_handle: TaskHandle_t) @This() {
Expand All @@ -171,6 +180,7 @@ pub const Task = struct {

return if (pdPASS == c.xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, @constCast(&self.handle))) self else FreeRtosError.TaskCreationFailed;
}
/// Create a FreeRTOS task using static memory allocation
pub fn createStatic(pxTaskCode: TaskFunction_t, pcName: [*:0]const u8, pvParameters: ?*anyopaque, uxPriority: UBaseType_t, stack: []StackType_t, pxTaskBuffer: *StaticTask_t) !@This() {
var self = @This(){ .handle = c.xTaskCreateStatic(pxTaskCode, pcName, stack.len, pvParameters, uxPriority, stack.ptr, pxTaskBuffer) };

Expand Down Expand Up @@ -206,6 +216,7 @@ pub const Task = struct {
pub inline fn notify(self: *const @This(), ulValue: u32, eAction: eNotifyAction) FreeRtosError!void {
return if (pdPASS == c.xTaskGenericNotify(self.handle, c.tskDEFAULT_INDEX_TO_NOTIFY, ulValue, @intFromEnum(eAction), null)) return FreeRtosError.TaskNotifyFailed;
}
/// Notify Task from ISR with given value
pub inline fn notifyFromISR(self: *const @This(), ulValue: u32, eAction: eNotifyAction, pxHigherPriorityTaskWoken: *BaseType_t) bool {
return (pdPASS == c.xTaskNotifyFromISR(self.handle, ulValue, eAction, pxHigherPriorityTaskWoken));
}
Expand Down Expand Up @@ -307,6 +318,27 @@ pub fn StaticTimer() type {
return struct {
timer: Timer = undefined,
staticTimer: StaticTimer_t = undefined,
pub fn create(pcTimerName: [*:0]const u8, xTimerPeriodInTicks: TickType_t, autoReload: bool, comptime T: type, pvTimerID: *T, pxCallbackFunction: TimerCallbackFunction_t) !@This() {
return @This(){ .timer = try Timer.createStatic(pcTimerName, xTimerPeriodInTicks, autoReload, T, pvTimerID, pxCallbackFunction) };
}
pub inline fn start(self: *const @This(), xTicksToWait: ?TickType_t) !void {
return self.timer.start(xTicksToWait);
}
pub inline fn stop(self: *const @This(), xTicksToWait: ?TickType_t) !void {
return self.timer.stop(xTicksToWait);
}
pub inline fn changePeriod(self: *const @This(), xNewPeriod: TickType_t, xBlockTime: ?TickType_t) !void {
return self.timer.changePeriod(xNewPeriod, xBlockTime);
}
pub inline fn reset(self: *const @This(), xTicksToWait: TickType_t) BaseType_t {
return self.timer.reset(xTicksToWait);
}
pub inline fn getId(self: *const @This(), comptime T: type) ?*T {
return self.timer.getId(T);
}
pub inline fn getIdFromHandle(comptime T: type, xTimer: TimerHandle_t) *T {
return Timer.getIdFromHandle(T, xTimer);
}
};
}

Expand All @@ -315,6 +347,7 @@ pub const Timer = struct {
handle: TimerHandle_t = undefined,

/// Get the timer ID from the timer handle and cast it into the desired (referenced) type
/// This function can be used in the timer callback function to get the timer ID
pub inline fn getIdFromHandle(comptime T: type, xTimer: TimerHandle_t) *T {
return @as(*T, @ptrCast(@alignCast(c.pvTimerGetTimerID(xTimer))));
}
Expand All @@ -325,14 +358,14 @@ pub const Timer = struct {

return if (self.handle == null) FreeRtosError.TimerCreationFailed else self;
}

/// Create a FreeRTOS timer using static memory allocation
pub inline fn createStatic(pcTimerName: [*:0]const u8, xTimerPeriodInTicks: TickType_t, autoReload: bool, comptime T: type, pvTimerID: *T, pxCallbackFunction: TimerCallbackFunction_t, pxTimerBuffer: *StaticTimer_t) !@This() {
var self: @This() = .{ .handle = c.xTimerCreateStatic(pcTimerName, xTimerPeriodInTicks, if (autoReload) pdTRUE else pdFALSE, @ptrCast(@alignCast(pvTimerID)), pxCallbackFunction, pxTimerBuffer) };

return if (self.handle == null) FreeRtosError.TimerCreationFailed else self;
}

/// Get the timer ID from the own timer
/// Get the timer ID from the own timer and cast it into the desired (referenced) type
pub inline fn getId(self: *const @This(), comptime T: type) ?*T {
return @as(?*T, @ptrCast(@alignCast(c.pvTimerGetTimerID(self.timer))));
}
Expand Down
11 changes: 4 additions & 7 deletions src/lwm2m.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ const c = @cImport({

extern fn write_temperature(temperature: f32) callconv(.C) void;

task: freertos.StaticTask(config.rtos_stack_depth_lwm2m),
task: freertos.StaticTask(@This(), config.rtos_stack_depth_lwm2m, "lwm2m", if (config.enable_lwm2m) taskFunction else dummyTaskFunction),
reg_update: freertos.Timer,
timer_update: freertos.Timer,

fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.getAndCastPvParameters(@This(), pvParameters);
fn taskFunction(self: *@This()) void {
var ret: i32 = 0;

self.reg_update.start(null) catch unreachable;
Expand All @@ -32,9 +31,7 @@ fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
system.reset();
}

fn dummyTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.Task.getAndCastPvParameters(@This(), pvParameters);

fn dummyTaskFunction(self: *@This()) void {
while (true) {
self.task.suspendTask();
}
Expand All @@ -49,7 +46,7 @@ fn timer_update_function(xTimer: freertos.TimerHandle_t) callconv(.C) void {
}

pub fn create(self: *@This()) void {
self.task.create(if (config.enable_lwm2m) taskFunction else dummyTaskFunction, "lwm2m", self, config.rtos_prio_lwm2m) catch unreachable;
self.task.create(self, config.rtos_prio_lwm2m) catch unreachable;

self.task.suspendTask();

Expand Down
9 changes: 7 additions & 2 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ export fn vApplicationIdleHook() void {
pub export const miso_nvm3_handle = &nvm.miso_nvm3;
pub export const miso_nvm3_init_handle = &nvm.miso_nvm3_init;

var timerTask: freertos.StaticTask(config.rtos_stack_depth_timer_task) = undefined;
var idleTask: freertos.StaticTask(config.rtos_stack_depth_idle_task) = undefined;
var timerTask: freertos.StaticTask(@This(), config.rtos_stack_depth_timer_task, "timer", dummyTask) = undefined;
var idleTask: freertos.StaticTask(@This(), config.rtos_stack_depth_idle_task, "idle", dummyTask) = undefined;

fn dummyTask(self: *@This()) void {
_ = self;
unreachable;
}

export fn vApplicationGetTimerTaskMemory(ppxTimerTaskTCBBuffer: **freertos.StaticTask_t, ppxTimerTaskStackBuffer: **freertos.StackType_t, pulTimerTaskStackSize: *c_uint) callconv(.C) void {
ppxTimerTaskTCBBuffer.* = &timerTask.staticTask;
Expand Down
12 changes: 4 additions & 8 deletions src/mqtt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ disconnectionCounter: usize,

pingTimer: freertos.Timer,
pubTimer: freertos.Timer, // delete this!
task: freertos.StaticTask(config.rtos_stack_depth_mqtt),
task: freertos.StaticTask(@This(), config.rtos_stack_depth_mqtt, "mqtt", if (config.enable_mqtt) taskFunction else dummyTaskFunction),
state: state,
packet: @This().packet,
uri_string: [*:0]u8,
Expand Down Expand Up @@ -725,9 +725,7 @@ fn loop(self: *@This(), uri: std.Uri) !void {
}
}

fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.Task.getAndCastPvParameters(@This(), pvParameters);

fn taskFunction(self: *@This()) void {
// Clear the buffers
@memset(&txBuffer, 0);
@memset(&rxBuffer, 0);
Expand All @@ -754,9 +752,7 @@ fn taskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
// Go to disconnect phase
}

fn dummyTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.getAndCastPvParameters(@This(), pvParameters);

fn dummyTaskFunction(self: *@This()) void {
while (true) {
self.task.suspendTask();
}
Expand All @@ -780,7 +776,7 @@ fn pubTimer(xTimer: freertos.TimerHandle_t) callconv(.C) void {
}

pub fn create(self: *@This()) void {
self.task.create(if (config.enable_mqtt) taskFunction else dummyTaskFunction, "mqtt", self, config.rtos_prio_mqtt) catch unreachable;
self.task.create(self, config.rtos_prio_mqtt) catch unreachable;
self.task.suspendTask();
if (config.enable_mqtt) {
self.connection = connection.init(.mqtt, authCallback, null);
Expand Down
8 changes: 3 additions & 5 deletions src/sensors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ const c = @cImport({
@cInclude("task.h");
});

task: freertos.StaticTask(config.rtos_stack_depth_sensor) = undefined,
task: freertos.StaticTask(@This(), config.rtos_stack_depth_sensor, "sensor", sensorSampingTask) = undefined,
timer: freertos.Timer = undefined,

fn tempTimerCallback(xTimer: freertos.TimerHandle_t) callconv(.C) void {
freertos.Timer.getIdFromHandle(@This(), xTimer).task.notify(1, .eSetBits) catch {};
}

fn sensorSampingTask(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.Task.getAndCastPvParameters(@This(), pvParameters);

fn sensorSampingTask(self: *@This()) void {
var bme280_sensor = bme280.init(@ptrCast(board.bme280_dev)) catch unreachable;
var bma280_sensor = bma280.init(@ptrCast(board.bma280_dev)) catch unreachable;
_ = bma280_sensor;
Expand All @@ -42,7 +40,7 @@ fn sensorSampingTask(pvParameters: ?*anyopaque) callconv(.C) void {
}

pub fn init(self: *@This()) !void {
self.task.create(sensorSampingTask, "tempTask", self, config.rtos_prio_sensor) catch unreachable;
self.task.create(self, config.rtos_prio_sensor) catch unreachable;
self.timer = freertos.Timer.create("tempTimer", 1000, true, @This(), self, tempTimerCallback) catch unreachable;
self.timer.start(null) catch unreachable;
}
Expand Down
40 changes: 19 additions & 21 deletions src/user.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ const state = enum(usize) {
}
};

task: freertos.StaticTask(config.rtos_stack_depth_user_task),
task: freertos.StaticTask(@This(), config.rtos_stack_depth_user_task, "user task", myUserTaskFunction),
timer: freertos.Timer,
state: state,
stateMachineState: state,

fn myTimerFunction(xTimer: freertos.TimerHandle_t) callconv(.C) void {
const self = freertos.Timer.getIdFromHandle(@This(), xTimer);
Expand All @@ -52,9 +52,7 @@ fn myTimerFunction(xTimer: freertos.TimerHandle_t) callconv(.C) void {
self.task.notify(test_var, .eSetBits) catch {};
}

fn myUserTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
const self = freertos.Task.getAndCastPvParameters(@This(), pvParameters);

fn myUserTaskFunction(self: *@This()) void {
var wifi_task = freertos.Task.initFromHandle(@as(freertos.TaskHandle_t, @ptrCast(c.wifi_task_handle)));

_ = nvm.init() catch 0;
Expand All @@ -64,7 +62,7 @@ fn myUserTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
while (true) {
var eventValue: u32 = 0;

if (self.state == .verify_config) {
if (self.stateMachineState == .verify_config) {
config.load_config_from_nvm() catch {
_ = c.printf("Failure!!\n\r");
};
Expand All @@ -73,8 +71,8 @@ fn myUserTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
_ = c.printf("Failure!!\n\r");
};

self.state = .start_connectivity;
} else if (self.state == .start_connectivity) {
self.stateMachineState = .start_connectivity;
} else if (self.stateMachineState == .start_connectivity) {

// Change this to wait for connectivity
wifi_task.resumeTask();
Expand All @@ -85,8 +83,8 @@ fn myUserTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {
}
}

self.state = .perform_firmware_download;
} else if (self.state == .perform_firmware_download) {
self.stateMachineState = .perform_firmware_download;
} else if (self.stateMachineState == .perform_firmware_download) {
if (config.enable_http) {
_ = c.printf("Performing firmware download\r\n");

Expand All @@ -112,23 +110,23 @@ fn myUserTaskFunction(pvParameters: ?*anyopaque) callconv(.C) void {

// perform HTTP download
if (comptime config.enable_lwm2m) {
self.state = .start_lwm2m;
self.stateMachineState = .start_lwm2m;
} else if (comptime config.enable_mqtt) {
self.state = .start_mqtt;
self.stateMachineState = .start_mqtt;
} else {
self.state = .working;
self.stateMachineState = .working;
}
} else if (self.state == .start_mqtt) {
} else if (self.stateMachineState == .start_mqtt) {
mqtt.service.resumeTask();

self.timer.start(null) catch unreachable;

self.state = .working;
} else if (self.state == .start_lwm2m) {
self.stateMachineState = .working;
} else if (self.stateMachineState == .start_lwm2m) {
lwm2m.service.task.resumeTask();

self.state = .working;
} else if (self.state == .working) {
self.stateMachineState = .working;
} else if (self.stateMachineState == .working) {
// recieve

if (self.task.waitForNotify(0, 0xFFFFFFFF, null) catch unreachable) |_| {
Expand All @@ -150,9 +148,9 @@ fn downloadAndVerify() !bool {
}

pub fn create(self: *@This()) void {
self.state = state.verify_config;
self.task.create(myUserTaskFunction, "user_task", @constCast(self), config.rtos_prio_user_task) catch unreachable;
self.stateMachineState = state.verify_config;
self.task.create(self, config.rtos_prio_user_task) catch unreachable;
self.timer = freertos.Timer.create("user_timer", 2000, true, @This(), self, myTimerFunction) catch unreachable;
}

pub var user_task: @This() = .{ .timer = undefined, .state = undefined, .task = undefined };
pub var user_task: @This() = .{ .timer = undefined, .stateMachineState = undefined, .task = undefined };

0 comments on commit c25e63f

Please sign in to comment.