#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
// 睡眠函数,单位ms
void msleep(int ms)
{
usleep(1000 * ms);
}
// 获取系统运行的时间,单位ms
uint32_t get_tick_count(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
long uptime_ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
return (uint32_t)uptime_ms;
}
#define println(fmt, args...) fprintf(stderr, "[%d] " fmt "\n", get_tick_count(), ##args)
static void step0_func_init(void);
static void step0_func_loop(void);
static void step1_func_init(void);
static void step1_func_loop(void);
static void step2_func_init(void);
static void step2_func_loop(void);
static void step3_func_init(void);
static void step3_func_loop(void);
typedef struct
{
void (*step_func_init)(void);
void (*step_func_loop)(void);
} pg_step_fun_t;
typedef struct
{
void (*all_step_init)(void);
pg_step_fun_t *func_list;
uint8_t flag_force_init; // 强制初始化
uint8_t max_step_num; // 最大步骤数
uint8_t pg_step; // 当前步骤
uint8_t pg_step_old; // 上一次步骤
uint8_t pg_step_save; // 步骤发生改变时,保存上一次步骤
uint8_t dev_state_changed; // 设备状态改变标志
uint16_t loop_cnt; // 循环计数
uint32_t tick_enter; // 进入当前步骤的tick
uint32_t tick_curr; // 当前tick时间戳
} pg_param_t;
static pg_param_t g_param;
#define MAX_STEP_NUM 4 // 最大步骤数
// 本页面各步骤的初始化和循环函数列表定义
static pg_step_fun_t g_func_list[MAX_STEP_NUM] =
{
{step0_func_init, step0_func_loop},
{step1_func_init, step1_func_loop},
{step2_func_init, step2_func_loop},
{step3_func_init, step3_func_loop},
};
//当进入步骤时,会调用此函数【公用部分】
static void all_step_init(void)
{
println("all_step_init.");
}
static void step0_func_init(void)
{
println("step0_func_init.");
}
static void step0_func_loop(void)
{
// 每跑100个循环打印一次
if (g_param.loop_cnt % 100 == 0)
{
println("step0_func_loop.");
}
// 运行5秒后跳到step1
if (g_param.tick_curr - g_param.tick_enter > 5000)
{
g_param.pg_step = 1;
}
}
static void step1_func_init(void)
{
println("step1_func_init.");
}
static void step1_func_loop(void)
{
// println("step1_func_loop.");
// 运行2秒后跳到step2
if (g_param.tick_curr - g_param.tick_enter > 2000)
{
g_param.pg_step = 2;
}
}
static void step2_func_init(void)
{
println("step2_func_init.");
}
static void step2_func_loop(void)
{
// 运行2秒后跳到step3
if (g_param.tick_curr - g_param.tick_enter > 2000)
{
g_param.pg_step = 3;
}
}
static void step3_func_init(void)
{
println("step3_func_init.");
}
static void step3_func_loop(void)
{
// 每跑50个循环后跳到step0
if (g_param.loop_cnt > 50)
{
g_param.pg_step = 0;
println("recall step0 here.");
}
}
static void processing_step(pg_param_t *param)
{
if (param->flag_force_init || param->pg_step != param->pg_step_old)
{
param->flag_force_init = 0;
param->pg_step_save = param->pg_step_old;
param->pg_step_old = param->pg_step;
if (param->pg_step <= param->max_step_num)
{
param->loop_cnt = 0;
param->tick_enter = get_tick_count();
if(param->all_step_init != NULL)
param->all_step_init();
param->func_list[param->pg_step].step_func_init();
}
}
if (param->pg_step <= param->max_step_num)
{
param->func_list[param->pg_step].step_func_loop();
param->loop_cnt++;
}
}
void jump_to_step(uint8_t step)
{
g_param.pg_step = step;
g_param.flag_force_init = 1;
}
// 页面内有N个步骤,每个步骤有初始化和循环函数,根据当前步骤,调用对应的初始化和循环函数
// 该设计模式可适用于LVGL,页面内嵌套子页面。
int main()
{
println("_________SOFT BUILD: %s %s______", __DATE__, __TIME__);
g_param.max_step_num = MAX_STEP_NUM;
g_param.func_list = g_func_list;
g_param.all_step_init = all_step_init;
println("start testing step logic....");
jump_to_step(3); // 首次运行,跳到step3
while (1)
{
g_param.tick_curr = get_tick_count();
processing_step(&g_param);
msleep(10);
}
return 0;
}
[C] 关于页面内运行各种步骤的方案
于 2024-10-03 20:46:15 首次发布