-
準備freeRTOS源碼和一個簡單的工程
freeRTOS源碼下載下傳連結:
連結:https://pan.baidu.com/s/1hgyQqoDqDuETEHr_I80M8Q
提取碼:e890
另外還需要準備一個簡單的工程,這裡使用led閃爍的例子來完成移植
已移植好的stm32f103ve例程下載下傳連結:
https://download.csdn.net/download/mygod2008ok/12234264
-
開始移植
-
在led閃爍工程中建立一個檔案夾,并命名為freeRTOS

2.将準備好的freeRTOS庫中的源碼全部複制
3. 粘貼到led閃爍工程中的freeRTOS檔案夾中,并将portable中的檔案僅保留以下4個
4.在工程中建立兩個檔案組freeRTOS_sourcet和freeRTOS_portable,并加入以下檔案到工程,注意port.c選擇M3裡面的,因為stm32f1是m3系列
5. 另外要添加freeRTOS相關的檔案路徑到工程中
6.先編譯一下,出現如下錯誤
7.少了FreeRTOSConfig.h檔案,可以去下載下傳一個,也可以到freeRTOS提供的Demo中複制一份過來,這裡從DEMO中尋找
8.找到FreeRTOSConfig.h檔案複制
9.粘貼到工程中的FreeRTOS中的include檔案夾内
10.再次編譯一下工程,會出現以下錯誤
11.按住CTRL+F鍵,輸入xTaskGetCurrentTaskHandle後進行全局搜尋
12.搜尋結果如下
13.在FreeRTOSConfig.h中加入如下宏後再次編譯一下
#define INCLUDE_xTaskGetCurrentTaskHandle 1
14.對port.c中的三個函數進行适配,也就是讓啟動檔案分别能夠指向這三個函數
15.再次編譯一下,會出現以下錯誤
16.将stm32f10x_it.c中的SVC_Handler,PendSV_Handler,SysTick_Handler三個函數屏蔽掉,重新編譯一下工程
17.在main檔案中加入頭檔案task.h,然後編譯一下,出現如下錯誤
18.輕按兩下跳轉到出錯處,并加入FreeRTOS.h頭檔案再次編譯一下,編譯通過
19.在main中建立以下2個任務,main.c如下
/**
* @file main.c
* @author 仙劍情緣
* @version V1.0
* @data 20-Oct-2019
* @brief 序列槽USART2實驗
*
* 介紹配置USART2序列槽收發功能
*
*
*
*/
#include "stm32f10x_usart.h"
#include "stm32f10x.h"
#include <stdio.h>
#include "task.h"
/* 加入以下代碼,支援printf函數,而不需要選擇use MicroLIB */
#ifdef DEBUG
#pragma import(__use_no_semihosting)
//标準庫需要的支援函數
struct __FILE
{
int handle;
};
FILE __stdout;
//定義_sys_exit()以避免使用半主機模式
void _sys_exit(int x)
{
x = x;
}
//重定義fputc函數
int fputc(int ch, FILE *f)
{
while((USART2->SR&0X40)==0);
USART2->DR = (u8) ch;
return ch;
}
#endif
uint8_t rxBuf[40];
uint8_t rxLen;
/**
* @brief USART2序列槽初時化
*
*
* @param uint32_t baudrate[in]:設定波特率
* @retval None
*/
void Usart2_Init(uint32_t baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 初時化序列槽前,先将相應的時鐘打開 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
/* 初時化USART2 TX PA2引腳設為複用推挽輸出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/* 初時化USART2 RX PA3引腳為浮空輸入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);/*!< 複位序列槽2 */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);/*!< 停止複位 */
/* USART2 NVIC初時化 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /*!< 設定NVIC中斷分組2:2位搶占優先級,2位響應優先級 0-3; */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; /*!< USART2中斷通道USART1_IRQn */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; /*!< 搶占優先級3 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; /*!< 子優先級3 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /*!< IRQ使能通道 */
NVIC_Init(&NVIC_InitStructure); /*!< 初時化NVIC寄存器 */
/* USART2初時化設定 */
USART_InitStructure.USART_BaudRate = baudrate; /*!< 設定波特率 */
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; /*!< 8位資料*/
USART_InitStructure.USART_StopBits = USART_StopBits_1; /*!< 1位停止位 */
USART_InitStructure.USART_Parity = USART_Parity_No; /*!< 無校驗位 */
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /*!< 收發模式*/
USART_Init(USART2,&USART_InitStructure); /*!< 初時化序列槽2 */
/* 開啟序列槽2接收中斷 */
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
/* 使能序列槽2 */
USART_Cmd(USART2,ENABLE);
}
/**
* @brief USART2序列槽發送函數
*
*
* @param uint8_t *buf[in]:待發送的資料buffer
* @param uint16_t len:發送的資料長度
* @retval None
*/
void USART2_Send_Data(uint8_t *buf,uint16_t len)
{
for(uint16_t i = 0; i<len; i++)
{
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET); /*!< 是否可以寫資料到發送寄存器*/
USART_SendData(USART2,buf[i]);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); /*!<發送是否完成*/
}
}
/**
* @brief USART2序列槽中斷函數
*
*
* @param None
* @retval None
*/
void USART2_IRQHandler(void)
{
/* 暫存接收結果 */
uint8_t result;
/* @note
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
* error) and IDLE (Idle line detected) pending bits are cleared by
* software sequence: a read operation to USART_SR register
* (USART_GetITStatus()) followed by a read operation to USART_DR register
* (USART_ReceiveData()).
* - RXNE pending bit can be also cleared by a read to the USART_DR register
* (USART_ReceiveData()).
*/
/* 檢查是否為USART2接收中斷 */
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
{
result = USART_ReceiveData(USART2);
if(rxLen < 20)
{
rxBuf[rxLen] = result;
rxLen++;
}
}
/* 溢出發生時,先讀SR,再讀DR,解決中斷不進入問題*/
else if(USART_GetFlagStatus(USART2,USART_IT_ORE) == SET)
{
USART_ClearFlag(USART2,USART_IT_ORE);
USART_ReceiveData(USART2);
}
}
// 任務句柄
TaskHandle_t task2_handler;
/**
* 任務2
*/
void led2_task(void* t)
{
while(1)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_9))
GPIO_ResetBits(GPIOB, GPIO_Pin_9 );
else
GPIO_SetBits(GPIOB, GPIO_Pin_9 );
printf("task2\n");
vTaskDelay(20);
}
}
/**
* 任務1
*/
void led1_task(void* t)
{
uint8_t i = 5;
while(1)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_8))
GPIO_ResetBits(GPIOB, GPIO_Pin_8 );
else
GPIO_SetBits(GPIOB, GPIO_Pin_8 );
printf("task1\n");
vTaskDelay(10);
if(i > 0)
{
if(--i == 0)
{
vTaskDelete(task2_handler);
}
}
}
}
/**
* @brief 主函數,程式的入口
*
*
* @param None
* @retval int:不用理會,對于嵌入式系統,永遠都不會傳回
*/
int main(void)
{
Usart2_Init(9600);
printf("%s","hello world");
// assert_param(0);
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
xTaskCreate(led2_task, "LED2", configMINIMAL_STACK_SIZE, NULL, 3, &task2_handler );
xTaskCreate(led1_task, "LED1", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
vTaskStartScheduler();
for(;;)
{
if(rxLen >= 20)
{
USART2_Send_Data(rxBuf,20);
rxLen = 0;
}
}
}
#if USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
printf("\r\nfile path is %s,error line is %d\r\n",file,line);
while(1);
}
#endif
編譯運作
-
protues仿真代碼下載下傳,注意protues仿真STM32序列槽會亂碼https://download.csdn.net/download/mygod2008ok/12234385