嵌入式: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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...