超詳細的FreeRTOS移植全教程——基於srm32

来源:https://www.cnblogs.com/iot-dev/archive/2019/10/15/11681067.html
-Advertisement-
Play Games

準備 在移植之前,我們首先要獲取到FreeRTOS的官方的源碼包。這裡我們提供兩個下載鏈接: 一個是官網:http://www.freertos.org/ 另外一個是代碼托管網站:https://sourceforge.net/projects/freertos/files/FreeRTOS/ 這裡 ...


準備

在移植之前,我們首先要獲取到FreeRTOS的官方的源碼包。這裡我們提供兩個下載鏈接:

一個是官網:http://www.freertos.org/
另外一個是代碼托管網站:https://sourceforge.net/projects/freertos/files/FreeRTOS/

這裡我們演示如何在代碼托管網站裡面下載。打開網站鏈接之後,我們選擇FreeRTOS的最新版本V9.0.0(2016年),儘管現在FreeRTOS的版本已經更新到V10.0.1了,但是我們還是選擇V9.0.0,因為內核很穩定,並且網上資料很多,因為V10.0.0版本之後是亞馬遜收購了FreeRTOS之後才出來的版本,主要添加了一些雲端組件,我們本書所講的FreeRTOS是實時內核,採用V9.0.0版本足以。

簡單介紹FreeRTOS

FreeRTOS包含Demo常式和內核源碼(比較重要,我們就需要提取該目錄下的大部分文件)。
Source文件夾裡面包含的是FreeRTOS內核的源代碼,我們移植FreeRTOS的時候就需要這部分源代碼;
Demo 文件夾裡面包含了FreeRTOS官方為各個單片機移植好的工程代碼,FreeRTOS為了推廣自己,會給各種半導體廠商的評估板寫好完整的工程程式,這些程式就放在Demo這個目錄下,這部分Demo非常有參考價值。
在這裡插入圖片描述

Source文件夾

這裡我們再重點分析下FreeRTOS/ Source文件夾下的文件,①和③包含的是FreeRTOS的通用的頭文件和C文件,這兩部分的文件試用於各種編譯器和處理器,是通用的。需要移植的頭文件和C文件放在②portblle這個文件夾。
在這裡插入圖片描述

portblle文件夾,是與編譯器相關的文件夾,在不同的編譯器中使用不同的支持文件。①中的KEIL就是我們就是我們使用的編譯器,其實KEIL裡面的內容跟RVDS裡面的內容一樣,所以我們只需要③RVDS文件夾裡面的內容即可,裡面包含了各種處理器相關的文件夾,從文件夾的名字我們就非常熟悉了,我們學習的STM32有M0、M3、M4等各種系列,FreeRTOS是一個軟體,單片機是一個硬體,FreeRTOS要想運行在一個單片機上面,它們就必須關聯在一起。MemMang文件夾下存放的是跟記憶體管理相關的源文件。
在這裡插入圖片描述

移植過程

提取源碼

  1. 首先在我們的STM32裸機工程模板根目錄下新建一個文件夾,命名為“FreeRTOS”,並且在FreeRTOS文件夾下新建兩個空文件夾,分別命名為“src”與“port”,src文件夾用於保存FreeRTOS中的核心源文件,也就是我們常說的‘.c文件’,port文件夾用於保存記憶體管理以及處理器架構相關代碼,這些代碼FreeRTOS官方已經提供給我們的,直接使用即可,在前面已經說了,FreeRTOS是軟體,我們的開發版是硬體,軟硬體必須有橋梁來連接,這些與處理器架構相關的代碼,可以稱之為RTOS硬體介面層,它們位於FreeRTOS/Source/Portable文件夾下。
  2. 打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0\FreeRTOS\Source”目錄下找到所有的‘.c文件’,將它們拷貝到我們新建的src文件夾中,

在這裡插入圖片描述

  1. 打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0\FreeRTOS\Source\portable”目錄下找到“MemMang”文件夾與“RVDS”文件夾,將它們拷貝到我們新建的port文件夾中

在這裡插入圖片描述

  1. 打開FreeRTOS V9.0.0源碼,在“FreeRTOSv9.0.0 FreeRTOS\Source”目錄下找到“include”文件夾,它是我們需要用到FreeRTOS的一些頭文件,將它直接拷貝到我們新建的FreeRTOS文件夾中,完成這一步之後就可以看到我們新建的FreeRTOS文件夾已經有3個文件夾,這3個文件夾就包含FreeRTOS的核心文件,至此,FreeRTOS的源碼就提取完成。

在這裡插入圖片描述

添加到工程

添加FreeRTOSConfig.h文件
FreeRTOSConfig.h文件是FreeRTOS的工程配置文件,因為FreeRTOS是可以裁剪的實時操作內核,應用於不同的處理器平臺,用戶可以通過修改這個FreeRTOS內核的配置頭文件來裁剪FreeRTOS的功能,所以我們把它拷貝一份放在user這個文件夾下麵。
打開FreeRTOSv9.0.0源碼,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夾下麵找到“CORTEX_STM32F103_Keil”這個文件夾,雙擊打開,在其根目錄下找到這個“FreeRTOSConfig.h”文件,然後拷貝到我們工程的user文件夾下即可,等下我們需要對這個文件進行修改。

創建工程分組
接下來我們在mdk裡面新建FreeRTOS/src和FreeRTOS/port兩個組文件夾,其中FreeRTOS/src用於存放src文件夾的內容,FreeRTOS/port用於存放port\MemMang文件夾 與port\RVDS\ARM_CM3文件夾的內容。
然後我們將工程文件中FreeRTOS的內容添加到工程中去,按照已經新建的分組添加我們的FreeRTOS工程源碼。
在FreeRTOS/port分組中添加MemMang文件夾中的文件只需選擇其中一個即可,我們選擇“heap_4.c”,這是FreeRTOS的一個記憶體管理源碼文件。
添加完成後:

在這裡插入圖片描述

** 添加頭文件路徑**
FreeRTOS的源碼已經添加到開發環境的組文件夾下麵,編譯的時候需要為這些源文件指定頭文件的路徑,不然編譯會報錯。FreeRTOS的源碼裡面只有FreeRTOS\include和FreeRTOS\port\RVDS\ARM_CM3這兩個文件夾下麵有頭文件,只需要將這兩個頭文件的路徑在開發環境裡面指定即可。同時我們還將FreeRTOSConfig.h這個頭文件拷貝到了工程根目錄下的user文件夾下,所以user的路徑也要加到開發環境裡面。
在這裡插入圖片描述

修改FreeRTOSConfig.h

FreeRTOSConfig.h是直接從demo文件夾下麵拷貝過來的,該頭文件對裁剪整個FreeRTOS所需的功能的巨集均做了定義,有些巨集定義被使能,有些巨集定義被失能,一開始我們只需要配置最簡單的功能即可。要想隨心所欲的配置FreeRTOS的功能,我們必須對這些巨集定義的功能有所掌握,下麵我們先簡單的介紹下這些巨集定義的含義,然後再對這些巨集定義進行修改。

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "stm32f10x.h"
#include "bsp_usart.h"


//針對不同的編譯器調用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

//斷言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)

/************************************************************************
 *               FreeRTOS基礎配置配置選項 
 *********************************************************************/
/* 置1:RTOS使用搶占式調度器;置0:RTOS使用協作式調度器(時間片)
 * 
 * 註:在多任務管理機制上,操作系統可以分為搶占式和協作式兩種。
 * 協作式操作系統是任務主動釋放CPU後,切換到下一個任務。
 * 任務切換的時機完全取決於正在運行的任務。
 */
#define configUSE_PREEMPTION                      1

//1使能時間片調度(預設式使能的)
#define configUSE_TIME_SLICING                  1       

/* 某些運行FreeRTOS的硬體有兩種方法選擇下一個要執行的任務:
 * 通用方法和特定於硬體的方法(以下簡稱“特殊方法”)。
 * 
 * 通用方法:
 *      1.configUSE_PORT_OPTIMISED_TASK_SELECTION 為 0 或者硬體不支持這種特殊方法。
 *      2.可以用於所有FreeRTOS支持的硬體
 *      3.完全用C實現,效率略低於特殊方法。
 *      4.不強制要求限制最大可用優先順序數目
 * 特殊方法:
 *      1.必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1。
 *      2.依賴一個或多個特定架構的彙編指令(一般是類似計算前導零[CLZ]指令)。
 *      3.比通用方法更高效
 *      4.一般強制限定最大可用優先順序數目為32
 * 一般是硬體計算前導零指令,如果所使用的,MCU沒有這些硬體指令的話此巨集應該設置為0!
 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         1                       
                                                                        
/* 置1:使能低功耗tickless模式;置0:保持系統節拍(tick)中斷一直運行
 * 假設開啟低功耗的話可能會導致下載出現問題,因為程式在睡眠中,可用以下辦法解決
 * 
 * 下載方法:
 *      1.將開發版正常連接好
 *      2.按住複位按鍵,點擊下載瞬間鬆開複位按鍵
 *     
 *      1.通過跳線帽將 BOOT 0 接高電平(3.3V)
 *      2.重新上電,下載
 *    
 *          1.使用FlyMcu擦除一下晶元,然後進行下載
 *          STMISP -> 清除晶元(z)
 */
#define configUSE_TICKLESS_IDLE                                                 0   

/*
 * 寫入實際的CPU內核時鐘頻率,也就是CPU指令執行頻率,通常稱為Fclk
 * Fclk為供給CPU內核的時鐘信號,我們所說的cpu主頻為 XX MHz,
 * 就是指的這個時鐘信號,相應的,1/Fclk即為cpu時鐘周期;
 */
#define configCPU_CLOCK_HZ                        (SystemCoreClock)

//RTOS系統節拍中斷的頻率。即一秒中斷的次數,每次中斷RTOS都會進行任務調度
#define configTICK_RATE_HZ                        (( TickType_t )1000)

//可使用的最大優先順序
#define configMAX_PRIORITIES                      (32)

//空閑任務使用的堆棧大小
#define configMINIMAL_STACK_SIZE                ((unsigned short)128)
  
//任務名字字元串長度
#define configMAX_TASK_NAME_LEN                 (16)

 //系統節拍計數器變數數據類型,1表示為16位無符號整形,0表示為32位無符號整形
#define configUSE_16_BIT_TICKS                  0                      

//空閑任務放棄CPU使用權給其他同優先順序的用戶任務
#define configIDLE_SHOULD_YIELD                 1           

//啟用隊列
#define configUSE_QUEUE_SETS                      1    

//開啟任務通知功能,預設開啟
#define configUSE_TASK_NOTIFICATIONS    1   

//使用互斥信號量
#define configUSE_MUTEXES                           1    

//使用遞歸互斥信號量                                            
#define configUSE_RECURSIVE_MUTEXES         1   

//為1時使用計數信號量
#define configUSE_COUNTING_SEMAPHORES       1

/* 設置可以註冊的信號量和消息隊列個數 */
#define configQUEUE_REGISTRY_SIZE               10                                 
                                                                       
#define configUSE_APPLICATION_TASK_TAG        0                       
                      

/*****************************************************************
              FreeRTOS與記憶體申請有關配置選項                                               
*****************************************************************/
//支持動態記憶體申請
#define configSUPPORT_DYNAMIC_ALLOCATION        1    
//支持靜態記憶體
#define configSUPPORT_STATIC_ALLOCATION                 0                   
//系統所有總的堆大小
#define configTOTAL_HEAP_SIZE                   ((size_t)(36*1024))    


/***************************************************************
             FreeRTOS與鉤子函數有關的配置選項                                            
**************************************************************/
/* 置1:使用空閑鉤子(Idle Hook類似於回調函數);置0:忽略空閑鉤子
 * 
 * 空閑任務鉤子是一個函數,這個函數由用戶來實現,
 * FreeRTOS規定了函數的名字和參數:void vApplicationIdleHook(void ),
 * 這個函數在每個空閑任務周期都會被調用
 * 對於已經刪除的RTOS任務,空閑任務可以釋放分配給它們的堆棧記憶體。
 * 因此必須保證空閑任務可以被CPU執行
 * 使用空閑鉤子函數設置CPU進入省電模式是很常見的
 * 不可以調用會引起空閑任務阻塞的API函數
 */
#define configUSE_IDLE_HOOK                     0      

/* 置1:使用時間片鉤子(Tick Hook);置0:忽略時間片鉤子
 * 
 * 
 * 時間片鉤子是一個函數,這個函數由用戶來實現,
 * FreeRTOS規定了函數的名字和參數:void vApplicationTickHook(void )
 * 時間片中斷可以周期性的調用
 * 函數必須非常短小,不能大量使用堆棧,
 * 不能調用以”FromISR" 或 "FROM_ISR”結尾的API函數
 */
 /*xTaskIncrementTick函數是在xPortSysTickHandler中斷函數中被調用的。因此,vApplicationTickHook()函數執行的時間必須很短才行*/
#define configUSE_TICK_HOOK                     0           

//使用記憶體申請失敗鉤子函數
#define configUSE_MALLOC_FAILED_HOOK            0 

/*
 * 大於0時啟用堆棧溢出檢測功能,如果使用此功能 
 * 用戶必須提供一個棧溢出鉤子函數,如果使用的話
 * 此值可以為1或者2,因為有兩種棧溢出檢測方法 */
#define configCHECK_FOR_STACK_OVERFLOW          0   


/********************************************************************
          FreeRTOS與運行時間和任務狀態收集有關的配置選項   
**********************************************************************/
//啟用運行時間統計功能
#define configGENERATE_RUN_TIME_STATS           0             
 //啟用可視化跟蹤調試
#define configUSE_TRACE_FACILITY                      0    
/* 與巨集configUSE_TRACE_FACILITY同時為1時會編譯下麵3個函數
 * prvWriteNameToBuffer()
 * vTaskList(),
 * vTaskGetRunTimeStats()
*/
#define configUSE_STATS_FORMATTING_FUNCTIONS    1                       
                                                                        
                                                                        
/********************************************************************
                FreeRTOS與協程有關的配置選項                                                
*********************************************************************/
//啟用協程,啟用協程以後必須添加文件croutine.c
#define configUSE_CO_ROUTINES                     0                 
//協程的有效優先順序數目
#define configMAX_CO_ROUTINE_PRIORITIES       ( 2 )                   


/***********************************************************************
                FreeRTOS與軟體定時器有關的配置選項      
**********************************************************************/
 //啟用軟體定時器
#define configUSE_TIMERS                            1                              
//軟體定時器優先順序
#define configTIMER_TASK_PRIORITY               (configMAX_PRIORITIES-1)        
//軟體定時器隊列長度
#define configTIMER_QUEUE_LENGTH                10                               
//軟體定時器任務堆棧大小
#define configTIMER_TASK_STACK_DEPTH          (configMINIMAL_STACK_SIZE*2)    

/************************************************************
            FreeRTOS可選函數配置選項                                                     
************************************************************/
#define INCLUDE_xTaskGetSchedulerState       1                       
#define INCLUDE_vTaskPrioritySet                 1
#define INCLUDE_uxTaskPriorityGet                1
#define INCLUDE_vTaskDelete                        1
#define INCLUDE_vTaskCleanUpResources          1
#define INCLUDE_vTaskSuspend                       1
#define INCLUDE_vTaskDelayUntil                  1
#define INCLUDE_vTaskDelay                         1
#define INCLUDE_eTaskGetState                      1
#define INCLUDE_xTimerPendFunctionCall       1
//#define INCLUDE_xTaskGetCurrentTaskHandle       1
//#define INCLUDE_uxTaskGetStackHighWaterMark     0
//#define INCLUDE_xTaskGetIdleTaskHandle          0


/******************************************************************
            FreeRTOS與中斷有關的配置選項                                                 
******************************************************************/
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS             __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS             4                  
#endif
//中斷最低優先順序
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15     

//系統可管理的最高中斷優先順序
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5 

#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )    /* 240 */

#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


/****************************************************************
            FreeRTOS與中斷服務函數有關的配置選項                         
****************************************************************/
#define xPortPendSVHandler  PendSV_Handler
#define vPortSVCHandler     SVC_Handler


/* 以下為使用Percepio Tracealyzer需要的東西,不需要時將 configUSE_TRACE_FACILITY 定義為 0 */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
#define INCLUDE_xTaskGetCurrentTaskHandle               1   // 啟用一個可選函數(該函數被 Trace源碼使用,預設該值為0 表示不用)
#endif


#endif /* FREERTOS_CONFIG_H */

修改stm32f10x_it.c

SysTick中斷服務函數是一個非常重要的函數,FreeRTOS所有跟時間相關的事情都在裡面處理,SysTick就是FreeRTOS的一個心跳時鐘,驅動著FreeRTOS的運行,就像人的心跳一樣,假如沒有心跳,我們就相當於“死了”,同樣的,FreeRTOS沒有了心跳,那麼它就會卡死在某個地方,不能進行任務調度,不能運行任何的東西,因此我們需要實現一個FreeRTOS的心跳時鐘,FreeRTOS幫我們實現了SysTick的啟動的配置:在port.c文件中已經實現vPortSetupTimerInterrupt()函數,並且FreeRTOS通用的SysTick中斷服務函數也實現了:在port.c文件中已經實現xPortSysTickHandler()函數,所以移植的時候只需要我們在stm32f10x_it.c文件中實現我們對應(STM32)平臺上的SysTick_Handler()函數即可。FreeRTOS為開發者考慮得特別多,PendSV_Handler()與SVC_Handler()這兩個很重要的函數都幫我們實現了,在在port.c文件中已經實現xPortPendSVHandler()與vPortSVCHandler()函數,防止我們自己實現不了,那麼在stm32f10x_it.c中就需要我們註釋掉PendSV_Handler()與SVC_Handler()這兩個函數了。

//void SVC_Handler(void)
//{
//}

//void PendSV_Handler(void)
//{
//}

extern void xPortSysTickHandler(void);

//systick中斷服務函數
void SysTick_Handler(void)
{   
    #if (INCLUDE_xTaskGetSchedulerState  == 1 )
      if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
      {
    #endif  /* INCLUDE_xTaskGetSchedulerState */  
        xPortSysTickHandler();
    #if (INCLUDE_xTaskGetSchedulerState  == 1 )
      }
    #endif  /* INCLUDE_xTaskGetSchedulerState */
}

創建任務

這裡,我們創建一個單任務,任務使用的棧和任務控制塊是在創建任務的時候FreeRTOS動態分配的。
任務必須是一個死迴圈,否則任務將通過LR返回,如果LR指向了非法的記憶體就會產生HardFault_Handler,而FreeRTOS指向一個死迴圈,那麼任務返回之後就在死迴圈中執行,這樣子的任務是不安全的,所以避免這種情況,任務一般都是死迴圈並且無返回值的。
並且每個任務迴圈主體中應該有阻塞任務的函數,否則就會餓死比它優先順序更低的任務!!!

/* FreeRTOS頭文件 */
#include "FreeRTOS.h"
#include "task.h"
/* 開發板硬體bsp頭文件 */
#include "bsp_led.h"

static void AppTaskCreate(void);/* AppTask任務 */

 /* 創建任務句柄 */
static TaskHandle_t AppTask_Handle = NULL;

int main(void)
{   
  BaseType_t xReturn = pdPASS;/* 定義一個創建信息返回值,預設為pdPASS */

  /* 開發板硬體初始化 */
  BSP_Init();

   /* 創建AppTaskCreate任務 */
  xReturn = xTaskCreate((TaskFunction_t )AppTask,  /* 任務入口函數 */
                        (const char*    )"AppTask",/* 任務名字 */
                        (uint16_t       )512,  /* 任務棧大小 */
                        (void*          )NULL,/* 任務入口函數參數 */
                        (UBaseType_t    )1, /* 任務的優先順序 */
                        (TaskHandle_t*  )&AppTask_Handle);/* 任務控制塊指針 */ 
  /* 啟動任務調度 */           
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* 啟動任務,開啟調度 */
  else
    return -1;  
  
  while(1);   /* 正常不會執行到這裡 */    
}

static void AppTask(void* parameter)
{   
    while (1)
    {
        LED1_ON;
        vTaskDelay(500);   /* 延時500個tick */
        LED1_OFF;     
        vTaskDelay(500);   /* 延時500個tick */             
    }
}

關註我

歡迎關註我公眾號

更多資料歡迎關註“物聯網IoT開發”公眾號!


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

-Advertisement-
Play Games
更多相關文章
  • 關鍵字:流程未來節點處理人 工作流快速開發平臺 工作流流設計 業務流程管理 asp.net 開源工作流 業務背景:一個流程在啟動起來後,是可以對一些節點計算出來處理人是誰,流程的走向。對於另外一些節點處理人有可能需要相關的人員調整的。在一些審批的環境下,需要把能夠計算出來的節點處理人在發起時計算出來... ...
  • 一、背景 代碼實例:https://gitee.com/D_C_L/CurtainEtcAOP.git我們實際系統中有很多操作,是不管做多少次,都應該產生一樣的效果或返回一樣的結果。 例如: 1. 前端重覆提交選中的數據,應該後臺只產生對應這個數據的一個反應結果。 2. 我們發起一筆付款請求,應該只 ...
  • 本篇主要寫一些 腳本排序工具的使用。 sort 概述 是一個以行為單位對文件內容進行排序的工具,也可以根據不同的數據類型來排序。 用法 sort [選項] 參數 :忽略大小寫 :忽略每行前面的空格 :按照月份進行排序 :按照數字進行排序 :反向排序 :等同於 ,表示相同的數據僅顯示一行 :指定分隔符 ...
  • 本篇主要寫一些 腳本編輯工具 的使用。 概述 是一個功能強大的編輯工具,逐行讀取輸入文本,並根據指定的匹配模式進行查找,對符合條件的內容進行格式化輸出或者過濾處理。 傾向於將一行分成多個欄位然後再進行處理,且預設情況下欄位的分隔符為 或者 鍵。 執行結果可以通過 的功能將欄位數據列印顯示。 可以使用 ...
  • 1.先apt-get update一下當前預設的源,更新完成後先把vim命令安裝一下,再修改源倉庫為阿裡雲,否則無法直接編輯文件 2.先添加阿裡雲的源,編輯文件/etc/apt/sources.list,編輯完再次更新一下 deb http://mirrors.aliyun.com/ubuntu/ ...
  • 作為一個技術純小白,在Linux伺服器初始化MySQL資料庫的時候遇到了一點小問題: ​ 1、不會使用MySQL圖形工具,幾乎沒玩過 ​ 2、客戶的VPN沒有開放3306埠,沒法用navicat等工具連接資料庫 ​ 3、懶的再打開圖形工具,畢竟命令行接近萬能了…… 所以: 方法一、在初始化腳本文件 ...
  • 對稱加密演算法 非對稱加密演算法 單向散列(hash演算法) CA和證書 證書獲取 安全協議 OpenSSL openssl命令 創建CA和申請證書 ...
  • awk介紹 awk的工作原理 awk基本格式 awk之print格式 awk變數 awk之printf awk操作符 awk PATTERN awk action awk控制語句 awk控制語句if-else awk控制語句 while迴圈 awk控制語句do-while迴圈 awk控制語句 for ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...