SDK的初始化及运行参考Jim_天河博主的博客
最终程序会在两个部分中执行:
1每个模块的 下运行task_deal函数,例蓝牙模块,相当于这个模块的主函数,杰理主函数以message为媒介运行,仔细分析代码可以发现所有模块的函数的主体都是,主函数中一直出队列获取消息,其他地方发布消息
void task()
{
/* 模块初始化 */
while(1){
/* 获取消息队列中消息 */
error = task_get_msg(0, 2, msg);
/* 这里调用task_common_msg_deal可以实现各种外设接入或者按键跳转模块
在调用task_switch这个函数之后成功,这个函数即可完成模块的切换,
task_common_msg_deal会返回 false,使得当前模块的函数被return*/
if (task_common_msg_deal(NULL, msg[0]) == false) {
return ;
}
switch(msg[0]){
/* 各种消息处理 */
}
}
}
2定时器中断 time值代表 time*2ms时间回调一次fun函数指针,定时在timer0中进行,类似于定时器中断处理。
/*不同功能的循环检测功能统一用LOOP_DETECT_REGISTER注册,可搜索关键字看例子*/
struct loop_detect_handler {
int time;/*TIMER周期的倍数。timer周期默认一般是2ms */
void (*fun)();
};
#define LOOP_DETECT_REGISTER(handler) \
const struct loop_detect_handler handler \
SEC_USED(.loop_detect_region)
1、主函数的while(1)循环只处理一个函数void task_manager(void);
任务数组数组的元素是一个任务,该元素为一个TASK_APP
结构体指针
static const TASK_APP *task_app_list[TASK_ID_MAX] = {
[TASK_ID_BT] = &task_bt_info,
#if BT_HID_INDEPENDENT_MODE
[TASK_ID_BT_HID] = &task_bt_hid_info,
#endif
[TASK_ID_MUSIC] = &task_music_info,
#if (BT_TWS_LINEIN==0)//开启linein_tws时,linein在蓝牙模式进行linein播放
[TASK_ID_LINEIN] = &task_linein_info,
#endif
#if USB_PC_EN
[TASK_ID_PC] = &task_pc_info,
#endif
#if FM_RADIO_EN
[TASK_ID_FM] = &task_fm_info,
#endif
#if RTC_CLK_EN
[TASK_ID_RTC] = &task_rtc_info,
#endif
#if MIC_REC_EN
[TASK_ID_REC] = &task_rec_info,
#endif
#if TASK_ECHO_EN
[TASK_ID_ECHO] = &task_echo_info,
#endif
#if SPDIF_EN
[TASK_ID_SPDIF] = &task_spdif_info,
#endif
[TASK_ID_IDLE] = &task_idle_info,
};
TASK_APP
任务结构体成员:任务的退出函数,初始化函数,任务函数,还有按键消息的函数指针
typedef struct __TASK_APP {
// const char *name;
tbool(*skip_check)(void **priv);
void *(*init)(void *priv);
void (*exit)(void **priv);
void (*task)(void *priv);
const KEY_REG *key;
} TASK_APP;
例如task_rtc
const TASK_APP task_rtc_info = {
.skip_check = NULL,
.init = task_rtc_init,
.exit = task_rtc_exit,
.task = task_rtc_deal,
.key = &task_rtc_key,
};
2、类似定时器中断处理
SDK运行的核心部分,循环处理结构体
例如下面3 个函数都是通过上面的结构体定义的,其中delay_1500ms_count()
是自己定义的。所以要定义结构体,系统定义的接构体SDK中没有提供,可能在别的文件中,我们查看不到。
const struct loop_detect_handler delay_1500ms ;
static volatile u32 delay2ms_cnt = 0;
static void delay_2ms_count()
{
//printf("delay_2ms_count\n");
if (delay2ms_cnt) {
delay2ms_cnt--;
}
}
LOOP_DETECT_REGISTER(delay_2m_cnt) = {
.time = 1,
.fun = delay_2ms_count,
};
void task_message_init()
{
printf("task_message_init\n");
cbuf_init(&msg_cbuf, msg_pool, sizeof(msg_pool));
cbuf_clear(&msg_cbuf);
}
LOOP_DETECT_REGISTER(half_second_det) = {
.time = 250,
.fun = half_second_msg,
};
const struct loop_detect_handler delay_1500ms ;
static void delay_1500ms_count()
{
printf("delay_1s_count\n");
}
LOOP_DETECT_REGISTER(delay_1500ms) = {
.time = 1500,
.fun = delay_1500ms_count,
};
通过串口打印可以看出来,很明显。SDK中大多数的程序运行都是通过上述结构体进行定义的,程序会按设定好的时间去执行,不同功能的循环检测功能函数。