OSAL

OSAL事件触发机制----定时器触发
CC2540 OSAL 学习其中原理,以及 给任务 添加 一个事件(定时发送串口消息)
OSAL调度机制
OSAL之消息管理
OSAL的消息机制触发事件流程
OSAL中的消息与事件
ZStack OSAL的事件(event)与消息(message)——part1
有关zstack的osal机制的理解
CC254x的软件基于OSAL架构

zigbee开源协议栈中的OSAL操作系统移植到12单片机(很值得一看)


OSAL使用


OSAL并非是一个实时的操作系统,只是在循环的执行所有任务。如果一个任务占用时间太久会影响另一个任务的实时性。
每一个任务可以使用的事件标识总共有16个(一个16位的变量),其中一个被系统占用为SYS_EVENT_MSG(消息事件,为事件标志最高位),其他15位的事件功能根据需要自己定义
1. 需要在时基中断为1ms的定时器中调用osal_update_timers();
2. 可通过三种方法调用执行的函数,osal_set_event,osal_msg_send,osal_start_reload_timer
osal_set_event:触发自定义事件,osal_set_event(Modbus_TaskID,MODBUS_REC_FINISH_EVENT);
osal_msg_send:由于OSAL用户只能自己定义15个事件,想要多定义事件及给对应的任务发送消息,需要使用osal_msg_send,触发的事件是SYS_EVENT_MSG
osal_start_reload_timer:定时触发指定任务的自定义事件
//osal操作系统初始化
osal_init_system();
//添加任务
osal_add_Task(Display_Task_Init,Display_Task_EventProcess,0);
osal_add_Task(NULL,ReadRTC_Task_EventProcess,1);
osal_add_Task(NULL,Modbus_Task_EventProcess,1);
osal_add_Task(NULL,WaveProcess_Task_EventProcess,1);

//添加的任务统一进行初始化
osal_Task_init();
//设置初始任务事件,上电就需要自动轮询的任务事件可在此添加
osal_start_reload_timer( Display_TaskID, DISP_TIMER_EVENT, 500);

//设置初始任务事件,上电就需要自动轮询的任务事件可在此添加
osal_start_reload_timer( ReadRTC_TaskID, RTC_TIMER_EVENT, 500);
//启动osal系统,不会再返回
osal_start_system();

uint8_t SendKeyCode( uint8_t keyCode)
 {
   osal_sys_msg_t *msgPtr;
   msgPtr = (osal_sys_msg_t *)osal_msg_allocate( sizeof(osal_sys_msg_t) );
   if ( msgPtr )
   {
     msgPtr->hdr.event = KEY_PRESSED_EVENT;
     msgPtr->Data_t = keyCode;
     osal_msg_send( Display_TaskID, (uint8 *)msgPtr );
     return ( TRUE );
   }
   else
   {return ( FALSE );}
   return ( TRUE );
 }
//对应的任务必须按照如下定义的ID顺序移入osal_add_Task,否则TaskID和任务不对应
  enum TASK_ID
  {
    Display_TaskID=0,
    ReadRTC_TaskID,
    Modbus_TaskID,
    WaveProcess_TaskID,
  };
 
   enum WAVE_TASK_EVENT
  {
    WAVE_READY_EVENT=(1<<0),
  };
  
  enum MODBUS_TASK_EVENT
  {
    MODBUS_REC_FINISH_EVENT=(1<<0),
  };
  
  enum KEY_TASK_EVENT
  {
    KEY_PRESSED_EVENT=(1<<0),
  };
  
  enum DISP_TASK_EVENT
  {
    DISP_TIMER_EVENT=(1<<0),
    DISP_COUNT_EVENT=(1<<1),
  };
  
  enum RTC_TASK_EVENT
  {
    RTC_TIMER_EVENT=(1<<0),
  };
  
typedef struct
{
  void   *next;
  uint16 len;
  uint8  dest_id;
} osal_msg_hdr_t;

typedef struct
{
  uint8  event;
  uint8  status;
} osal_event_hdr_t;

typedef struct
{
  osal_event_hdr_t hdr;
  uint8  state;  
  uint8  keys; 
} keyChange_t;

 uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
 {
	 keyChange_t *msgPtr;
 	if ( registeredKeysTaskID != NO_TASK_ID )
  	{
     	// Send the address to the task
     	msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
    	if ( msgPtr )
     	{
     		msgPtr->hdr.event = KEY_CHANGE;
      		msgPtr->state = state;
       		msgPtr->keys = keys;
       		osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
    	}
		return ( SUCCESS );
 	}  
 	else
    	return ( FAILURE );
   }

//串口通信任务事件处理
uint16 Serial_Task_EventProcess(uint8 task_id,uint16 task_event)
{
	if ( task_event & SYS_EVENT_MSG )   	//判断系统消息事件
  	{
  		osal_sys_msg_t *MSGpkt;    			//定义一个指向接受系统消息结构体的指针
	    //从消息队列获取消息  
	    MSGpkt = (osal_sys_msg_t *)osal_msg_receive( task_id ); 
    
	    while ( MSGpkt )
	    {
	      	switch ( MSGpkt->hdr.event )  	//判断消息事件
	      	{
	          	case OSAL_PRINTF:
	          		break;

	        	default:
	          		break;
	      	}

	      	// Release the memory
	      	osal_msg_deallocate( (uint8 *)MSGpkt );

	      	// Next  获取下一个消息
	      	MSGpkt = (osal_sys_msg_t *)osal_msg_receive( task_id );
	    }

    	// return unprocessed events
    	return (task_event ^ SYS_EVENT_MSG);
  	}
  	
	if(task_event & PRINTF_STR)
	{
		static int dir = 1;

		if(dir)
		{
			dir = 0;
			LED0 = 0;
		}
		else
		{
			dir = 1;
			LED0 = 1;
		}
		
		Usart_Printf(COM1,"Linux GCC STM32F103 printf !\r\n");
	  	
		return task_event ^ PRINTF_STR;
	}

	return 0;
}

OSAL纯净版程序下载

https://download.csdn.net/download/lyrain2009/12837122


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值