@[TOC](Nordic nRF52840 低功耗蓝牙BLE 5.0新手入门指南_004------scheduler(伪调度)实现多任务处理)
scheduler(伪调度)和操作系统的调度是不一样的,这个scheduler其实里面就是一个队列,不同任务之间通过排队顺序执行,可以设置队列的大小、给任务传入事件数据(参数)等。
在sdk_config.h中打开APP_SCHEDULER_ENABLED宏。
#ifndef APP_SCHEDULER_ENABLED
#define APP_SCHEDULER_ENABLED 1
#endif
#include "app_scheduler.h"
#include "carey_scheduler.h"
#include "app_timer.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#define SCHEDULER_MAX_EVENT_DATA_SIZE 2 /**< Maximum size of scheduler events data size. */
#define SCHEDULER_QUEUE_SIZE 10 /**< Maximum number of events in the scheduler queue. */
#define SCHEDULER_TIMEOUT_INTERVAL APP_TIMER_TICKS(1000) /**< Scheduler interval (ticks). */
APP_TIMER_DEF(m_scheduler_timer_id);
uint32_t scheduler_count = 0;
/**@brief Function for the Event Scheduler initialization.
*/
void scheduler_init(void)
{
APP_SCHED_INIT(SCHEDULER_MAX_EVENT_DATA_SIZE, SCHEDULER_QUEUE_SIZE);
}
/**@brief Function for gui task.
*/
void gui_task(void * p_event_data, uint16_t event_size)
{
uint8_t *p_evt = p_event_data;
switch (*p_evt)
{
case GUI_EVT_DISPLAY_ON://display on
NRF_LOG_DEBUG("Display on");
break;
case GUI_EVT_DISPLAY_REFRESH://display refresh
NRF_LOG_DEBUG("Display Refresh");
break;
case GUI_EVT_DISPLAY_OFF://display off
NRF_LOG_DEBUG("Display off\n");
break;
default:
NRF_LOG_DEBUG("GUI task unknown event");
break;
}
}
/**@brief Function for power manager task.
*/
void power_manager_task(void * p_event_data, uint16_t event_size)
{
UNUSED_PARAMETER(p_event_data);
NRF_LOG_DEBUG("power_manager_task");
}
/**@brief Function for starting timers.
*/
void scheduler_timers_start(void)
{
ret_code_t err_code;
err_code = app_timer_start(m_scheduler_timer_id, SCHEDULER_TIMEOUT_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
static void scheduler_timer_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
ret_code_t err_code = NRF_SUCCESS;
uint8_t buf[SCHEDULER_MAX_EVENT_DATA_SIZE] = {0};
if ((scheduler_count % 10) == 0)
{
buf[0] = GUI_EVT_DISPLAY_ON;//display on
err_code = app_sched_event_put(buf, 1, gui_task);
APP_ERROR_CHECK(err_code);
}
else if ((scheduler_count % 10) == 1)
{
err_code = app_sched_event_put(NULL, 0, power_manager_task);
APP_ERROR_CHECK(err_code);
}
else if ((scheduler_count % 10) == 9)
{
buf[0] = GUI_EVT_DISPLAY_OFF;//display off
err_code = app_sched_event_put(buf, 1, gui_task);
APP_ERROR_CHECK(err_code);
}
else
{
buf[0] = GUI_EVT_DISPLAY_REFRESH;//display refresh
err_code = app_sched_event_put(buf, 1, gui_task);
APP_ERROR_CHECK(err_code);
}
scheduler_count++;
}
void scheduler_timer_init(void)
{
ret_code_t err_code;
// Create timers.
err_code = app_timer_create(&m_scheduler_timer_id, APP_TIMER_MODE_REPEATED, scheduler_timer_timeout_handler);
APP_ERROR_CHECK(err_code);
}
#ifndef ___CAREY_SCHEDULER_H
#define ___CAREY_SCHEDULER_H
#ifdef __cplusplus
extern "C" {
#endif
void scheduler_init(void);
void scheduler_timer_init(void);
void scheduler_timers_start(void);
typedef enum
{
GUI_EVT_DISPLAY_ON = 0x01,
GUI_EVT_DISPLAY_REFRESH,
GUI_EVT_DISPLAY_OFF
} gui_evt_enum_t;
#ifdef __cplusplus
}
#endif
#endif /* ___CAREY_SCHEDULER_H */
int main(void)
{
bool erase_bonds = false;
// Initialize.
log_init();
timers_init();
//buttons_leds_init(&erase_bonds);
power_management_init();
ble_stack_init();
scheduler_init();
gap_params_init();
gatt_init();
advertising_init();
services_init();
conn_params_init();
peer_manager_init();
// Start execution.
NRF_LOG_INFO("Template example started.");
application_timers_start();
advertising_start(erase_bonds);
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
static void idle_state_handle(void)
{
app_sched_execute();
if (NRF_LOG_PROCESS() == false)
{
nrf_pwr_mgmt_run();
}
}
static void timers_init(void)
{
// Initialize timer module.
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
// Create timers.
scheduler_timer_init();
/* YOUR_JOB: Create any timers to be used by the application.
Below is an example of how to create a timer.
For every new timer needed, increase the value of the macro APP_TIMER_MAX_TIMERS by
one.
ret_code_t err_code;
err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
APP_ERROR_CHECK(err_code); */
}
static void application_timers_start(void)
{
scheduler_timers_start();
/* YOUR_JOB: Start your timers. below is an example of how to start a timer.
ret_code_t err_code;
err_code = app_timer_start(m_app_timer_id, TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code); */
}
写博客不容易,需要大家多多支持。想了解更多,本人也可以提供有赏服务