这篇先分析一下提供模板的框架部分程序。
这里以模板的代码(灯和按键)为例:
http://download.youkuaiyun.com/download/dfsae/9987318
1.主函数
NRF51822的框架还是采用事件驱动框架。先从主函数进行分析
int main(void)
{
// Initialize
leds_init(); //led初始化,硬件配置
timers_init();
gpiote_init(); //中断初始化
buttons_init();
ble_stack_init();
scheduler_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();
sec_params_init();
// Start execution
timers_start();
advertising_start();
// Enter main loop
for (;;)
{
app_sched_execute();
power_manage();
}
}
主函数里做一些初始化,再启动定时器和广播,在主循环里实现任务调度和电源管理power_manage();
1.1.定时器
NRF51822的定时器由队列进行多个定时器的管理。
1.1.1.数据结构
定时器主要放在timer_node_t结构体组成数组中进行集中管理,存储的方式具体看timers_init中的解析。
timer_node_t的结构如下:
typedef struct
{
timer_alloc_state_t state; /**< 定时器分配状态 */
app_timer_mode_t mode; /**< 定时器模式 */
uint32_t ticks_to_expire; /**< 上一次定时器中断到终止的ticks. */
uint32_t ticks_at_start; /**< 当前当定时器启动的RTC计数值. */
uint32_t ticks_first_interval; /**< 第一次定时器间隔的ticks */
uint32_t ticks_periodic_interval; /**< 时间周期 */
bool is_running; /**< True代表运行, False其他. */
app_timer_timeout_handler_t p_timeout_handler; /**< 指向当定时器倒是后调用的函数 */
void * p_context; /**<通用目标指针. 当定时器到时时,将进行超时处理。 */
app_timer_id_t next; /**<下一个运行定时器的id*/
} timer_node_t;
app_timer.c中为定时器队列提供了基础的添加移除操作。
1.1.2.初始化函数
主函数中调用timers_init实现定时器的初始化
static void timers_init(void)
{
// Initialize timer module, making it use the scheduler
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
}
#define APP_TIMER_INIT(PRESCALER, MAX_TIMERS, OP_QUEUES_SIZE, USE_SCHEDULER) \
do \
{ \
static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((MAX_TIMERS), \
(OP_QUEUES_SIZE) + 1), \
sizeof(uint32_t))]; \
uint32_t ERR_CODE = app_timer_init((PRESCALER), \
(MAX_TIMERS), \
(OP_QUEUES_SIZE) + 1, \
APP_TIMER_BUF, \
(USE_SCHEDULER) ? app_timer_evt_schedule : NULL); \
APP_ERROR_CHECK(ERR_CODE); \
} while (0)
该初始化调用了app_timer.c中的app_timer_init,同时根据USE_SCHEDULER来设置回调函数app_timer_evt_schedule。
static __INLINE uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler,
void * p_context)
{
app_timer_event_t timer_event;
timer_event.timeout_handler = timeout_handler;
timer_event.p_context = p_context;
return app_sched_event_put(&timer_event, sizeof(timer_event), app_timer_evt_get);
}
app_timer_evt_schedule中做了:
1>.生成一个事件。
2>.通过事件调度的API(app_sched_event_put)发送事件。
uint32_t app_timer_init(uint32_t prescaler,//预分频器
uint8_t max_timers,//最大时间
uint8_t op_queues_size,
void * p_buffer,