MQX下隊列和socket(客戶端的)的編程

            硬件條件:飛思卡爾的二型集中器(基於Coretex-M4的飛思卡爾K60方案)  其中網卡芯片是AR8032  

            軟件條件: IAR開發平臺  MQX 系統

首先,創建一個自啓動任務   MQX_AUTO_START_TASK 

const TASK_TEMPLATE_STRUCT MQX_template_list[] =
 {
      /* Task Index,   Function,   Stack,  Priority,   Name,   Attributes,          Param, Time Slice */
      { 1,            Main_task,  2000L,   9,         "INIT",  MQX_AUTO_START_TASK, 0,     0 },
      {9,           NET_recv_task,    5200L,  10,    "NET_recv", 0, 0,     0 },
      {10,           NET_send_task,    6000L,  10,    "NET_send",  0, 0,     0},
      { 0 }
};

這裏要注意分配的棧空間。其中,第四 個參數爲 優先級。越大優先級越低,10比9的優先級小。分配  NET_recv_task 和NET_send_task爲10,讓他們並行。 

void Main_task( uint_32 temp)
{
_task_id  NET_recv_task_id;
_task_id  NET_send_task_id;
queue1 = (CHARQ_STRUCT_PTR)_mem_alloc_system((_mem_size)( sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + QUEUE_SIZE_1));
_CHARQ_INIT(queue1, QUEUE_SIZE_1);
   NET_recv_task_id=_task_create( 0, 9, 0);    //創建recv_task
   if (NET_recv_task_id == MQX_NULL_TASK_ID) { 
   printf("\n Could not create NET_recv_task\n"); 
   } 
   NET_send_task_id=_task_create( 0, 10, 0);    //創建send_task 
  if (NET_send_task_id == MQX_NULL_TASK_ID) { 
   printf("\n Could not create NET_recv_task\n"); 
   }
}

衆所周知,每個任務體都有個死循環。要想讓其他任務執行。最好在這個循環中有一個阻塞函數。或者用一個延時_time_delay(400); 這個當中的400  ms爲經驗值。


void NET_send_task(uint_32 temp)
{
// 網口檢測  check the internet device linking
//fix me!!!
   int i=0;
   int j=1;
   int send_length=0;
   uchar buff4;
   uchar buff3[1];
   
 
   while(1)
   {
      printf("Andy: FILE %s FUNCTION %s LINE %d  j is %d \n",__FILE__,__FUNCTION__,__LINE__,j);
      init_NET(0);           //初始化網絡,並建立起已經連接的套接字
_time_delay(400);  //讓出時間片
printf("Andy: FILE %s FUNCTION %s LINE %d  j is %d \n",__FILE__,__FUNCTION__,__LINE__,j);
     while(flag)      
      {                  
      flag=0;
uchar buf[]={0x68,0x32,0x00,0x32,0x00,0x68,0xC9,0x01,0x35,0x01,0x00,0x00,0x02,0x70,0x00,0x00,0x01,0x00,0x73, 0x16};
send_length=send(sockClient,buf,sizeof(buf),0);
printf("Andy: FILE %s FUNCTION %s LINE %d  send_length is %d  j is %d\n",__FILE__,__FUNCTION__,__LINE__,send_length,j);
      }                  
      printf("\nthe sizeof queue is %d \n",_CHARQ_SIZE(queue1));
     while( (send_length>0)&(!_CHARQ_EMPTY(queue1)))
 {
 _CHARQ_DEQUEUE(queue1, buff4);
printf("Andy :  FUNCTION %s :the char in queue is  %02x\n",__FUNCTION__,buff4);
 }
   }
  
}
  這裏向服務端發送一個約定好的心跳包。

/* 
FUCTION:  NET_recv_task
comments: 通過以太網接受數據
*/
 void NET_recv_task(uint_32 temp)
 {
	uint_32 i;
	_queue_id server_qid;
	uchar buf1[1024]={0};
	int recv_length;
	int send_length;
	uchar buff4;   
	TIME_STRUCT time;
	uint_32 End_Time;
	uint_32 Start_Time;
	_time_get(&time);
	End_Time=time.SECONDS*1000 + time.MILLISECONDS;
	Start_Time=End_Time;

while(1)
   {
	while(1==( recv_length=recv(sockClient,buf1,1,0)))
	{ 
	      if(recv_length>0)
		  my_printf(buf1,recv_length);      // 對接收到的數據進行處理
	       _CHARQ_ENQUEUE(queue1, buf1[0]);
		printf("recv_length is %d the recv data is  : \n",recv_length);
		
	}
	
   //一分鐘接收不到任何數據,讓send_task 發送一個心跳包
           _time_get(&time);
            End_Time=time.SECONDS*1000 + time.MILLISECONDS;
	  printf(" End_Time is %d, Start_Time is %d\n",End_Time,Start_Time);
	   if(1==recv_length)  
	   	{
	   	Start_Time=End_Time;
	   	}
	   else
	   	{
               if(( End_Time-Start_Time)>60000)
               	{
               		printf(" End_Time is %d, Start_Time is %d\n",End_Time,Start_Time);
               		Start_Time=End_Time;
					flag=1;
               	}
	    }


	_time_delay(400);  //讓出時間片
     }

 }

1.隊列的操作

        隊列是MQX 任務之間輕量級的傳遞數據的工具。文檔《Freescale MQX 實時操作系統用戶手冊》中對列的描述如下:

                                      

       


              這個隊列在操作系統中,應用很廣泛。個人感覺這QUEUE_STRUCT 主要用設備驅動方面(mqx\source\kernel\Queue.c)。把表示設備的結構體鏈接到內核裏面。不太適合,一個字符進入,一個字符出來的情況。這裏主要使用   CHARQ_STRUCT  (mqx\source\include\charq.h)。 值得注意是這個隊列的初始化,並不是在這個頭文件中   _CHARQ_INIT(cq,max_size) 。在申請隊列大小時需要爲它分配空間。

          queue1 = (CHARQ_STRUCT_PTR)_mem_alloc_system((_mem_size)( sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + QUEUE_SIZE_1));              

CHARQ_STRUCT  結構體定義如下:

typedef struct charq_struct
{
      /*! 
    * \brief The maximum number of characters for the queue, as specified in
    * initialization of the queue.
    */
   _mqx_uint  MAX_SIZE;   
   /*! \brief The current number of characters in the queue. */
   _mqx_uint  CURRENT_SIZE;  
   /*! \brief Index of the first character in queue. */
   _mqx_uint  HEAD;          
   /*! \brief Index of the last character in queue. */
   _mqx_uint  TAIL;          
   /*! \brief The character queue itself. */
   char      QUEUE[4];
} CHARQ_STRUCT, _PTR_ CHARQ_STRUCT_PTR;

 申請的結構的在內存中的分佈如下:




   
 2.MQX中的網絡操作

             RTCS_create() 通信組件起來之後,ENET_initialize(.....) 初始化網絡之後,在於本機(集中器)的IP綁定。然後常規的TCP客戶端操作即可以聯上。

在ENET_initialize(...)之後,我們會得到一個句柄(ehandle)  ,通過( ENET_link_status(ehandle))可以得到這個時候機器的網線插拔狀態。

    



發佈了28 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章