FreeRTOS隊列

在實際應用中,我們會遇到一個任務或者中斷服務需要和另一個任務進行消息傳遞,FreeRTOS提供了隊列的機制來完成任務與任務、任務與中斷之間的消息傳遞。

0x01 隊列簡介

隊列是為了任務與任務、任務與中斷之間的通信而準備的,可以在任務與任務、任務與中斷之間傳遞消息,隊列中可以存儲有限的、大小固定的數據項目。隊列中能保存的最大數據項目數量叫做隊列的長度。

1. 數據存儲

隊列提供了FIFO、LIFO的存儲緩沖機制,數據發送到隊列中會導致數據拷貝,數據拷貝是值傳遞,在隊列中存儲的是數據的原始值,而不是原始值的引用(即值傳遞數據的引用),FreeRTOS中使用隊列傳遞消息的話雖然使用的是數據拷貝,但是也可以使用引用來傳遞消息,直接往隊列中發送指向這個消息的地址指針就可以了。

2. 多任務訪問

隊列不屬于某個特別指定的任務,任何任務都可以向隊列中發送消息,提取消息

0x02 隊列結構體

隊列的類型是Queue_t,定義在queue.c文件中

typedef struct QueueDefinition
{int8_t *pcHead;					/*< Points to the beginning of the queue storage area. */int8_t *pcTail;					/*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */int8_t *pcWriteTo;				/*< Points to the free next place in the storage area. */union							/* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */{int8_t *pcReadFrom;			/*< Points to the last place that a queued item was read from when the structure is used as a queue. */UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */} u;List_t xTasksWaitingToSend;		/*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */List_t xTasksWaitingToReceive;	/*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */UBaseType_t uxLength;			/*< The length of the queue defined as the number of items it will hold, not the number of bytes. */UBaseType_t uxItemSize;			/*< The size of each items that the queue will hold. */volatile int8_t cRxLock;		/*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */volatile int8_t cTxLock;		/*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )uint8_t ucStaticallyAllocated;	/*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */#endif#if ( configUSE_QUEUE_SETS == 1 )struct QueueDefinition *pxQueueSetContainer;#endif#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t uxQueueNumber;uint8_t ucQueueType;#endif} xQUEUE;/* The old xQUEUE name is maintained above then typedefed to the new Queue_t
name below to enable the use of older kernel aware debuggers. */
typedef xQUEUE Queue_t;
  • pcHead:指向隊列存儲區首地址
  • pcTail:指向隊列存儲區最后一個字節地址
  • pcWriteTo:指向下一個可以存儲的地址
  • pcReadFrom:當用作隊列的時候,指向最后一個出隊的隊列項首地址
  • uxRecursiveCallCount:當用作遞歸互斥量的時候用來記錄遞歸互斥量被調用的次數
  • xTasksWaitingToSend:等待發送任務列表,那些因為隊列滿導致入隊失敗而進入阻塞態的任務就會掛到此列表上
  • xTasksWaitingToReceive:等待接受任務列表,那些因為隊列空導致出隊失敗而進入阻塞態的任務就會掛到此列表上
  • uxMessagesWaiting:隊列中當前消息數
  • uxLength:隊列中最大允許的消息數量
  • uxItemSize:每個消息最大長度
  • cRxLock:當列表上鎖后,統計出隊的消息數量
  • cTxLock:當列表上鎖后,統計入隊的消息數量

0x03 隊列創建

隊列創建有兩種方法:

  1. 方法1:使用xQueueCreate函數動態創建
  2. 方法2:使用xQueueCreateStatic動態創建
1. xQueueCreate

從源碼可以看出,使用xQueueCreate,configSUPPORT_DYNAMIC_ALLOCATION 要等于1,支持動態分配內存

 QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength,UBaseType_t uxItemSize)
  • uxQueueLength:要創建的隊列的隊列長度,即最多可以接受多少個消息
  • uxItemSize :隊列中每個消息的長度

創建成功返回隊列句柄,失敗返回NULL

2.xQueueCreateStatic
 QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength,UBaseType_t uxItemSize,uint8_t *pucQueueStorageBuffer,StaticQueue_t *pxQueueBuffer);
  • uxQueueLength:要創建的隊列的隊列長度,即最多可以接受多少個消息
  • uxItemSize :隊列中每個消息的長度
  • pucQueueStorage:指向消息的存儲區,是一個uint8_t類型的數組,數組的大小要大于等于(uxQueueLength*uxItemSize )
  • pxQueueBuffer :保存隊列結構體

創建成功返回隊列句柄,失敗返回NULL

0x04 向隊列發送消息

1. 函數原型

創建好隊列就可以向隊列發送消息了,FreeRTOS提供了8個向對列發送消息的API函數。
在這里插入圖片描述

1.1 xQueueSend、xQueueSendToBack、xQueueSendToToFront
 BaseType_t xQueueSend(QueueHandle_t xQueue,const void * pvItemToQueue,TickType_t xTicksToWait);BaseType_t xQueueSendToBack(QueueHandle_t	xQueue,const void		*pvItemToQueue,TickType_t		xTicksToWait);BaseType_t xQueueSendToToFront(QueueHandle_t	xQueue,const void		*pvItemToQueue,TickType_t		xTicksToWait);
  • QueueHandle_t xQueue:任務句柄,指明要向那個隊列發送數據
  • const void *pvItemToQueue:指向要發送的數據,發送的時候會將這個消息拷貝到隊列中
  • TickType_t xTicksToWait:阻塞時間,此參數指示隊列滿的時候任務進入阻塞態等待隊列空閑的最大時間,如果是0,隊列滿會立即返回,當為portMAX_DELAY就會一直等待。

成功返回pdPASS,失敗返回errQUEUE_FULL

1.2 xQueueOverwrite
 BaseType_t xQueueOverwrite(QueueHandle_t xQueue,const void * pvItemToQueue);
  • QueueHandle_t xQueue:隊列句柄,指明要向那個隊列發送數據
  • const void * pvItemToQueue:要發送的數據
1.3 xQueueSendFromISR、xQueueSendToBackFromISR、xQueueSendToFrontFromISR
 BaseType_t xQueueSendFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);BaseType_t xQueueSendToBackFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue,const void *pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);BaseType_t xQueueOverwriteFromISR(QueueHandle_t xQueue,const void * pvItemToQueue,BaseType_t *pxHigherPriorityTaskWoken);
  • QueueHandle_t xQueue:隊列句柄,指明要向那個隊列發送數據
  • const void *pvItemToQueue:要發送的數據
  • BaseType_t *pxHigherPriorityTaskWoken:標記退出此函數以后是否進行任務切換,這個變量由三個函數來設置,用戶不用進行設置,用戶只需提供一個變量來保存這個值就行了。當此值為pdTRUE的時候在退出中斷服務函數之前一定要進行一次任務切換。

成功返回pdTURE,失敗返回errQUEUE_FULL

0x05 從隊列讀取消息

從隊列中獲取消息,FreeRTOS相關API函數如下
在這里插入圖片描述

1. xQueueReceive、xQueuePeek
BaseType_t xQueueReceive(QueueHandle_t xQueue,void *pvBuffer,TickType_t xTicksToWait)BaseType_t xQueuePeek(QueueHandle_t xQueue,void *pvBuffer,TickType_t xTicksToWait);
  • QueueHandle_t xQueue:指明讀取那個隊列的數據
  • void *pvBuffer:讀取隊列的過程中將讀取的數據拷貝到這個緩沖區
  • TickType_t xTicksToWait:阻塞時間,如果為0,隊列為空立即返回,當為portMAX_DELAY的話就一直等待,直到隊列有數據。
2. xQueueReceiveFromISR
 BaseType_t xQueueReceiveFromISR(QueueHandle_t	xQueue,void	*pvBuffer,BaseType_t *pxTaskWoken);BaseType_t xQueuePeekFromISR(QueueHandle_t xQueue,void *pvBuffer,);
  • QueueHandle_t xQueue:指明讀取那個隊列的數據
  • void *pvBuffer:讀取隊列的過程中將讀取的數據拷貝到這個緩沖區
  • BaseType_t *pxTaskWoken:標記退出此函數以后是否進行任務切換

返回值:
返回pdTRUE,從隊列中讀取數據成功,返回pdFALSE,從隊列中讀取數據失敗。

驗證

實驗設計三個任務,start_task、task1_task、Keyprocess_task這三個任務。
start_task:用來創建其他兩個任務
task1_task:讀取按鍵的鍵值,然后將鍵值發送到KEY_Queue隊列中,并且檢查隊列的剩余容量等信息
Keyprocess_task:按鍵處理任務,讀取隊列Key_Queue中的信息,根據不同的消息值做相應的處理。
實驗需要是哪個按鍵KEY_UP、KEY2、KEY0,不同的按鍵對應不同的按鍵值,任務task1_task會將這些值發送到隊列Key_Queue中。
實驗中創建兩個隊列Key_Queue和Message_Queue,隊列Key_Queue用于傳遞按鍵值,隊列Message_Queue用于傳遞串口發送過來的消息。
實驗還需要兩個中斷,一個是串口1接收中斷,一個是定時器9中斷,他們的作用如下:串口1接收中斷,接收串口發送過來的數據,并將接收到的數據發送到隊列Message_Queue中,定時器9中斷,定時周期為500ms,在定時器中斷中讀取隊列Message_Queue中的消息,并將其顯示在LCD上。

start_task代碼:

//開始任務任務函數
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //進入臨界區//創建消息隊列Key_Queue=xQueueCreate(KEYMSG_Q_NUM,sizeof(u8));        //創建消息Key_QueueMessage_Queue=xQueueCreate(MESSAGE_Q_NUM,USART_REC_LEN); //創建消息Message_Queue,隊列項長度是串口接收緩沖區長度//創建TASK1任務xTaskCreate((TaskFunction_t )task1_task,             (const char*    )"task1_task",           (uint16_t       )TASK1_STK_SIZE,        (void*          )NULL,                  (UBaseType_t    )TASK1_TASK_PRIO,        (TaskHandle_t*  )&Task1Task_Handler);   //創建TASK2任務xTaskCreate((TaskFunction_t )Keyprocess_task,     (const char*    )"keyprocess_task",   (uint16_t       )KEYPROCESS_STK_SIZE,(void*          )NULL,(UBaseType_t    )KEYPROCESS_TASK_PRIO,(TaskHandle_t*  )&Keyprocess_Handler); vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL();            //退出臨界區
}

在start_task中創建了兩個隊列,分別是Key_Queue和Message_Queue,Key_Queue用于和按鍵通信,Message_Queue用于和串口通信。

task1_task代碼

//task1任務函數
void task1_task(void *pvParameters)
{u8 key,i=0;BaseType_t err;while(1){key=KEY_Scan(0);            //掃描按鍵if((Key_Queue!=NULL)&&(key))   //消息隊列Key_Queue創建成功,并且按鍵被按下{err=xQueueSend(Key_Queue,&key,10);if(err==errQUEUE_FULL)   //發送按鍵值{printf("隊列Key_Queue已滿,數據發送失敗!\r\n");}}i++;if(i%10==0) check_msg_queue();//檢Message_Queue隊列的容量if(i==50){i=0;LED0=!LED0;}vTaskDelay(10);                           //延時10ms,也就是10個時鐘節拍	}
}

task1_task獲取按鍵值,并將按鍵值發送到Key_Queue中

Keyprocess_task代碼:

//Keyprocess_task函數
void Keyprocess_task(void *pvParameters)
{u8 num,key,beepsta=1;while(1){if(Key_Queue!=NULL){if(xQueueReceive(Key_Queue,&key,portMAX_DELAY))//請求消息Key_Queue{switch(key){case WKUP_PRES:		//KEY_UP控制LED1LED1=!LED1;break;case KEY1_PRES:		//KEY1控制蜂鳴器beepsta=!beepsta;BEEP=beepsta;break;case KEY0_PRES:		//KEY0刷新LCD背景num++;LCD_Fill(126,111,233,313,lcd_discolor[num%14]);break;}}} vTaskDelay(10);      //延時10ms,也就是10個時鐘節拍	}
}

Keyprocess_task獲取Key_Queue隊列中按鍵值

整個main.c代碼如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "sdram.h"
#include "key.h"
#include "timer.h"
#include "beep.h"
#include "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/************************************************ALIENTEK 水星STM32F429開發板 FreeRTOS實驗13-1FreeRTOS隊列操作實驗-HAL庫版本技術支持:www.openedv.com淘寶店鋪:http://eboard.taobao.com 關注微信公眾平臺微信號:"正點原子",免費獲取STM32資料。廣州市星翼電子科技有限公司  作者:正點原子 @ALIENTEK
************************************************///任務優先級
#define START_TASK_PRIO		1
//任務堆棧大小	
#define START_STK_SIZE 		256  
//任務句柄
TaskHandle_t StartTask_Handler;
//任務函數
void start_task(void *pvParameters);//任務優先級
#define TASK1_TASK_PRIO		2
//任務堆棧大小	
#define TASK1_STK_SIZE 		256  
//任務句柄
TaskHandle_t Task1Task_Handler;
//任務函數
void task1_task(void *pvParameters);//任務優先級
#define KEYPROCESS_TASK_PRIO 3
//任務堆棧大小	
#define KEYPROCESS_STK_SIZE  256 
//任務句柄
TaskHandle_t Keyprocess_Handler;
//任務函數
void Keyprocess_task(void *pvParameters);//按鍵消息隊列的數量
#define KEYMSG_Q_NUM    1  		//按鍵消息隊列的數量  
#define MESSAGE_Q_NUM   4   	//發送數據的消息隊列的數量 
QueueHandle_t Key_Queue;   		//按鍵值消息隊列句柄
QueueHandle_t Message_Queue;	//信息隊列句柄//LCD刷屏時使用的顏色
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      GRED,  GBLUE, RED,   MAGENTA,       	 GREEN, CYAN,  YELLOW,BROWN, 			BRRED, GRAY };//用于在LCD上顯示接收到的隊列的消息
//str: 要顯示的字符串(接收到的消息)
void disp_str(u8* str)
{LCD_Fill(5,230,110,245,WHITE);					//先清除顯示區域LCD_ShowString(5,230,100,16,16,str);
}//加載主界面
void freertos_load_main_ui(void)
{POINT_COLOR = RED;LCD_ShowString(10,10,200,16,16,"Apollo STM32F4/F7");	LCD_ShowString(10,30,200,16,16,"FreeRTOS Examp 13-1");LCD_ShowString(10,50,200,16,16,"Message Queue");LCD_ShowString(10,70,220,16,16,"KEY_UP:LED1 KEY0:Refresh LCD");LCD_ShowString(10,90,200,16,16,"KEY1:SendMsg KEY2:BEEP");POINT_COLOR = BLACK;LCD_DrawLine(0,107,239,107);		//畫線LCD_DrawLine(119,107,119,319);		//畫線LCD_DrawRectangle(125,110,234,314);	//畫矩形POINT_COLOR = RED;LCD_ShowString(0,130,120,16,16,"DATA_Msg Size:");LCD_ShowString(0,170,120,16,16,"DATA_Msg rema:");LCD_ShowString(0,210,100,16,16,"DATA_Msg:");POINT_COLOR = BLUE;
}//查詢Message_Queue隊列中的總隊列數量和剩余隊列數量
void check_msg_queue(void)
{u8 *p;u8 msgq_remain_size;	//消息隊列剩余大小u8 msgq_total_size;     //消息隊列總大小taskENTER_CRITICAL();   //進入臨界區msgq_remain_size=uxQueueSpacesAvailable(Message_Queue);//得到隊列項剩余大小msgq_total_size=uxQueueMessagesWaiting(Message_Queue)+uxQueueSpacesAvailable(Message_Queue);//得到隊列總大小,總大小=使用+剩余的。p=mymalloc(SRAMIN,20);	//申請內存sprintf((char*)p,"Total Size:%d",msgq_total_size);	//顯示DATA_Msg消息隊列總的大小LCD_ShowString(10,150,100,16,16,p);sprintf((char*)p,"Remain Size:%d",msgq_remain_size);	//顯示DATA_Msg剩余大小LCD_ShowString(10,190,100,16,16,p);myfree(SRAMIN,p);		//釋放內存taskEXIT_CRITICAL();    //退出臨界區
}int main(void)
{HAL_Init();                     //初始化HAL庫   Stm32_Clock_Init(360,25,2,8);   //設置時鐘,180Mhzdelay_init(180);                //初始化延時函數uart_init(115200);              //初始化串口LED_Init();                     //初始化LED KEY_Init();                     //初始化按鍵BEEP_Init();                 	//初始化蜂鳴器SDRAM_Init();                   //初始化SDRAMLCD_Init();                     //初始化LCDTIM9_Init(5000,18000-1);		//初始化定時器9,周期500msmy_mem_init(SRAMIN);            //初始化內部內存池freertos_load_main_ui();        //加載主UI//創建開始任務xTaskCreate((TaskFunction_t )start_task,            //任務函數(const char*    )"start_task",          //任務名稱(uint16_t       )START_STK_SIZE,        //任務堆棧大小(void*          )NULL,                  //傳遞給任務函數的參數(UBaseType_t    )START_TASK_PRIO,       //任務優先級(TaskHandle_t*  )&StartTask_Handler);   //任務句柄                vTaskStartScheduler();          //開啟任務調度
}//開始任務任務函數
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //進入臨界區//創建消息隊列Key_Queue=xQueueCreate(KEYMSG_Q_NUM,sizeof(u8));        //創建消息Key_QueueMessage_Queue=xQueueCreate(MESSAGE_Q_NUM,USART_REC_LEN); //創建消息Message_Queue,隊列項長度是串口接收緩沖區長度//創建TASK1任務xTaskCreate((TaskFunction_t )task1_task,             (const char*    )"task1_task",           (uint16_t       )TASK1_STK_SIZE,        (void*          )NULL,                  (UBaseType_t    )TASK1_TASK_PRIO,        (TaskHandle_t*  )&Task1Task_Handler);   //創建TASK2任務xTaskCreate((TaskFunction_t )Keyprocess_task,     (const char*    )"keyprocess_task",   (uint16_t       )KEYPROCESS_STK_SIZE,(void*          )NULL,(UBaseType_t    )KEYPROCESS_TASK_PRIO,(TaskHandle_t*  )&Keyprocess_Handler); vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL();            //退出臨界區
}//task1任務函數
void task1_task(void *pvParameters)
{u8 key,i=0;BaseType_t err;while(1){key=KEY_Scan(0);            //掃描按鍵if((Key_Queue!=NULL)&&(key))   //消息隊列Key_Queue創建成功,并且按鍵被按下{err=xQueueSend(Key_Queue,&key,10);if(err==errQUEUE_FULL)   //發送按鍵值{printf("隊列Key_Queue已滿,數據發送失敗!\r\n");}}i++;if(i%10==0) check_msg_queue();//檢Message_Queue隊列的容量if(i==50){i=0;LED0=!LED0;}vTaskDelay(10);                           //延時10ms,也就是10個時鐘節拍	}
}//Keyprocess_task函數
void Keyprocess_task(void *pvParameters)
{u8 num,key,beepsta=1;while(1){if(Key_Queue!=NULL){if(xQueueReceive(Key_Queue,&key,portMAX_DELAY))//請求消息Key_Queue{switch(key){case WKUP_PRES:		//KEY_UP控制LED1LED1=!LED1;break;case KEY1_PRES:		//KEY1控制蜂鳴器beepsta=!beepsta;BEEP=beepsta;break;case KEY0_PRES:		//KEY0刷新LCD背景num++;LCD_Fill(126,111,233,313,lcd_discolor[num%14]);break;}}} vTaskDelay(10);      //延時10ms,也就是10個時鐘節拍	}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379737.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379737.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379737.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

括號配對問題(C)

描述 現在&#xff0c;有一行括號序列&#xff0c;請你檢查這行括號是否配對。 輸入 第一行輸入一個數N&#xff08;0<N<100&#xff09;,表示有N組測試數據。后面的N行輸入多組輸入數據&#xff0c;每組輸入數據都是一個字符串S(S的長度小于10000&#xff0c;且S不是空串…

劇情介紹:“阿甘正傳”

阿甘是個智商只有75的低能兒。在學校里為了躲避別的孩子的欺侮&#xff0c;聽從一個朋友珍妮的話而開始“跑”。他跑著躲避別人的捉弄。在中學時&#xff0c;他為了躲避別人而跑進了一所學校的橄欖球場&#xff0c;就這樣跑進了大學。阿甘被破格錄取&#xff0c;并成了橄欖球巨…

java 方法 示例_Java集合syncedList()方法與示例

java 方法 示例集合類syncList()方法 (Collections Class synchronizedList() method) synchronizedList() method is available in java.util package. syncList()方法在java.util包中可用。 synchronizedList() method is used to return the synchronized view of the given…

FreeRTOS信號量---二值信號量

信號量可以用來進行資源管理和任務同步&#xff0c;FreeRTOS中信號量又分為二值信號量、計算型信號量、互斥信號量和遞歸互斥信號量。 0x01 二值信號量 二值信號量其實就是一個只有一個隊列項的隊列&#xff0c;這個特殊的隊列要么是滿的&#xff0c;要么是空的&#xff0c;任…

Linux 上 rpm包管理工具的基本使用

查詢是否安裝某個包&#xff1a;rpm -q 包名查詢所有已安裝的包&#xff1a;rpm -q a查詢未安裝包的文件信息&#xff1a;rpm -qilp 未安裝的包安裝包&#xff1a;rpm -i 包測試安裝包&#xff1a;rpm -i test 包刪除包&#xff1a;rpm -e 包名測試刪除包&#xff1a;rpm -e te…

ios 內存使用陷阱

在iphone開發過程中&#xff0c;代碼中的內存泄露我們很容易用內存檢測工具leaks 檢測出來&#xff0c;并一一改之&#xff0c;但有些是因為ios 的缺陷和用法上的錯誤&#xff0c;leaks 檢測工具并不能檢測出來&#xff0c;你只會看到大量的內存被使用&#xff0c;最后收到didR…

FreeRTOS軟件定時器

軟件定時器允許設置一段時間&#xff0c;當設置的時間達到后就執行指定的功能函數&#xff0c;被軟件定時器調用的功能函數叫做定時器的回調函數。軟件定時器的回調函數是在定時器服務任務中執行的&#xff0c;所以一定不能在回調函數中調用任何阻塞任務的API函數&#xff0c;比…

Java類class isAssignableFrom()方法及示例

類class isAssignableFrom()方法 (Class class isAssignableFrom() method) isAssignableFrom() method is available in java.lang package. isAssignableFrom()方法在java.lang包中可用。 isAssignableFrom() method is used to check whether the class or an interface den…

關于 列表實例

wss3.0工具中有個列表實例項目。此項目的作用是在自定義網站或自定義字段時使用默認值。也就是定義其默認的數據。 格式詳見微軟msdn&#xff1a;http://msdn.microsoft.com/zh-cn/library/ms478860.aspx轉載于:https://www.cnblogs.com/heavencloud/archive/2009/03/20/141793…

WP7之Application Bar控件

Microsoft.Phone.Shell命名空間中定義了ApplicationBar及其相關類&#xff08;ApplicationBarIconButton和ApplicationBarMenuItem&#xff09;&#xff0c;這些類派生自Object,并完全獨立于常規Silverlight編程中的DependencyObject,UIElement和FrameworkElement類層次結構。A…

TomCat使用以及端口號被占用的處理方法

一.HTTP協議 什么是HTTP協議 HTTP協議&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是因特網上應用最為廣泛的一種網絡傳輸協議&#xff0c;所有的WWW文件都必須遵守這個標準。 HTTP請求 HTTP響應 2.如何處理端口被占用 方法一&#xff…

FreeRTOS事件標志組

使用信號量來同步的話&#xff0c;任務只能與單個事務或任務進行同步&#xff0c;有時候某個任務可能會需要與多個事件或任務進行同步&#xff0c;此時信號量就無能為力了&#xff0c;FreeRTOS為此提供了一個可選的解決方法&#xff0c;那就是事件標志組。 0x01 事件標志組 事…

FusionCharts等產品簡介

以前做柱狀圖、餅形圖等圖表都是根據數據繪制出來的靜態圖&#xff0c;偶然看到別人的一套系統&#xff0c;居然可以讓柱狀圖的柱子動畫般的逐個出現&#xff0c;效果還是很不錯的。不要跟我抬杠說不就是展現數據嘛&#xff0c;靜態圖表有什么不好&#xff0c;要知道用戶一般可…

c#foreach循環_C#| 使用foreach循環打印整數數組

c#foreach循環Given an integer array and we have to print its elements using "foreach loop" in C#. 給定一個整數數組&#xff0c;我們必須在C&#xff03;中使用“ foreach循環”打印其元素 。 Syntax for foreach loop: foreach循環的語法&#xff1a; fore…

Eclipse和Tomcat綁定并且將上傳資源到Tomcat上

步驟如下&#xff1a; 創建一個Dynamic Web Project&#xff08;圖一&#xff09; Target runtime 選擇Apache Tomcat v7.0版本&#xff08;圖二&#xff09; 切記要選擇 v7.0 和2.5 &#xff08;若沒有圖二選項見圖三&#xff09; 然后&#xff0c;點擊window --> Prefer…

淺析.NET平臺編程語言的未來走向

在去年的PDC2008召開期間&#xff0c;微軟逐步公開了圍繞.NET和編程語言的很多想法&#xff0c;據此我們可以饒有興趣地對.NET的未來預測一番。 .NET平臺以運行在通用語言運行時(Common Language Runtime&#xff0c;CLR)上的C#和VB.NET作為開端。CLR是通用語言架構(Common Lan…

FreeRTOS任務通知

從v8.2.0版本開始&#xff0c;FreeRTOS新增了任務通知這個功能&#xff0c;可以使用任務通知來代替信號量、消息隊列、事件標志組等這些東西&#xff0c;使用任務通知的話效率會更高。 任務通知在FreeRTOS是一個可選的選項&#xff0c;要使用任務通知的話就需要將宏configUSE_T…

kinect在openni下也能玩摳出人物換背景

之前想了個很拉風的名字《用kinect玩穿越》&#xff0c;但是現在功能還不是很完善&#xff0c;細節處理也不是很好&#xff0c;臉皮沒有足夠的厚&#xff0c;所以呢還是叫換背景吧。 這里面包含兩個技術要點&#xff1a; 一、摳出活動人物 在微軟的SDK里深度圖像的前3位即0-2位…

物聯網基礎知識_聯網| 基礎知識能力問答 套裝1

物聯網基礎知識1) There are the following statements that are given below, which of them are correct about the computer network? A computer network is an interconnection between multiple devices to share hardware resources and information.A computer networ…

Emit學習-基礎篇-基本概念介紹

之前的Hello World例子應該已經讓我們對Emit有了一個模糊的了解&#xff0c;那么Emit到底是什么樣一個東西&#xff0c;他又能實現些什么功能呢&#xff1f;昨天查了點資料&#xff0c;大致總結了下&#xff0c;由于才開始學習肯定有不完善的地方&#xff0c;希望大家能夠批評指…