基于OSAL的嵌入式裸机事件驱动框架——DEMO


感谢大佬分享B站up主【架构分析】嵌入式祼机事件驱动框架


DEMO演示,使用OSAL的任务事件,定时器以及消息队列功能进行一个简单的使用演示
有两个任务
LED任务
- 定时器1事件:500ms闪烁一次
- 定时器2事件:1000ms发送消息给打印任务

打印任务
- 按键按下事件:打印" button pressed "
- 系统消息事件:打印" msg test received "


app_led_task.c

/****************************************************************************************
 * 文件名  :app_led_task.c
 * 描述    :led任务
 *          定时器1事件:500ms闪烁一次
 *          定时器2事件:1000ms发送消息给打印任务
 ***************************************************************************************/
#include "application.h"
#include "bsp_led.h"

#define TIMER1_TIMEOUT 500
#define TIMER2_TIMEOUT 1000
task_id_t TASK_LED = 2;					        //LED任务ID
event_id_t EVE_TIMER1_Elapsed = 1 << 0;			//定时器溢出事件
event_id_t EVE_TIMER2_Elapsed = 1 << 1;			//定时器溢出事件

/**LED任务初始化**/
void task_led_init(task_id_t task_id)
{
    osal_timer_startre(task_id,EVE_TIMER1_Elapsed,TIMER1_TIMEOUT);
    osal_timer_startre(task_id,EVE_TIMER2_Elapsed,TIMER2_TIMEOUT);
}

/**LED任务事件处理函数**/
osal_uint16_t task_led_event_process(task_id_t task_id,event_asb_t events)
{
    if(events & EVE_TIMER1_Elapsed)
    {
        //500ms定时器溢出,LED闪烁
        bsp_LedToggle();
        return events ^ EVE_TIMER1_Elapsed;
    }
    if(events & EVE_TIMER2_Elapsed)
    {
        //1000ms定时器溢出,发送消息给打印任务
        osal_msg_bdy_t *msg;
        msg = (osal_msg_bdy_t*)osal_msg_alloc(sizeof (osal_msg_bdy_t));
        if( msg!= NULL ){
            msg->hdr.event_id = EVE_MSG_TEST;
            msg->hdr.status = 0;
            osal_msg_send(TASK_PRINT,msg);
        }
        return events ^ EVE_TIMER2_Elapsed;
    }
    return 0;
}

osal_task_ops_t task_led_ops =
        {
                task_led_init,
                task_led_event_process,
        };

app_print_task.c

/****************************************************************************************
 * 文件名  :app_print_task.c
 * 描述    :打印任务
 *          按键按下事件:打印" button pressed "
 *          系统消息事件:打印" msg test received "
 ***************************************************************************************/
#include "application.h"

task_id_t TASK_PRINT = 1;					//打印任务ID
event_id_t EVE_KEY_PRESS = 1 << 0;			//按键按下事件(此事件在外部中断(按键按下)中触发)
const event_id_t EVE_MSG_TEST  = 1;


/**打印任务初始化**/
void task_print_init(task_id_t task_id)
{

}

/**打印任务事件处理函数**/
osal_uint16_t task_print_event_process(task_id_t task_id,event_asb_t events)
{
   
	if(events & EVE_KEY_PRESS)
	{
        osal_printf(" button pressed \r\n");

		return events ^ EVE_KEY_PRESS;
	}
    if ( events & SYS_EVE_MSG )   	//判断系统消息事件
    {
        osal_msg_bdy_t *msg;    			//定义一个指向接受系统消息结构体的指针
        // receive the message
        msg = (osal_msg_bdy_t *)osal_msg_receive( task_id );
        if(msg != NULL){
            switch ( msg->hdr.event_id )  	//判断消息事件
            {
                case EVE_MSG_TEST:
                    osal_printf(" msg test received \r\n");
                    break;

                default:
                    break;
            }
        }
        // free the memory
        osal_msg_free( msg );

        // return unprocessed events
        return (events ^ SYS_EVE_MSG);
    }
	return 0;
}

osal_task_ops_t task_print_ops =
        {
            task_print_init,
            task_print_event_process,
        };

application.h

#ifndef APPLICATION_H
#define APPLICATION_H

#include "osal.h"
#include "osal_timer.h"
#include "osal_task.h"
#include "osal_memory.h"
#include "osal_msg.h"
#include "osal_debug.h"
#include "main.h"

/****************************************************************************
 * TASK_XXX shuoule be one an only in the system, it ranges from 0 to 0xFFFE.
 * 0xFFFE is reserved for SYS_TSK_INIT.
 * TASK_XXX is also uesed to schedule task in a decreasing order when event is triggered.
 *
 * EVE_XXX is tied to task events,total num should be no more than 15 for each task.
 * it ranges from 1<<0 to 1<<14, 1<<15 is reserved for SYS_EVE_MSG.
 * EVE_XXX could be the same for different tasks,as for one particular task it should be unique.
 *
 * EVE_MSG_XXX is carried alongside msg' body.
 * the handler process of the task will be called to handle the message, use EVE_MSG_XXX to deal with different situations.
 * it ranges from 0 to 0xFFFF, use different EVE_MSG_XXX as possible.
 * **************************************************************************/

/*print task*/
extern task_id_t TASK_PRINT;
extern event_id_t EVE_KEY_PRESS;
extern osal_task_ops_t task_print_ops;

/*led task*/
extern task_id_t TASK_LED;
extern event_id_t EVE_TIMER1_Elapsed;
extern event_id_t EVE_TIMER2_Elapsed;
extern osal_task_ops_t task_led_ops;
extern const event_id_t EVE_MSG_TEST;


/*****************************************************************************/

#endif

main.c部分

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
	bsp_init();

  /**OSAL**/
    osal_init_system();
    osal_task_create(&task_print_ops,TASK_PRINT);
    osal_task_create(&task_led_ops,TASK_LED);
	osal_task_init();
	osal_mem_kick();
    osal_system_start();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

你可能感兴趣的:(OSAL,嵌入式,事件驱动)