BES2300YP - 千头万绪的各种入口: 线程,中断,定时器

目录

1.线程

2.app_mod_handler

3.中断

4.CMSIS RTOS 定时器

5.10s定时器

谁在管理10s定时器

a. 周期定时器

b.app_battery_measure.cb

c.电池管理线程

 结论


1.线程

        osThreadCreate这个函数会创建各种线程

        查找osThreadCreate关键字可以找到这些线程入口

2.app_mod_handler

        这实际上是app_thread中基于mod_id的回调接口, 
        app_thread就会在收到message时, 根据message里面的mod_id把消息交给对应的mod_handle来处理.

        每个mod的处理函数是通过app_set_threadhandle来设定的

        查找关键字app_set_threadhandle可以找到这些mode的处理入口

        以下是这些接口的列表,

enum APP_MODUAL_ID_T {
    APP_MODUAL_KEY = 0,
    APP_MODUAL_AUDIO,
    APP_MODUAL_BATTERY,
    APP_MODUAL_BT,
    APP_MODUAL_FM,
    APP_MODUAL_SD,
    APP_MODUAL_LINEIN,
    APP_MODUAL_USBHOST,
    APP_MODUAL_USBDEVICE,
    APP_MODUAL_WATCHDOG,
    APP_MODUAL_AUDIO_MANAGE,
    APP_MODUAL_ANC,
    APP_MODUAL_SMART_MIC,
    APP_MODUAL_CMD,
    APP_MODUAL_TILE,
    APP_MODUAL_MIC,
    APP_MODUAL_VOICE_DETECTOR,
    APP_MODUAL_IR,
    APP_MODUAL_OHTER,

    APP_MODUAL_NUM
};

我们注意到此列表中的第一个mod是用来处理按键消息的, 其mod_handle是app_key_handle_process

        在希望处理某种按键消息时,

        - 需要声明一个APP_KEY_HANDLE对象, 其中包含了按键事件和回调函数

        - 调用app_key_handle_registration注册该对象, 

        这样一来, app_thread在收到mod_id为APP_MODUAL_KEY时把消息转发到app_key_handle_process, 后者会根据按键键值和类型调用对应的函数.

        查找关键app_key_handle_registration可以找到按键类的处理函数的入口.

        其他mod的子入口关键字需要到各mod里面细细的找

3.中断

        中断函数的设定是通过IRQ_SetHandler来做到的, 我拿到的这版SDK中对它包了一层变成了宏NVIC_SetVector

       这里列出两个定义来感受下.

NVIC_SetVector(SYS_TICK_IRQn, (uint32_t)&SysTick_Handler);
NVIC_SetVector(TIMER01_IRQn, (uint32_t)hal_timer01_irq_handler);
NVIC_SetVector(GPIOAUX_IRQn, (uint32_t)_gpio_aux_irq_handler[bank]);

有意思的是, 

TIMER01_IRQn的处理函数hal_timer01_irq_handler,

- > 会去调用hal_timer_setup设定的hwtimer_handler

-> 后者会跟踪由hwtimer_alloc添加的一个hwtimer_list

而,按键处理除了直接使用按键相关中断外, 也使用了hwtimer_alloc来处理debounce事件

查找关键字NVIC_SetVector和hwtimer_alloc可以看到这两种入口

4.CMSIS RTOS 定时器

osTimerDef/osTimerCreate/osTimerStart是CMSIS中负责定时器管理的CMSIS-RTOS API

更详细的内容可以参考这篇 https://blog.csdn.net/ichamber/article/details/53240733

5.10s定时器

代码和调用关系很简洁

typedef struct
{
    uint8_t timer_id;
    uint8_t timer_en;
    uint8_t timer_count;
    uint8_t timer_period;
    APP_10_SECOND_TIMER_CB_T cb;
}APP_10_SECOND_TIMER_STRUCT;

#define INIT_APP_TIMER(_id, _en, _count, _period, _cb) \
    { \
        .timer_id = _id, \
        .timer_en = _en, \
        .timer_count = _count, \
        .timer_period = _period, \
        .cb = _cb, \
    }

其中start/stop/set都是用来控制定时器的, 

check是用来轮训检查各定时器并回调的.

谁在管理10s定时器

为啥是app_status_battery_report在维护10s定时器

原来这可以追溯电池状态管理进程, 是app_battery_open在其中穿针引线,

int app_battery_open(void) // 仅保留了关键代码
{
    // 1. 开启了一个周期定时器
    if (app_battery_timer == NULL)
        app_battery_timer = osTimerCreate (osTimer(APP_BATTERY), osTimerPeriodic, NULL);

    // 2.设置app_battery_measure.cb
    app_battery_measure.cb = app_battery_event_process;

    // 3.创建电池管理线程
    app_set_threadhandle(APP_MODUAL_BATTERY, app_battery_handle_process);
}

如以上代码中的注释:

a. 周期定时器

通过app_battery_timer_handler来访问ADC调用app_battery_irqhandler,  后者会调用app_battery_measure.cb

static void app_battery_timer_handler(void const *param)
{
    hal_gpadc_open(HAL_GPADC_CHAN_BATTERY, HAL_GPADC_ATP_ONESHOT, app_battery_irqhandler);
}

b.app_battery_measure.cb

即app_battery_event_process, 会在app_battery_irqhandler中不断调用来发送消息到app_battery_handle_process

static void app_battery_event_process(enum APP_BATTERY_STATUS_T status, APP_BATTERY_MV_T volt)
{
    uint32_t app_battevt;
    APP_MESSAGE_BLOCK msg;

    APP_BATTERY_TRACE(3,"%s %d,%d",__func__, status, volt);
    msg.mod_id = APP_MODUAL_BATTERY; // 消息被发送到电池线程
    APP_BATTERY_SET_MESSAGE(app_battevt, status, volt);
    msg.msg_body.message_id = app_battevt;
    msg.msg_body.message_ptr = (uint32_t)NULL;
    app_mailbox_put(&msg);

}

c.电池管理线程

会层层深入调用到

 结论

电池状态管理进程依赖于CMSIS RTOS定时器APP_BATTERY实现了10s定时器的管理

欢迎阅读更多 BES专栏文章

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值