FREERTOS任務(wù)通知模擬事件標(biāo)志組實(shí)驗(yàn)
代碼:
主程序
#include "./SYSTEM/sys/sys.h" #include "./SYSTEM/usart/usart.h" #include "./SYSTEM/delay/delay.h" #include "./BSP/LED/led.h" #include "./BSP/LCD/lcd.h" #include "./BSP/KEY/key.h" #include "./BSP/EXTI/exti.h" #include "freertos_demo.h" #include "./BSP/SDRAM/sdram.h" #include "./MALLOC/malloc.h" #define START_TASK_PRIO 1 #define START_STK_SIZE 128 const char *SRAM_NAME_BUF[SRAMBANK] = {" SRAMIN ", " SRAMCCM ", " SRAMEX "}; int main(void) { HAL_Init(); /* 初始化HAL庫(kù) */ sys_stm32_clock_init(360, 25, 2, 8); /* 設(shè)置時(shí)鐘,180Mhz */ delay_init(180); /* 延時(shí)初始化 */ usart_init(115200); /* 串口初始化為115200 */ //usmart_dev.init(90); /* 初始化USMART */ led_init(); /* 初始化LED */ key_init(); /* 初始化按鍵 */ sdram_init(); /* SRAM初始化 */ //lcd_init(); /* 初始化LCD */ extix_init(); my_mem_init(SRAMIN); /* 初始化內(nèi)部?jī)?nèi)存池 */ my_mem_init(SRAMEX); /* 初始化外部?jī)?nèi)存池 */ my_mem_init(SRAMCCM); /* 初始化CCM內(nèi)存池 */ // lcd_show_string(30, 50, 200, 16, 16, "STM32", RED); // lcd_show_string(30, 70, 200, 16, 16, "MALLOC TEST", RED); // lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED); // lcd_show_string(30, 110, 200, 16, 16, "KEY0:Malloc KEY2:Free", RED); // lcd_show_string(30, 130, 200, 16, 16, "KEY_UP:SRAMx KEY1:Read", RED); // lcd_show_string(60, 160, 200, 16, 16, " SRAMIN ", BLUE); // lcd_show_string(30, 176, 200, 16, 16, "SRAMIN USED:", BLUE); // lcd_show_string(30, 192, 200, 16, 16, "SRAMCCM USED:", BLUE); // lcd_show_string(30, 208, 200, 16, 16, "SRAMEX USED:", BLUE); freertos_demo(); }
freertos_demo.c
#include "freertos_demo.h" #include "./SYSTEM/usart/usart.h" #include "./BSP/LED/led.h" #include "./BSP/KEY/key.h" #include "./SYSTEM/delay/delay.h" /*FreeRTOS*********************************************************************************************/ #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "string.h" #include "limits.h" /******************************************************************************************************/ /*FreeRTOS配置*/ /* START_TASK 任務(wù) 配置 * 包括: 任務(wù)句柄 任務(wù)優(yōu)先級(jí) 堆棧大小 創(chuàng)建任務(wù) */ #define START_TASK_PRIO 1 /* 任務(wù)優(yōu)先級(jí) */ #define START_STK_SIZE 128 /* 任務(wù)堆棧大小 */ TaskHandle_t StartTask_Handler; /* 任務(wù)句柄 */ void start_task(void *pvParameters); /* 任務(wù)函數(shù) */ /* TASK1 任務(wù) 配置 * 包括: 任務(wù)句柄 任務(wù)優(yōu)先級(jí) 堆棧大小 創(chuàng)建任務(wù) */ #define EVENTSETBIT_PRIO 2 /* 任務(wù)優(yōu)先級(jí) */ #define EVENTSETBIT_STK_SIZE 128 /* 任務(wù)堆棧大小 */ TaskHandle_t EventSetBit_Handler; /* 任務(wù)句柄 */ void eventsetbit(void *pvParameters); /* 任務(wù)函數(shù) */ #define EVENTGROUP_PRIO 2 /* 任務(wù)優(yōu)先級(jí) */ #define EVENTGROUP_STK_SIZE 128 /* 任務(wù)堆棧大小 */ TaskHandle_t EventGroup_Handler; /* 任務(wù)句柄 */ void eventgroup(void *pvParameters); /* 任務(wù)函數(shù) */ #define KEYMSG_Q_NUM 1 /* 任務(wù)函數(shù) */ QueueHandle_t Key_Queue; #define EVENTBIT_0 (1<<0) #define EVENTBIT_1 (1<<1) #define EVENTBIT_2 (1<<2) #define EVENTBIT_ALL (EVENTBIT_1|EVENTBIT_2) /******************************************************************************************************/ /* LCD刷屏?xí)r使用的顏色 */ /** * @brief FreeRTOS例程入口函數(shù) * @param 無(wú) * @retval 無(wú) */ void freertos_demo(void) { xTaskCreate((TaskFunction_t )start_task, /* 任務(wù)函數(shù) */ (const char* )"start_task", /* 任務(wù)名稱(chēng) */ (uint16_t )START_STK_SIZE, /* 任務(wù)堆棧大小 */ (void* )NULL, /* 傳入給任務(wù)函數(shù)的參數(shù) */ (UBaseType_t )START_TASK_PRIO, /* 任務(wù)優(yōu)先級(jí) */ (TaskHandle_t* )&StartTask_Handler); /* 任務(wù)句柄 */ vTaskStartScheduler(); } /** * @brief start_task * @param pvParameters : 傳入?yún)?shù)(未用到) * @retval 無(wú) */ void start_task(void *pvParameters) { taskENTER_CRITICAL(); Key_Queue=xQueueCreate(KEYMSG_Q_NUM,sizeof(uint8_t)); /* 創(chuàng)建任務(wù)1 */ xTaskCreate((TaskFunction_t )eventsetbit, (const char* )"eventsetbit", (uint16_t )EVENTSETBIT_STK_SIZE, (void* )NULL, (UBaseType_t )EVENTSETBIT_PRIO, (TaskHandle_t* )&EventSetBit_Handler); xTaskCreate((TaskFunction_t )eventgroup, (const char* )"eventgroup", (uint16_t )EVENTGROUP_STK_SIZE, (void* )NULL, (UBaseType_t )EVENTGROUP_PRIO, (TaskHandle_t* )&EventGroup_Handler); // xTaskCreate((TaskFunction_t )eventgroup, // (const char* )"eventquery", // (uint16_t )EVENTQUERY_STK_SIZE, // (void* )NULL, // (UBaseType_t )EVENTQUERY_PRIO, // (TaskHandle_t* )&EventQuery_Handler); vTaskDelete(StartTask_Handler); /* 刪除開(kāi)始任務(wù) */ taskEXIT_CRITICAL(); /* 退出臨界區(qū) */ } /** * @brief task1 * @param pvParameters : 傳入?yún)?shù)(未用到) * @retval 無(wú) */ void eventsetbit(void *pvParameters) { uint8_t key; while(1) { if(EventGroup_Handler!=NULL) { key=key_scan(0); switch(key) { case KEY1_PRES: xTaskNotify(EventGroup_Handler,EVENTBIT_1,eSetBits); //xEventGroupSetBits(EventGroupHandle,EVENTBIT_1); break; case KEY2_PRES: xTaskNotify(EventGroup_Handler,EVENTBIT_2,eSetBits); //xEventGroupSetBits(EventGroupHandle,EVENTBIT_2); break; } } vTaskDelay(10); /* 延時(shí)1000ticks */ } } void eventgroup(void *pvParameters) { uint8_t num=0; static uint8_t eventvalue,event0flag,event1flag,event2flag; BaseType_t err; uint32_t NotifyValue; while(1) { err=xTaskNotifyWait(0,ULONG_MAX,&NotifyValue,portMAX_DELAY); if(err==pdPASS) { if(NotifyValue & EVENTBIT_0) { event0flag=1; } else if(NotifyValue & EVENTBIT_1) { event1flag=1; } else if(NotifyValue & EVENTBIT_2) { event2flag=1; } } eventvalue=event0flag|(event1flag<<1)|(event2flag<<2); printf("eventvalue =%#x\r\n",eventvalue); if(eventvalue==0x07) { num++; event0flag=0; event1flag=0; event2flag=0; printf("event running =%d\r\n",num); } } }
外部中斷程序:
#include "./SYSTEM/sys/sys.h" #include "./SYSTEM/delay/delay.h" #include "./BSP/LED/led.h" #include "./BSP/KEY/key.h" #include "./BSP/EXTI/exti.h" #include "FreeRTOS.h" #include "task.h" /** * @brief KEY0 外部中斷服務(wù)程序 * @param 無(wú) * @retval 無(wú) */ //extern TaskHandle_t Task2Task_Handler; #define EVENTBIT_0 (1<<0) /** * @brief KEY1 外部中斷服務(wù)程序 * @param 無(wú) * @retval 無(wú) */ extern TaskHandle_t EventGroup_Handler; /* 任務(wù)句柄 */ /** * @brief KEY2 外部中斷服務(wù)程序 * @param 無(wú) * @retval 無(wú) */ void KEY0_INT_IRQHandler(void) { //HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN); /* 調(diào)用中斷處理公用函數(shù),清除中斷標(biāo)志位 */ /* 退出時(shí)再清一次中斷,避免按鍵抖動(dòng)誤觸發(fā) */ delay_ms(20); /* 消抖 */ BaseType_t xYieldRequired,xHigherPriorityTaskWoken; //if (KEY0 == 0) { xTaskNotifyFromISR(EventGroup_Handler,EVENTBIT_0,eSetBits,&xHigherPriorityTaskWoken); /* LED0 狀態(tài)取反 */ portYIELD_FROM_ISR(xYieldRequired); } //portYIELD_FROM_ISR(xYieldRequired); __HAL_GPIO_EXTI_CLEAR_IT(KEY0_INT_GPIO_PIN); } /** * @brief WK_UP 外部中斷服務(wù)程序 * @param 無(wú) * @retval 無(wú) */ /** * @brief 中斷服務(wù)程序中需要做的事情 在HAL庫(kù)中所有的外部中斷服務(wù)函數(shù)都會(huì)調(diào)用此函數(shù) * @param GPIO_Pin:中斷引腳號(hào) * @retval 無(wú) */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { } /** * @brief 外部中斷初始化程序 * @param 無(wú) * @retval 無(wú) */ void extix_init(void) { GPIO_InitTypeDef gpio_init_struct; key_init(); gpio_init_struct.Pin = KEY0_INT_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; /* 下降沿觸發(fā) */ gpio_init_struct.Pull = GPIO_PULLUP; HAL_GPIO_Init(KEY0_INT_GPIO_PORT, &gpio_init_struct); /* KEY2配置為下降沿觸發(fā)中斷 */ /* 使能中斷線(xiàn)2 */ HAL_NVIC_SetPriority(KEY0_INT_IRQn, 6, 0); /* 搶占2,子優(yōu)先級(jí)2 */ HAL_NVIC_EnableIRQ(KEY0_INT_IRQn); /* 使能中斷線(xiàn)13 */ /* 使能中斷線(xiàn)0 */ }
效果圖:
*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。