FreeRTOS教程3 中斷管理

来源:https://www.cnblogs.com/lc-guo/p/18068231
-Advertisement-
Play Games

本文主要學習 FreeRTOS 中斷管理的相關知識,包括系統硬體中斷、 FreeRTOS 可管理的中斷、中斷屏蔽和一些其他註意事項等知識 ...


1、準備材料

正點原子stm32f407探索者開發板V2.4

STM32CubeMX軟體(Version 6.10.0

Keil µVision5 IDE(MDK-Arm

野火DAP模擬器

XCOM V2.6串口助手

2、學習目標

本文主要學習 FreeRTOS 中斷管理的相關知識,包括系統硬體中斷、 FreeRTOS 可管理的中斷、中斷屏蔽和一些其他註意事項等知識

3、前提知識

3.1、STM32 的硬體中斷

根據STM32CubeMX教程4 EXTI 按鍵外部中斷實驗 “3、中斷系統概述表” 小節內容可知

  1. STM32F4 系列有 10 個系統中斷和82個可屏蔽的外部中斷
  2. 嵌套向量中斷控制器(NVIC)採用 4 位二進位數表示中斷優先順序,這 4 位二進位數表示的中斷優先順序又分為了搶占優先順序和次優先順序

當啟用FreeRTOS之後,NVIC中斷分組策略採用 4 位搶占優先順序且不可修改,對於 STM32 的硬體優先順序來說,優先順序數字越小表示優先順序越高,最高優先順序為0,如下所示為 STM32 的中斷列表

3.2、FreeRTOS 可管理的中斷

對於 STM32 處理器所有的硬體中斷來說,其中有些可以被 FreeRTOS 軟體管理,而有些特別重要的中斷則不能夠被 FreeRTOS 軟體所管理,這很好理解,比如系統的硬體 Reset 中斷,如果 Reset 中斷可以被FreeRTOS所管理,那麼在系統死機時用戶需要硬體複位,但 FreeRTOS 不能響應最終導致無法複位從而卡死

那麼哪些硬體中斷可以被 FreeRTOS 所管理呢?

這由 configLIBRARY_LOWEST_INTERRUPT_PRIORITY (中斷的最低優先順序數值) 和 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (FreeRTOS可管理的最高優先順序) 兩個參數決定,由於 NVIC 中斷分組策略採用 4 位搶占優先順序,因此中斷最低優先順序數值為 15 ,而 FreeRTOS 可管理的最高優先順序預設設置為 5

當配置參數 configLIBRARY_LOWEST_INTERRUPT_PRIORITY = 15 , configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 5 時,則表示在 STM32 的所有硬體中斷中優先順序為 0~4 的中斷 FreeRTOS 不可管理,而對於中斷優先順序為 5~15 的中斷 FreeRTOS 可以管理,具體如下圖所示

3.3、何為上下文?

在操作系統和嵌入式系統中,上下文(Context)是指程式執行過程中的當前狀態,包括所有的寄存器值、程式計數器(PC)值以及其他與執行環境相關的狀態信息。上下文記錄了程式執行的位置和狀態,使得程式可以在中斷、任務切換或函數調用等場景下進行正確的恢復和繼續執行

在 FreeRTOS 中,上下文通常與任務(Task)或中斷處理函數相關聯。當任務切換髮生時,當前任務的上下文會被保存,然後將控制權轉移到下一個任務,該任務的上下文會被恢復以便繼續執行。類似地,當中斷發生時,處理器會保存當前執行任務的上下文,併在中斷處理完畢後,恢復之前任務的上下文以繼續執行。

3.4、在 ISR 中使用 FreeRTOS API 函數

3.4.1、中斷安全版本 API

通常需要在中斷服務常式 (ISR) 中使用 FreeRTOS API 函數提供的功能,但許多 FreeRTOS API 函數執行的操作在 ISR 內無效,比如能夠讓任務進入阻塞狀態的 API 函數,如果從 ISR 調用這些 API 函數,因為它不是從任務調用,所以沒有有效的調用任務使其進入阻塞狀態

因此對於一些 API 函數,FreeRTOS 提供了兩種不同版本,一種版本供任務使用,另一種版本供 ISR 使用,在 ISR 中使用的函數名稱後面帶有 “FromISR” 的尾碼,關於這種設計的優缺點,感興趣的讀者可以自行閱讀 “Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf” 6.2小節內容

3.4.2、xHigherPriorityTaskWoken 參數

xHigherPriorityTaskWoken 參數是中斷安全版本 API 中常見的一個參數,該參數用於通知應用程式編寫者在退出 ISR 時是否應該進行上下文切換,因為在執行某個中斷期間,在進入中斷時和退出中斷後多個任務的狀態可能發生了改變,也即可能存在中斷某個任務,但返回另外一個任務的情況發生

如果通過 FreeRTOS API 函數解鎖的任務的優先順序高於運行狀態任務的優先順序,則根據 FreeRTOS 調度策略,應切換到更高優先順序的任務,但究竟何時實際切換到更高優先順序的任務則取決於調用 API 函數的上下文,有以下兩種情況

  1. 如果 API 函數是從任務中調用的,那麼在搶占式調度策略下,在 API 函數退出之前,API 函數內會自動切換到更高優先順序的任務
  2. 如果 API 函數是從 ISR 中調用的,那麼在中斷中不會自動切換到更高優先順序的任務,但是可以設置一個變數來通知應用程式編寫者應該執行上下文切換,也就是 FreeRTOS 中斷安全版本的 API 函數中經常見到的 xHigherPriorityTaskWoken 參數

如果應執行上下文切換,則中斷安全 API 函數會將 pxHigherPriorityTaskWoken 設置為 pdTRUE ,而且只能將其設置為 pdTRUE ,所以 pxHigherPriorityTaskWoken 指向的變數必須在第一次使用之前初始化為 pdFALSE

如果不通過上述的方法在退出 ISR 前執行上下文切換,那麼最壞的情況就是本來應該在退出 ISR 時切換到某個高優先順序的任務進行執行,但現在只能將其轉為就緒狀態,直到下一個滴答定時器到來進行上下文切換其才會轉為運行狀態

3.4.3、portYIELD_FROM_ISR() 和 portEND_SWITCHING_ISR() 巨集

FreeRTOS教程2 任務管理 文章 "3.8、任務調度方法" 小節中,介紹了主動讓位於另一項同等優先順序任務的 API 函數 taskYIELD() ,它是一個可以在任務中調用來請求上下文切換的巨集,portYIELD_FROM_ISR() 和 portEND_SWITCHING_ISR() 都是 taskYIELD() 的中斷安全版本,他們兩個的使用方式相同,並且執行相同的操作

3.4.4、簡單總結

所以根據上面幾個小節的敘述,如果我們希望在 ISR 中使用 FreeRTOS 提供的 API 函數,則應該使用這些 API 函數的中斷安全版本,並且通過 xHigherPriorityTaskWoken 參數和 portYIELD_FROM_ISR() 巨集在退出 ISR 之前進行可能的上下文切換,其可能的一種應用結構如下所示

/*一個可能的在中斷中使用FreeRTOS API函數,然後進行上下文切換的例子*/
void An_Interrupt_Instance_Function(void)
{
	//定義一個用於通知應用程式編程者是否應該進行上下文切換的變數,必須初始化為pdFALSE
	BaseType_t highTaskWoken = pdFALSE;
	//使用二值信號量API函數做演示
	if(BinarySem_Handle != NULL)
	{
		//將中斷安全版本API函數的pxHigherPriorityTaskWoken參數指向 highTaskWoken
		xSemaphoreGiveFromISR(BinarySem_Handle, &highTaskWoken);
		//根據highTaskWoken決定是否要進行上下文切換
		portYIELD_FROM_ISR(highTaskWoken);
	}
}

但是不是所有中斷中都可以使用 FreeRTOS 提供的 API 函數,在 ISR 中使用 FreeRTOS API 函數總結如下所述

  1. 對於FreeRTOS可屏蔽的ISR中,如果要調用 FreeRTOS API 函數,則應該使用 FreeRTOS API 的中斷安全版本函數(函數名末尾為FromISR或FROM_ISR),不可以使用任務級的API函數
  2. 對於FreeRTOS不可屏蔽的ISR中,不能夠調用任何 FreeRTOS API函數

另外在 STM32CubeMX 軟體 NVIC 配置界面中,如果在某個中斷後面勾選了 “Uses FreeRTOS functions” 選項,根據上面的兩點描述可知,只能在 FreeRTOS 可屏蔽的ISR中使用 FreeRTOS API 函數,所以該中斷優先順序可選範圍會被強制到 15~5 之間,具體如下圖所示

3.5、任務優先順序和中斷優先順序

任務優先順序為軟體設置的一個屬性,設置範圍為1~(configMAX_PRIORITIES-1),數字越大優先順序越高,在搶占式調度方式中高優先順序的任務可以搶占低優先順序的任務

中斷優先順序為硬體響應優先順序,中斷分組策略4位全用於搶占優先順序的中斷優先順序數字設置範圍為0-15,數字越小優先順序越高

對於大多數的系統,其既會存在多個不同優先順序的任務,同時也會存在多個不同優先順序的中斷,它們之間的執行順序應該如下圖所示

3.6、延遲中斷處理

通常認為最佳實踐是使 ISR 儘可能短,下麵列出了可能的幾條原因

  1. 即使任務被分配了非常高的優先順序,它們也只有在硬體沒有中斷服務時才會運行
  2. ISR 會擾亂(添加“抖動”)任務的開始時間和執行時間
  3. 應用程式編寫者需要考慮任務和 ISR 同時訪問變數、外設和記憶體緩衝區等資源的後果,並防範這些資源
  4. 某些 FreeRTOS 埠允許中斷嵌套,但中斷嵌套會增加複雜性並降低可預測性,中斷越短,嵌套的可能性就越小

什麼時延遲中斷處理?

中斷服務程式必須記錄中斷原因,並清除中斷。中斷所需的任何其他處理通常可以在任務中執行,從而允許中斷服務常式儘可能快地退出,這稱為“延遲中斷處理”,因為中斷所需的處理從 ISR “延遲” 到任務。舉個例子,比如在 ADC 周期採集中,當一輪採集完成之後,ADC 採集完成中斷回調函數只負責將採集完成的值寫入緩存區,然後由其他任務對緩存區中的數據進行更複雜處理

將中斷處理推遲到任務還允許應用程式編寫者相對於應用程式中的其他任務確定處理的優先順序,並能夠使用所有 FreeRTOS API 函數

如果中斷處理被推遲的任務的優先順序高於任何其他任務的優先順序,則處理將立即執行,就像處理已在 ISR 本身中執行一樣。這種場景如下圖所示,其中任務 1 是普通應用程式任務,任務 2 是中斷處理被推遲的任務

那麼什麼情況下需要進行延遲中斷處理操作呢?

沒有具體絕對的規則,在以下列出的幾點情況下,將處理推遲到任務可能比較有用:

  1. 中斷所需的處理並不簡單。比如上面的舉例,如果 ADC 僅僅需要採集值,那麼在採集完成中斷回調函數中將採集值寫入緩存區即可,但是如果還需要對採集值進行複雜處理,那麼最好推遲到任務中完成
  2. 中斷處理是不確定的 - 這意味著事先不知道處理需要多長時間。

3.7、進行中斷屏蔽

FreeRTOS 中為什麼要屏蔽中斷?

想象這樣一個場景,當一個中等優先順序的任務 TASK1 正在通過串口輸出字元串 “Hello world!” 並且剛好輸出到 ”Hello“ 時,另外一個高級優先順序的任務 TASK2 突然搶占 TASK1 ,然後通過串口輸出字元串 “lc_guo” ,當兩個任務均執行完畢之後,你可能會在串口接受框中看到 ”Hellolc_guo world!“ 字元串

上述場景最終的結果與我們期望任務輸出的字元串不符,在操作系統中稱 TASK1 輸出字元串的操作不是原子的,可能被打斷的,因此在某些時候需要我們屏蔽掉中斷以保證某些操作為原子的,可以連續執行完不被打斷的,能夠連續執行完且不被打斷的程式段稱其為臨界段

那 FreeRTOS 中應該如何屏蔽中斷?

在 FreeRTOS 中提供了三組巨集函數方便用戶在合適的位置屏蔽中斷,在功能上屏蔽中斷和定義臨界代碼段幾乎是相同的,這幾組函數通常成對使用

/**
  * @brief  屏蔽FreeRTOS可管理的MCU中斷
  * @retval None
  */
void taskDISABLE_INTERRUPTS(void);

/**
  * @brief  解除屏蔽FreeRTOS可管理的MCU中斷
  * @retval None
  */
void taskENABLE_INTERRUPTS(void);

/**
  * @brief  開始臨界代碼段
  * @retval None
  */
void taskENTER_CRITICAL(void);

/**
  * @brief  退出臨界代碼段
  * @retval None
  */
void taskEXIT_CRITICAL(void);

/**
  * @brief  開始臨界代碼段的中斷安全版本
  * @retval 返回中斷屏蔽狀態uxSavedInterruptStatus,作為參數用於匹配的taskEXIT_CRITICAL_FROM_ISR()調用
  */
UBaseType_t taskENTER_CRITICAL_FROM_ISR(void);

/**
  * @brief  退出臨界代碼段的中斷安全版本
  * @param  uxSavedInterruptStatus:進入臨界代碼段時返回的中斷屏蔽狀態,taskENTER_CRITICAL_FROM_ISR()返回的值
  * @retval None
  */
void taskEXIT_CRITICAL_FROM_ISR(UBaseType_t uxSavedInterruptStatus);

4、實驗一:中斷各種特性測試

4.1、實驗目的

  1. 啟動 RTC 周期喚醒中斷,在周期喚醒中通過串口 USART1 不斷輸出當前 RTC 時間
  2. 創建任務 TASK_TEST ,在該任務中通過串口 USART1 輸出提示信息即可

4.2、CubeMX相關配置

首先讀者應按照 “FreeRTOS教程1 基礎知識” 章節配置一個可以正常編譯通過的 FreeRTOS 空工程,然後在此空工程的基礎上增加本實驗所提出的要求

本實驗需要初始化 USART1 作為輸出信息渠道,具體配置步驟請閱讀 “STM32CubeMX教程9 USART/UART 非同步通信” ,如下圖所示

本實驗需要配置 RTC 周期喚醒中斷,具體配置步驟和參數介紹讀者可閱讀 ”STM32CubeMX教程10 RTC 實時時鐘 - 周期喚醒、鬧鐘A/B事件和備份寄存器“ 實驗,此處不再贅述,這裡參數、中斷、時鐘如下圖所示

配置 Clock Configuration 和 Project Manager 兩個頁面,接下來直接單擊 GENERATE CODE 按鈕生成工程代碼即可

4.3、添加其他必要代碼

按照 “STM32CubeMX教程9 USART/UART 非同步通信” 實驗 “6、串口printf重定向”小節增加串口 printf 重定向代碼,具體不再贅述

然後在 rtc.c 文件下方重新實現 RTC 的周期喚醒回調函數,在該函數體內獲取當前 RTC 時間並通過 USART1 將時間輸出到串口助手,具體如下所述

/*周期喚醒回調函數*/
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
    RTC_TimeTypeDef sTime;
    RTC_DateTypeDef sDate;
    if(HAL_RTC_GetTime(hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK)
    {
        HAL_RTC_GetDate(hrtc, &sDate,  RTC_FORMAT_BIN);
        char str[22];
        sprintf(str,"RTC Time= %2d:%2d:%2d\r\n",sTime.Hours,sTime.Minutes,sTime.Seconds);
        printf("%s", str);
    }
}

最後在 freertos.c 中添加任務函數體內代碼即可,這裡無需實現具體功能,僅通過 USART1 串口輸出信息告知用戶該任務已執行即可,具體如下所述

/*測試任務函數*/
void TASK_TEST(void *argument)
{
  /* USER CODE BEGIN TASK_TEST */
  /* Infinite loop */
  for(;;)
  {
	printf("TASK_TEST\r\n");
    osDelay(pdMS_TO_TICKS(500));
  }
  /* USER CODE END TASK_TEST */
}

4.4、燒錄驗證

燒錄程式,打開串口助手,由於周期喚醒中斷每隔 1s 執行依次,TASK_TEST 任務大概每隔 500ms 執行有一次,因此通過串口助手輸出信息可以發現,每輸出兩次 ”TASK_TEST“ 就會輸出一次當前 RTC 時間,和預期一致,具體如下圖所示

上述任務流程應該如下圖所示

4.5、各種特性測試

4.5.1、中斷如果處理時間較長呢?

修改 RTC 周期喚醒中斷函數體,在函數體末尾增加 1s 延時函數 HAL_Delay(1000); 模擬中斷處理時間較長的情況,註意由於 RTC 周期喚醒中斷優先順序為 1 ,因此不能調用任何 FreeRTOS API 函數,包括延時函數,任務 TASK_TEST 不做任何改動,將修改後的程式重新編譯燒錄,觀察串口助手的輸出信息,具體如下圖所示

可以發現,只有最開始測試任務 TASK_TEST 執行了兩次,一旦 RTC 周期喚醒被執行那麼之後測試任務便得不到執行,為什麼會這樣?RTC 周期喚醒每隔 1s 執行一次,執行一次之後延時 1s 占用處理器,不斷迴圈,導致處理器沒有任何機會去處理 TASK_TEST

上述任務流程應該如下圖所示

4.5.2、任務如果處理時間較長呢?

修改測試任務 TASK_TEST 函數體,將其可以進入阻塞狀態的延時函數 osDelay() 修改為 HAL_Delay() 函數,同時將延時時間從 500ms 增加至 2s ,用於模擬任務一直運行的情況,RTC 周期喚醒中斷函數與 “4.3、添加其他必要代碼” 小節一致,具體如下所示

void TASK_TEST(void *argument)
{
  /* USER CODE BEGIN TASK_TEST */
  /* Infinite loop */
  for(;;)
  {
	printf("TASK_TEST\r\n");
    HAL_Delay(2000);
  }
  /* USER CODE END TASK_TEST */
}

將修改後的程式重新編譯燒錄,觀察串口助手的輸出信息,具體如下圖所示,從圖中可知 RTC 運行正常,本來應該連續運行 2s 的 TASK_TEST 並沒有影響到每隔 1s 輸出 RTC 時間的周期喚醒中斷,說明中斷搶占了 TASK_TEST 得到了執行,也就是說雖然我們希望 TASK_TEST 測試任務連續運行 2s ,但是其並沒有真正連續運行 2s,其在大概 1s 的時候被中斷了

4.5.3、進行中斷屏蔽

上述 ”4.5.2、任務如果處理時間較長呢?“ 小節闡述了一個問題,有時候我們希望我們的 TASK_TEST 任務是原子式執行的,不希望被中斷打斷,所以我們需要在任務函數體內屏蔽中斷,修改 TASK_TEST 任務函數體如下所示

void TASK_TEST(void *argument)
{
  /* USER CODE BEGIN TASK_TEST */
  /* Infinite loop */
  for(;;)
  {
	//進入臨界段
	//taskDISABLE_INTERRUPTS();
	taskENTER_CRITICAL();
	printf("TASK_TEST\r\n");
    HAL_Delay(2000);
    //退出臨界段
    //taskENABLE_INTERRUPTS();
    taskEXIT_CRITICAL();
  }
  /* USER CODE END TASK_TEST */
}

同時別忘記,FreeRTOS能夠屏蔽中斷優先順序為5~15,因此我們還需要在 STM32CubeMX 軟體的 NVIC 中將 RTC 周期喚醒中斷優先順序設置到該範圍內,這裡筆者將其設置為了 7 ,具體如下圖所示

將修改後的程式重新編譯燒錄,觀察串口助手的輸出信息,具體如下圖所示,可以發現 RTC 周期喚醒函數每隔 2s 才會得到一次輸出,這說明 TASK_TEST 任務整個函數體得到了連續運行,成功屏蔽掉了 RTC 周期喚醒中斷

5、註釋詳解

註釋1:圖片來源於 Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf

參考資料

STM32Cube高效開發教程(基礎篇)

Mastering_the_FreeRTOS_Real_Time_Kernel-A_Hands-On_Tutorial_Guide.pdf


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .NET Framework 和 .NET Core 2.0 及更低版本中由 HttpClient 使用的預設消息處理程式為HttpClientHandler。 從 .NET Core 2.1 開始,類SocketsHttpHandler提供了更高級別的 HTTP 網路類(例如HttpClient ...
  • 1、KingBaseES 人大金倉資料庫 是多資料庫、多模式。2、public 為預設模式,因此,預設情況下,我們可以在 public 模式下新建表即可。總的來說,使用 CYQ.Data 框架操作 KingBaseES 資料庫可以簡化開發流程,提高開發效率,同時也增強了系統的穩定性和安全性 ...
  • 一、多播委托的應用--觀察者模式 遇到一個開發的問題? 面試者:以面向對象的思想實現一下的場景: 貓:Miao一聲,緊接著引發了一系列的行為~ Miao:引發了一系列的動作; 從代碼層面來說:代碼這樣寫好嗎? 貓職責不單一(貓就是貓,他的行為只有Miao一聲) 依賴太重,依賴了很多的普通類; 被依賴 ...
  • 引言 本片文章分享一下之前遇到的WPF應用在觸摸屏下使用時的兩個問題。 場景 具體場景就是一個配置界面, ScrollViewer 中包含一個StackPanel 然後縱向堆疊,已滾動的方式查看,然後包含多個 TextBlock 、 TextBox 以及DataGrid ,期間遇到了兩個問題: WP ...
  • 前言 在.NET中,連接池被廣泛用於管理和優化不同類型資源的連接。連接池可以減少建立和關閉連接所需的時間和資源消耗,從而提高了應用程式的性能和響應能力。 HttpClient中的連接池 System.Net.Http.HttpClient 類用於發送 HTTP 請求以及從 URI 所標識的資源接收 ...
  • 概述:本教程使用OpenCvSharp和ZXing庫,詳細介紹了在C#中識別二維碼和條形碼的步驟。通過導入必要的命名空間、載入圖像,並使用ZXing庫進行二維碼和條形碼的識別,提供了清晰的示例代碼。這方便了開發人員在項目中集成二維碼和條形碼識別功能。 要使用OpenCvSharp來分別識別二維碼和條 ...
  • 概述:Quartz.NET是一個強大的任務調度庫,支持通過配置文件靈活配置任務和觸發器。配置文件中定義了調度器、線程池、作業和觸發器的相關信息。預設情況下,Quartz.NET在應用程式根目錄查找名為 quartz.config 的配置文件。若配置文件位於其他路徑或具有不同名稱,可以通過傳遞 Nam ...
  • 數據分頁,幾乎是任何應用系統的必備功能。但當數據量較大時,分頁操作的效率就會變得很低。大數據量分頁時,一個操作耗時5秒、10秒、甚至更長時間都是有可能的,但這在用戶使用的角度是不可接受的…… 數據分頁往往有三種常用方案。 第一種,把資料庫中存放的相關數據,全部讀入代碼/記憶體,再由代碼對其進行分頁操作 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 微服務架構已經成為搭建高效、可擴展系統的關鍵技術之一,然而,現有許多微服務框架往往過於複雜,使得我們普通開發者難以快速上手並體驗到微服務帶了的便利。為瞭解決這一問題,於是作者精心打造了一款最接地氣的 .NET 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...