1. 程式人生 > >信盈達stm32f103zet6開發板移植ucosii系統

信盈達stm32f103zet6開發板移植ucosii系統

身為一個電子資訊工程的學生, 臨近畢業了才開始走進嵌入式的大門, 是不是有點晚了, 這次要用rtos主要是因為想用在物聯網家居專案上.廢話少說, 開始我的ucosii的移植之路吧, 參照正點原子的移植教程, 其實挺簡單的.

實驗開發板:信盈達stm32f103zet6(其實發現市面上的開發板都一大抄, 有幾家公式來我們學校實訓, 原理圖都和原子的差不多)

實驗參看教程:STM32F1 UCOS開發手冊_V2.0.pdf

實驗所用例程: 正點原子的ucosii移植例程

 

一. 移植準備工作:

1. 首先的準備移植所需的基礎工程, 我用的原子的跑馬燈實驗, 只是把led埠改了一下而已(後文會上傳)

2. UCOS II原始碼:獲取途徑有:

                   first:最權威, 最靠譜的: 從官網上下載:https://www.micrium.com/(注: 裡面有ucos的原始碼, 同時也有在各個平臺上移植好的原始碼, 不過我建議都是學電子的人, 什麼都要會自己移植, 一開始會很苦, 但是學會後就那麼回事, 始終不要被別人牽著鼻子走, 建議下不要移植好的原始碼)

                  second: 用原子提供的原始碼(ps: 因為在學校, 不方便下載, 就用原子的了, 後面我會上傳資源)

二.移植步驟:

1.開始擼起袖子開始移植啦!!!

在跑馬燈的工程中新建UCOSII資料夾, 再建子資料夾CONFIG, CORE, PORT

2.向CORE資料夾中新增檔案

在CORE資料夾中新增UCOSII原始碼, 我們開啟ucosii的原始碼Source資料夾, 裡面一共有14個檔案, 除了os_cfg_r.h os_dbg_r.c 這兩個檔案外, 我們獎其他的檔案都複製到我們的工程中UCOSII中的CORE資料夾下.

3.向CONFIG資料夾中新增檔案

在CONFIG資料夾中新增 includes.h和os_cfg.h. 這兩個檔案我是從原子的例程中拷過來的. 因為這兩個檔案涉及到系統裁剪等等, 目前還沒學, 只能做一次伸手黨了, 資源在後面的連線中,新增後如圖所示

4.向PORT資料夾中新增檔案

新增的檔案如下圖所示, 這些檔案也是從例程中來的, copy一下吧.

4.將與ucosii有關的檔案新增到工程中

我們在工程分組中新增三個分組, UCOSII-CORE, UCOSII-PORT, UCOSII-CONFIG.如下圖所示

分別向UCOSII-CORE, UCOSII-PORT, UCOSII-CONFIG這中新增如下圖所示的檔案,

注意:前外不要將ucos_ii.c檔案新增到UCOSII-CORE分組中!!! 否則編譯以後會提示好多重複定義的錯誤!

最後新增相應的標頭檔案路徑, 如圖所示:(注, mdk不會新增標頭檔案路徑的請百度) 

到這一步我們可以編譯一下整個工程了, 結果提示好多錯誤, 但是錯誤都是不能開啟"app_cfg.h"

追蹤錯誤的源頭後, 發現是ucos_ii.h標頭檔案中添加了app_cfg.h這個頭文佳, 但是這個頭文佳並沒有實現, 所以遮蔽即可, 新增includes.h

修改後在編譯一下, 還是提示錯誤

因為重複定義了PendSV_Handler這個函式, 這裡將stm32f10x_it.c檔案的該函式遮蔽掉, 我們再編譯一下工程發現沒錯了, 但是我們的移植還沒成功

5. 修改sys.h頭文佳

開啟sys.h檔案, 裡面有個SYSTEM_SUPPORT_UCOS的巨集定義, 預設定義為0 , 0不支援ucos, 我們將其改為1, 再次編譯工程, 發現提示重複定義了SysTick_Handler函式, 

同樣, 我們將stm32f10x_it.c檔案中的中斷函式SysTick_Handler遮蔽掉, 編譯後發現沒錯誤了,

三.測試程式

因為我現在還不會使用ucos的api 只好用原子的例程了, main函式程式碼如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"
/************************************************
 ALIENTEK戰艦STM32開發板UCOS實驗
 UCOSII移植
 技術支援:www.openedv.com
 淘寶店鋪:http://eboard.taobao.com 
 關注微信公眾平臺微訊號:"正點原子",免費獲取STM32資料。
 廣州市星翼電子科技有限公司  
 作者:正點原子 @ALIENTEK
************************************************/

//START 任務
//設定任務優先順序
#define START_TASK_PRIO			10  ///開始任務的優先順序為最低
//設定任務堆疊大小
#define START_STK_SIZE			128
//任務任務堆疊
OS_STK START_TASK_STK[START_STK_SIZE];
//任務函式
void start_task(void *pdata);

//LED0任務
//設定任務優先順序
#define LED0_TASK_PRIO			7
//設定任務堆疊大小
#define LED0_STK_SIZE			128
//任務堆疊
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任務函式
void led0_task(void *pdata);

//LED1任務
//設定任務優先順序
#define LED1_TASK_PRIO			6
//設定任務堆疊大小
#define LED1_STK_SIZE			128
//任務堆疊
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任務函式
void led1_task(void *pdata);

//浮點測試任務
#define FLOAT_TASK_PRIO			5
//設定任務堆疊大小
#define FLOAT_STK_SIZE			128
//任務堆疊
//如果任務中使用printf來列印浮點資料的話一點要8位元組對齊
__align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE]; 
//任務函式
void float_task(void *pdata);

int main(void)
{
	delay_init();       	//延時初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷分組配置
	uart_init(115200);    	//串列埠波特率設定
	LED_Init();  			//LED初始化
	
	OSInit();  				//UCOS初始化
	OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); //建立開始任務
	OSStart(); 				//開始任務
}

//開始任務
void start_task(void *pdata)
{
	OS_CPU_SR cpu_sr=0;
	pdata=pdata;
	OSStatInit();  //開啟統計任務
	
	OS_ENTER_CRITICAL();  //進入臨界區(關閉中斷)
	OSTaskCreate(led0_task,(void*)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);//建立LED0任務
	OSTaskCreate(led1_task,(void*)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);//建立LED1任務
	OSTaskCreate(float_task,(void*)0,(OS_STK*)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);//建立浮點測試任務
	OSTaskSuspend(START_TASK_PRIO);//掛起開始任務
	OS_EXIT_CRITICAL();  //退出臨界區(開中斷)
}
 

//LED0任務
void led0_task(void *pdata)
{
	while(1)
	{
		LED0=0; 
		delay_ms(300);
		LED0=1;
		delay_ms(300);
	}
}

//LED1任務
void led1_task(void *pdata)
{
	while(1)
	{
		LED1=0;
		delay_ms(300);
		LED1=1;
		delay_ms(300);
	}
}

//浮點測試任務
void float_task(void *pdata)
{
	OS_CPU_SR cpu_sr=0;
	static float float_num=0.01;
	while(1)
	{
		float_num+=0.01f;
		OS_ENTER_CRITICAL();	//進入臨界區(關閉中斷)
		printf("float_num的值為: %.4f\r\n",float_num); //串列埠列印結果
		OS_EXIT_CRITICAL();		//退出臨界區(開中斷)
		delay_ms(500);
	}
}

好了, 終於能看到移植成功的標誌了, led0與led1同時閃速, 並且串列埠有列印浮點數的資訊. 

本實驗所需例程連結: https://download.csdn.net/download/fourleafcloverllls/10716726 博主qq:1372090604 歡迎與我交流