嵌入式:UCOSIII的使用

来源:http://www.cnblogs.com/leonlincq/archive/2017/01/18/6295390.html
-Advertisement-
Play Games

0、一些移植、系統相關 OS_CFG_APP.H OS_CFG.H:功能性裁剪 OS_APP_HOOKS.C:鉤子函數 OS_CPU_A.ASM:PendSV中斷、任務切換 OS_CPU_C.C: OSTaskStkInit函數,任務創建時,對堆棧初始化,寄存器地址要參照手冊 1、框架寫法(個人習慣 ...


0、一些移植、系統相關 

OS_CFG_APP.H

                                                            /* --------------------- MISCELLANEOUS ------------------ */
#define  OS_CFG_MSG_POOL_SIZE            100u               /* 消息池 大小                                       */
#define  OS_CFG_ISR_STK_SIZE             128u               /* Stack size of ISR stack (number of CPU_STK elements)   */
#define  OS_CFG_TASK_STK_LIMIT_PCT_EMPTY  10u               /* Stack limit position in percentage to empty            */


                                                            /* ---------------------- IDLE TASK --------------------- */
#define  OS_CFG_IDLE_TASK_STK_SIZE       128u               /* 空閑任務 堆棧空間大小   (一般不做修改)                 */


                                                            /* ------------------ ISR HANDLER TASK ------------------ */
#define  OS_CFG_INT_Q_SIZE                10u               /* 中斷服務隊列 大小                                  */
#define  OS_CFG_INT_Q_TASK_STK_SIZE      128u               /* 中斷服務隊列 堆棧空間大小(一般不做修改)                  */

                                                            /* ------------------- STATISTIC TASK ------------------- */
#define  OS_CFG_STAT_TASK_PRIO    (OS_CFG_PRIO_MAX-2u)   /* 統計任務 優先順序         (一般不做修改)                 */
#define  OS_CFG_STAT_TASK_RATE_HZ         10u               /* 統計任務頻率 (1 to 10 Hz)                             */
#define  OS_CFG_STAT_TASK_STK_SIZE       128u               /* 統計任務 堆棧空間大小    (一般不做修改)                 */


                                                            /* ------------------------ TICKS ----------------------- */
#define  OS_CFG_TICK_RATE_HZ            200u                /* 時鐘節拍頻率 200HZ = 5ms  (10 to 1000 Hz)                */
#define  OS_CFG_TICK_TASK_PRIO             1u               /* 時鐘節拍優先順序,一般設置一個相對較高的優先順序             */
#define  OS_CFG_TICK_TASK_STK_SIZE       128u               /* 時鐘節拍堆棧空間大小    (一般不做修改)                 */
#define  OS_CFG_TICK_WHEEL_SIZE           17u               /* Number of 'spokes' in tick  wheel; SHOULD be prime     */


                                                            /* ----------------------- TIMERS ----------------------- */
#define  OS_CFG_TMR_TASK_PRIO              2u               /* 軟體定時器優先順序				          */
#define  OS_CFG_TMR_TASK_RATE_HZ         100u               /* 軟體定時器頻率 100HZ = 10ms,不能小於心跳時鐘節拍        */
#define  OS_CFG_TMR_TASK_STK_SIZE        128u               /* 軟體定時器堆棧空間大小   (一般不做修改)                  */
#define  OS_CFG_TMR_WHEEL_SIZE            17u               /* Number of 'spokes' in timer wheel; SHOULD be prime     */

 

OS_CFG.H:功能性裁剪

OS_APP_HOOKS.C:鉤子函數

OS_CPU_A.ASM:PendSV中斷、任務切換

OS_CPU_C.C: OSTaskStkInit函數,任務創建時,對堆棧初始化,寄存器地址要參照手冊

 

 

1、框架寫法(個人習慣相關)

1-1、main 函數里創建一個開始任務

int main(void)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	
	初始化外設
	
	OSInit(&err);	      //初始化UCOSIII

	OS_CRITICAL_ENTER();    //進入臨界區

	OSTaskCreate();       //創建開始任務 

	OS_CRITICAL_EXIT();    //退出臨界區
 
	OSStart(&err);       //開啟UCOSIII

        while(1);
}   

1-2、開始任務里,創建我們要運行的多個任務

void start_task(void *p_arg)
{
	OS_ERR err;
	CPU_SR_ALLOC();
	p_arg = p_arg;

	CPU_Init();
	
#if OS_CFG_STAT_TASK_EN > 0u           //統計任務
   OSStatTaskCPUUsageInit(&err);                      
#endif
	
#ifdef CPU_CFG_INT_DIS_MEAS_EN	    //測量中斷關閉時間
    CPU_IntDisMeasMaxCurReset();	
#endif
	
#if	OS_CFG_SCHED_ROUND_ROBIN_EN   //時間片輪轉
	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);       //時間片長度為1個系統時鐘節拍,既1*5=5ms
#endif		
	
	OS_CRITICAL_ENTER();	    //進入臨界區
	
	OSTaskCreate(); 	    //創建任務	1		
	OSTaskCreate(); 	    //創建任務	2		 
	OSTaskCreate(); 	    //創建任務	3
	 
	OS_CRITICAL_EXIT();	     //進入臨界區
	
	OSTaskDel((OS_TCB*)0,&err);  //刪除start_task任務自身
}    

  

2、任務創建、掛起、刪除

2-1、任務創建

//==================任務創建巨集定義,便於修改==================

#define START_TASK_PRIO		3		//任務優先順序
#define START_STK_SIZE 		128		//任務堆棧大小

OS_TCB StartTaskTCB;				//任務控制塊
CPU_STK START_TASK_STK[START_STK_SIZE];	     //任務堆棧	

void start_task(void *p_arg);			//任務函數

//==================任務創建函數==================

OSTaskCreate((OS_TCB 	* )&StartTaskTCB,	//任務 控制塊
	   (CPU_CHAR	* )"start task", 	//任務 名字
	   (OS_TASK_PTR  )start_task, 		//任務 函數
	   (void	* )0,			//任務 任務函數的參數
	   (OS_PRIO	  )START_TASK_PRIO,     //任務 優先順序
	   (CPU_STK   * )&START_TASK_STK[0],	//任務 堆棧基地址
	   (CPU_STK_SIZE)START_STK_SIZE/10,	//任務 堆棧深度限位
	   (CPU_STK_SIZE)START_STK_SIZE,	//任務 堆棧大小
	   (OS_MSG_QTY  )0,			//任務 內部消息隊列能夠接收的最大消息數目,為0時禁止接收消息
	   (OS_TICK	 )0,			//任務 使用時間片輪轉,時間片長度,為0時為預設長度,
	   (void   	*)0,			//任務 用戶補充的存儲區
	   (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,   //任務 選項
	   (OS_ERR 	*)&err);		//任務 創建成功與否

2-2、任務掛起

OSTaskSuspend((OS_TCB*)&Task1TaskTCB,&err);		//掛起開始任務

2-3、任務解掛

OSTaskResume((OS_TCB*)&Task1TaskTCB,&err);    //任務解掛

2-4、任務刪除

OSTaskDel((OS_TCB*)0,&err);	//刪除start_task任務自身

 

3、時間片輪轉

3-1、兩個任務優先順序相等

#define Task0_Task_Prio		4                //優先順序4
#define Task0_Stk_Size		128
OS_TCB Task0TaskTCB;
CPU_STK Task0_Task_Stk[Task0_Stk_Size];
void Task0Task(void *p_arg);

#define Task1_Task_Prio		4                //優先順序4
#define Task1_Stk_Size		128
OS_TCB Task1TaskTCB;
CPU_STK Task1_Task_Stk[Task1_Stk_Size];
void Task1Task(void *p_arg); 

3-2、使能輪轉調度,調用API,設置單位時間

#if	OS_CFG_SCHED_ROUND_ROBIN_EN      //使用時間片輪轉

	OSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  //時間片長度為1個系統時鐘節拍,既1*5=5ms
	
#endif	

3-3、創建任務時,設置任務的時間片大小

OSTaskCreate((OS_TCB 	* )&Task1TaskTCB,		
			 (CPU_CHAR	* )"Task1 task", 		
			 (OS_TASK_PTR )Task1Task, 			
			 (void		* )0,					
			 (OS_PRIO	  )Task1_Task_Prio,     	
			 (CPU_STK   * )&Task1_Task_Stk[0],	
			 (CPU_STK_SIZE)Task1_Stk_Size/10,	
			 (CPU_STK_SIZE)Task1_Stk_Size,		
			 (OS_MSG_QTY  )0,					
			 (OS_TICK	  )2,						//時間片長度為2*5=10ms					
			 (void   	* )0,				
			 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, 
			 (OS_ERR 	* )&err);	

 

4、鉤子函數。函數指針,UCOS不希望我們去修改他的文件,弄了鉤子函數,比如 App_OS_IdleTaskHook ,在空閑時運行這個函數,功能自己填寫。

4-1、使能鉤子函數功能,並設置所有函數指針

#if OS_CFG_APP_HOOKS_EN > 0u	  //使能鉤子函數
	App_OS_SetAllHooks();			
#endif

4-2、在 os_app_hooks.c 里的 App_OS_*Hook,裡面填寫你要的功能。

void  App_OS_IdleTaskHook (void)
{
	static int num ;
	num++;                //計算運行了多少次空閑任務
}

 

5、軟體定時器

5-1、軟體定時器創建

//==============定時器結構體、函數聲明==============

OS_TMR Timer0;
void timer0CallBack(void *p_tmr, void *p_arg);

//==============定時器創建==============

//創建定時器0任務
OSTmrCreate (  (OS_TMR			*)&Timer0,		//定時器 結構體
		(CPU_CHAR		*)"time0",		//定時器 名字
		(OS_TICK		 )10,			//定時器 初次延時節拍 10*10 = 100ms
		(OS_TICK		 )100,			//定時器 以後延時節拍 100*10 = 1000ms = 1s
		(OS_OPT			 )OS_OPT_TMR_PERIODIC,	//定時器 選項 : 單次 或 周期。
		(OS_TMR_CALLBACK_PTR	 )timer0CallBack,	//定時器 回調函數,偽中斷服務函數
		(void			*)0,			//定時器 中斷服務函數的參數
		(OS_ERR			*)&err);		//定時器 創建成功與否

5-2、定時器“中斷服務函數”,回調函數

void timer0CallBack(void *p_tmr, void *p_arg)
{
	//do something
}

 

6、信號量

6-1、信號量創建

OSSemCreate (   (OS_SEM      *)&mySem,		//信號量 結構體
		(CPU_CHAR    *)"semtest",	//信號量 名字
		(OS_SEM_CTR   )1,		//信號量 初始值,
		(OS_ERR      *)&err);		//信號量 創建成功是否

6-2、信號量等待

OSSemPend ((OS_SEM   *)&mySem,			//信號量 結構體
	  (OS_TICK   )0,			//信號量 等待超時時間
	  (OS_OPT    )OS_OPT_PEND_BLOCKING,	//信號量 阻塞 或 不阻塞
	  (CPU_TS   *)0,			//信號量 時間戳
	  (OS_ERR   *)&err);			//信號量 等待錯誤

6-3、信號量發送

OSSemPost ((OS_SEM  *)&mySem,		//信號量 結構體
	  (OS_OPT   )OS_OPT_POST_1,	//信號量 給就緒最高優先順序
	  (OS_ERR  *)&err);		//信號量 等待錯誤

 

用途:   1、訪問共用資源。

    2、中斷發送信號,讓處理在任務。

 

7、任務內建信號量

7-1、等待自身的信號量

OSTaskSemPend ( (OS_TICK   )0,				//內建信號量 超時時間
		(OS_OPT    )OS_OPT_PEND_BLOCKING,	//內建信號量 阻塞 或 不阻塞	
		(CPU_TS   *)0,				//內建信號量 時間戳
		(OS_ERR   *)&err);			//內建信號量 等待錯誤

7-2、其他任務,給等待內建信號量的任務發送信號量

OSTaskSemPost ( (OS_TCB  *)&Task0TaskTCB,	//內建信號量 等待的任務
		(OS_OPT   )OS_OPT_POST_NONE,	//內建信號量 調度 或 不調度
		(OS_ERR  *)&err);		//內建信號量 等待錯誤

 

8、互斥信號量

8-1、互斥信號量創建

OSMutexCreate ( (OS_MUTEX  	*)&myMutex,	//互斥信號量 結構體
		(CPU_CHAR	*)"Mutextest",	//互斥信號量 名字
		(OS_ERR      *)err);		//互斥信號量 創建錯誤

8-2、互斥信號量等待

OSMutexPend (  (OS_MUTEX	*)&myMutex,		//互斥信號量 結構體
		(OS_TICK    )0,				//互斥信號量 等待超時時間
		(OS_OPT     )OS_OPT_PEND_BLOCKING,	//互斥信號量 阻塞 或 不阻塞
		(CPU_TS   	*)0,			//互斥信號量 時間戳
		(OS_ERR   	*)&err);		//互斥信號量 等待錯誤

8-3、互斥信號量發送

OSMutexPost ( (OS_MUTEX  *)&myMutex,		//互斥信號量 結構體
	    (OS_OPT   )OS_OPT_POST_NONE,	//互斥信號量 調度 或 不調度
	    (OS_ERR  *)&err);		//互斥信號量 發送錯誤

  

用途:防止優先順序反轉,如:2個任務共用一個資源,而,兩者的優先順序,中間隔著多個優先順序(任務)。高優先順序 等待 低優先順序 釋放,而,低優先順序 此時又被 中等優先順序 打斷,變成 高優先順序 要等 中等優先順序。

用互斥信號的話,此時 低優先順序 ,會暫時提高到共用資源的 高優先順序 級別。不會被中等優先順序打算。處理完,降回 低優先順序 ,高優先順序接著訪問。再 中等優先順序。

 

發現:1、高優先順序 等待時, 低優先順序用OSSched(); 此時達到預計效果,不會被 中等優先順序搶占。

     2、高優先順序 等待時,低優先順序用OSTimeDlyHMSM();延時指令,此時,會被中等優先順序搶占。

 

9、消息隊列

9-1、消息隊列創建

//================消息隊列巨集定義================

OS_Q my_MSG_Q;
#define my_MSG_QTY	(OS_MSG_QTY)5

//================消息隊列創建================

OSQCreate ( (OS_Q        *)&my_MSG_Q,	     //消息隊列 結構體
	  (CPU_CHAR    *)"MSG_Q_Test",  	//消息隊列 名字
	  (OS_MSG_QTY   )my_MSG_QTY,		//消息隊列 大小
	  (OS_ERR      *)&err);		//消息隊列 創建錯誤

9-2、消息發送

u8 *MSG = (u8 *)"testtet";
	
OSQPost (  (OS_Q         *)&my_MSG_Q,		//消息隊列 結構體
	  (void         *)MSG,			//消息隊列 發送的消息
	  (OS_MSG_SIZE   )8,			//消息隊列 發送的消息大小
	  (OS_OPT        )OS_OPT_POST_FIFO,	//消息隊列 發送方式,普通FIFO,緊急LIFO,及發送給所有等待該消息、發送調度與否
	  (OS_ERR       *)&err);		//消息隊列 發送錯誤

9-3、消息接收

u8 *MSG;	
u8 Q_size;	
		
MSG = OSQPend ( (OS_Q         *)&my_MSG_Q,		//消息隊列 結構體
		(OS_TICK       )0,			//消息隊列 等待超時
		(OS_OPT        )OS_OPT_PEND_BLOCKING,	//消息隊列 阻塞 或 不阻塞
		(OS_MSG_SIZE  *)&Q_size,		//消息隊列 收到的大小
		(CPU_TS       *)0,			//消息隊列 時間戳
		(OS_ERR       *)&err);			//消息隊列 接收錯誤

 

10、任務內建消息隊列

10-1、內建消息隊列發送

u8 *MSG = (u8 *)"testtet";

OSTaskQPost (  (OS_TCB       *)&MSG_Q_TaskTCB,	  //內建消息隊列 接收的任務				
		(void         *)MSG,		  //內建消息隊列 發送的消息
		(OS_MSG_SIZE   )8,		  //內建消息隊列 發送的消息大小
		(OS_OPT        )OS_OPT_POST_FIFO,  //內建消息隊列 發送方式,普通FIFO,緊急LIFO,及發送給所有等待該消息、發送調度與否
		(OS_ERR       *)&err);		  //內建消息隊列 發送錯誤

10-2、內建消息隊列接收

u8 *MSG;
u8 Q_size;
		
MSG = OSTaskQPend (	(OS_TICK		)0,		//內建消息隊列 等待超時
			(OS_OPT        )OS_OPT_PEND_BLOCKING,	//內建消息隊列 阻塞 或 不阻塞
			(OS_MSG_SIZE  *)&Q_size,		//內建消息隊列 收到的大小
			(CPU_TS       *)0,			//內建消息隊列 時間戳
			(OS_ERR       *)&err);			//內建消息隊列 接收錯誤	

  

11、標記位組

11-1、標記位組創建

OS_FLAG_GRP my_FLAG;

#define FLAG_INIT	0x00
#define FLAG_BIT0	0x01
#define FLAG_BIT1	0x02

OSFlagCreate (	(OS_FLAG_GRP  *)&my_FLAG,	//標記位組 結構體
		(CPU_CHAR     *)"Flag test",	//標記位組 名字
		(OS_FLAGS      )FLAG_INIT,	//標記位組 標記初始值
		(OS_ERR       *)&err);		//標記位組 創建成功與否

11-2、標記位組發送

OSFlagPost ((OS_FLAG_GRP  *)&my_FLAG,			//標記位組 結構體
	   (OS_FLAGS      )FLAG_BIT0,			//標記位組 bit0
	   (OS_OPT        )OS_OPT_POST_FLAG_SET,	//標記位組 置1
	   (OS_ERR       *)&err);			//標記位組 bit0 置 1 成功與否

11-3、標記為組等待

OS_FLAGS index;
		
index = OSFlagPend ((OS_FLAG_GRP  *)&my_FLAG,		  //標記位組 結構體
		    (OS_FLAGS      )FLAG_BIT0 | FLAG_BIT1, //標記位組 等待的BIT位
		    (OS_TICK       )0,			  //標記位組 等待超時時間
		    (OS_OPT        )OS_OPT_PEND_FLAG_SET_ANY | OS_OPT_PEND_FLAG_CONSUME | OS_OPT_PEND_BLOCKING,	  //標記位組 任意1個Bit置1,接收後清0,阻塞
		    (CPU_TS       *)0,			  //標記位組 時間戳
		    (OS_ERR       *)&err);		  //標記位組 等待錯誤

  

12、多個內核對象

12-1、多個內核對象 創建

//=================多個內核對象 結構體=================

OS_SEM my_Sem1;

OS_SEM my_Sem2;

OS_Q  my_Q1;
#define my_Q1_SIZE	5
	
//=================多個內核對象 創建=================

OSSemCreate (	(OS_SEM      *)&my_Sem1,
		(CPU_CHAR    *)"sem1 test",
		(OS_SEM_CTR   )0,
		(OS_ERR      *)&err);

OSSemCreate (	(OS_SEM      *)&my_Sem2,
		(CPU_CHAR    *)"sem2 test",
		(OS_SEM_CTR   )0,
		(OS_ERR      *)&err);			
					
OSQCreate (	(OS_Q        *)&my_Q1,
                (CPU_CHAR    *)"my_Q1",
                (OS_MSG_QTY   )my_Q1_SIZE,
                (OS_ERR      *)&err);

12-2、等待多個內核對象

//===============多個內核對象 巨集定義===============

#define MY_OBJ_NUM 3					//多個內核對象 等待數量
	
//===============多個內核對象 等待===============

OS_PEND_DATA my_OBJ_data[MY_OBJ_NUM];	//多個內核對象 數組
	
my_OBJ_data[0].PendObjPtr = (OS_PEND_OBJ *)&my_Sem1;	//多個內核對象 對象0
my_OBJ_data[1].PendObjPtr = (OS_PEND_OBJ *)&my_Sem2;	//多個內核對象 對象1
my_OBJ_data[2].PendObjPtr = (OS_PEND_OBJ *)&my_Q1;	//多個內核對象 對象2
	
my_return_data = OSPendMulti (	(OS_PEND_DATA  *)my_OBJ_data,	    //多個內核對象 對象數組
				(OS_OBJ_QTY     )MY_OBJ_NUM,	    //多個內核對象 對象數量
				(OS_TICK        )0,		    //多個內核對象 等待超時時間
				(OS_OPT         )OS_OPT_PEND_BLOCKING,	//多個內核對象 阻塞 或 不阻塞
				(OS_ERR        *)&err);			//多個內核對象 等待錯誤

 

12-3、多個內核對象 發送

任意對象 post ,都會結束等待

 

13、記憶體管理

13-1、記憶體創建

//==================記憶體 巨集定義==================

OS_MEM IN_MEM;
#define IN_MEM_Block	5			//必須大於2
#define IN_MEM_Zone		25 * 4		//必須大於4,且為4的倍數,存放下一塊的地址內容,4位元組
CPU_INT08U IN_MEM_DATA[IN_MEM_Block][IN_MEM_Zone];

//==================記憶體 創建==================

OSMemCreate (  (OS_MEM       *)&IN_MEM,			//記憶體 結構體
               (CPU_CHAR     *)"IN_MEM",		//記憶體 名字
               (void         *)&IN_MEM_DATA[0][0],	//記憶體 基地址
               (OS_MEM_QTY    )IN_MEM_Block,		//記憶體 幾個塊,一維數組
               (OS_MEM_SIZE   )IN_MEM_Zone,		//記憶體 每個塊大小,二維數組
               (OS_ERR       *)&error);			//記憶體 創建成功與否

13-2、記憶體申請

u8 *p;

p = OSMemGet (	(OS_MEM  *)&IN_MEM,	//記憶體 結構體
		(OS_ERR  *)&err);	//記憶體 申請成功與否

13-3、記憶體釋放

OSMemPut ( (OS_MEM  *)&IN_MEM,	  //記憶體 結構體
	  (void    *)p,	  //記憶體 要釋放的地址
	  (OS_ERR  *)&err);	  //記憶體 釋放成功與否

 

備註:記憶體有申請,必釋放,如果申請後,不釋放,再申請,那之前申請的地址就找不到了,因為你的指針地址變了。

    所以,如果要多次申請的話,1、還要弄個指針數組,2、或者普通數組來存放當前申請的地址,3、或者知道UCOS的記憶體管理機制,直接去記憶體數組裡找到地址。

 

 

暫時就這樣,以後再檢查修改,手酸。

 


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

-Advertisement-
Play Games
更多相關文章
  • 最近有時間,整了Ubuntu16.04和Windows10雙系統,登陸完Ubuntu後回到Windwos,發現時間不准,網上找方案,如下辦法完美解決,備忘之。 首先在Ubuntu下打開Terminal終端,輸出如下代碼,讓Ubuntu時間與windows伺服器同步。 第二步將同步過來的時間刷進Cmo ...
  • 很久以前的編譯Linux內核使用的腳本,翻出來記錄一下 ...
  • 不小心翻出了很久很久以前使用busybox製作根文件系統的腳本程式,在此記錄一下 !/bin/bash SHELL_DIR=$(cd $(dirname ${0});pwd) cd ${SHELL_DIR} if [ "" = "$1" ];then echo " CMD clean/nfs/ram ...
  • 最近寫了一個遞歸Makefile,目的是既可以實現子模塊的單獨編譯,也可以不做任何修改就和整個程式的整體進行無縫銜接的編譯。具體的思路是藉助第三方文件,將子模塊編譯好的.o文件的路徑自動寫到config.mk文件中,在總控Makfile中只需要include這個config.mk就可以。單個模塊的編 ...
  • 如何查看程式占用的埠 一、查看占用指定埠的程式 如:查詢占用了8080埠的進程: 在開始-運行-cmd,輸入: netstat -ano|findstr "8080" (查看全部埠信息:netstat –ano ) 二、通過任務管理器殺死相關的進程 1. 首先找到進程號對應的進程名稱 tas ...
  • Restricted 執行策略不允許任何腳本運行。 AllSigned 和 RemoteSigned 執行策略可防止 Windows PowerShell 運行沒有數字簽名的腳本。 本主題說明如何運行所選未簽名腳本(即使在執行策略為 RemoteSigned 的情況下),還說明如... ...
  • Hexiwear擴展塢(Docking Station)有一個很不錯的功能:它板載了一個調試電路(OpenSDA)。 這樣我就不需要一個外部調試器來調試Hexiwear。 但是,重新編程擴展塢自身需要一個調試器。 本文展示瞭如何在Hexiwear擴展塢上對OpenSDA(DAPLink)引導載入程式 ...
  • 第一次發表博客,可能寫的不是很好,希望大家諒解! 今天咱們來上手一下Windows10下的bash,首先這款bash是基於Ubuntu操作系統的一個移植,也是方便開發和學習Linux中的shell命令。那麼我們來演示一下如何安裝bash,我們先要打開設置,找到裡面的更新和安全,裡面有一個模式叫針對開 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...