Nordic nRF52840 低功耗藍牙BLE 5.0新手入門指南_004------scheduler(僞調度)實現多任務處理

@[TOC](Nordic nRF52840 低功耗藍牙BLE 5.0新手入門指南_004------scheduler(僞調度)實現多任務處理)

Nordic nRRF52840 低功耗藍牙BLE 5.0新手入門指南_004------scheduler(僞調度)實現多任務處理

1. scheduler(僞調度)配置

scheduler(僞調度)和操作系統的調度是不一樣的,這個scheduler其實裏面就是一個隊列,不同任務之間通過排隊順序執行,可以設置隊列的大小、給任務傳入事件數據(參數)等。

  • **APP_SCHED_INIT():**初始化scheduler(僞調度),設置隊列大小和事件數據(參數)大小。
  • **app_sched_event_put():**把要執行的任務放到隊列裏面,準備執行。
  • **app_sched_execute():**按照app_sched_event_put放入任務的先後順序,執行對應的任務。

在sdk_config.h中打開APP_SCHEDULER_ENABLED宏。

  • sdk_config.h
#ifndef APP_SCHEDULER_ENABLED
#define APP_SCHEDULER_ENABLED 1
#endif

2. 模擬幾個任務實現調度

  • carey_scheduler.c
#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); 
}	


  • carey_scheduler.h
#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 */



  • main.c
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); */

}

寫博客不容易,需要大家多多支持。想了解更多,本人也可以提供有賞服務
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章