西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
西西首頁(yè) 電腦軟件 安卓軟件 電腦游戲 安卓游戲 排行榜 專題合集

FreeRTOS stm32 完整移植包

  • FreeRTOS stm32 完整移植包
  • 軟件大小:8.5M
  • 更新時(shí)間:2013-07-22 16:09
  • 軟件語(yǔ)言:中文
  • 軟件廠商:
  • 軟件類別:國(guó)產(chǎn)軟件 / 免費(fèi)軟件 / 源碼相關(guān)
  • 軟件等級(jí):4級(jí)
  • 應(yīng)用平臺(tái):WinAll, WinXP
  • 官方網(wǎng)站:暫無(wú)
  • 應(yīng)用備案:
好評(píng):50%
壞評(píng):50%

本類精品

軟件介紹

介紹freertos在stm32上的移植說(shuō)明,每一步都很詳細(xì),讓你學(xué)會(huì)在stm32+freeRTOS的平臺(tái)上開發(fā)應(yīng)用程序

一、各文件關(guān)鍵部分的實(shí)現(xiàn):

1、PORTMACRO.H 宏定義部分
1)定義編譯器相關(guān)的各種數(shù)據(jù)類型
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE unsigned portLONG
#define portBASE_TYPE long

2)架構(gòu)相關(guān)的定義
Cortex-M3的堆棧增長(zhǎng)方向?yàn)楦叩刂废虻偷刂吩鲩L(zhǎng)
#define portSTACK_GROWTH ( -1 )
每毫秒的心跳次數(shù)
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
訪問(wèn)SRAM的字節(jié)對(duì)齊
#define portBYTE_ALIGNMENT 8

3)定義用戶主動(dòng)引起內(nèi)核調(diào)度的2個(gè)函數(shù)
強(qiáng)制上下文切換,用在任務(wù)環(huán)境中調(diào)用
#define portYIELD() vPortYieldFromISR()
強(qiáng)制上下文切換,用在中斷處理環(huán)境中調(diào)用
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()

4)定義臨界區(qū)的管理函數(shù)
中斷允許和關(guān)閉
#define portDISABLE_INTERRUPTS() vPortSetInterruptMask()
#define portENABLE_INTERRUPTS() vPortClearInterruptMask()
臨界區(qū)進(jìn)入和退出
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
用于在中斷環(huán)境的中斷允許和關(guān)閉
#define portSET_INTERRUPT_MASK_FROM_ISR() 0;vPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask();(void)x

2、PORT.C C接口部分
1)堆棧初始化
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
*pxTopOfStack = portINITIAL_XPSR; /* 程序狀態(tài)寄存器 */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* 任務(wù)的入口點(diǎn) */
pxTopOfStack--;
*pxTopOfStack = 0; /* LR */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* 任務(wù)的參數(shù) */
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}

2)啟動(dòng)任務(wù)調(diào)度
portBASE_TYPE xPortStartScheduler( void )
{
讓任務(wù)切換中斷和心跳中斷位于最低的優(yōu)先級(jí),使更高優(yōu)先級(jí)可以搶占mcu
*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;

設(shè)置并啟動(dòng)系統(tǒng)的心跳時(shí)鐘
prvSetupTimerInterrupt();

初始化臨界區(qū)的嵌套的個(gè)數(shù)
uxCriticalNesting = 0;

啟動(dòng)第一個(gè)任務(wù)
vPortStartFirstTask();

執(zhí)行到vPortStartFirstTask函數(shù),內(nèi)核已經(jīng)開始正常的調(diào)度
return 0;
}

3)主動(dòng)釋放mcu使用權(quán)
void vPortYieldFromISR( void )
{
觸發(fā)PendSV系統(tǒng)服務(wù)中斷,中斷到來(lái)時(shí)由匯編函數(shù)xPortPendSVHandler()處理
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
進(jìn)入臨界區(qū)時(shí),首先關(guān)閉中斷;當(dāng)退出所以嵌套的臨界區(qū)后再使能中斷
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
}
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
4)心跳時(shí)鐘處理函數(shù)
void xPortSysTickHandler( void )
{
unsigned portLONG ulDummy;

如果是搶占式調(diào)度,首先看一下有沒(méi)有需要調(diào)度的任務(wù)
#if configUSE_PREEMPTION == 1
*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
#endif

ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{ 通過(guò)task.c的心跳處理函數(shù)vTaskIncrementTick(),進(jìn)行時(shí)鐘計(jì)數(shù)和延時(shí)任務(wù)的處理
vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
}

3、PORTASM.S 匯編處理部分
1)請(qǐng)求切換任務(wù)
xPortPendSVHandler:
保存當(dāng)前任務(wù)的上下文到其任務(wù)控制塊
mrs r0, psp
ldr r3, =pxCurrentTCB 獲取當(dāng)前任務(wù)的任務(wù)控制塊指針
ldr r2, [r3]

stmdb r0!, {r4-r11} 保存R4-R11到該任務(wù)的堆棧
str r0, [r2] 將最后的堆棧指針保存到任務(wù)控制塊的pxTopOfStack

stmdb sp!, {r3, r14}
關(guān)閉中斷
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0
切換任務(wù)的上下文,pxCurrentTCB已指向新的任務(wù)

bl vTaskSwitchContext
mov r0, #0
msr basepri, r0
ldmia sp!, {r3, r14}
恢復(fù)新任務(wù)的上下文到各寄存器
ldr r1, [r3]
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
ldmia r0!, {r4-r11} /* Pop the registers. */
msr psp, r0
bx r14

2.)中斷允許和關(guān)閉的實(shí)現(xiàn),通過(guò)BASEPRI屏蔽相應(yīng)優(yōu)先級(jí)的中斷源
vPortSetInterruptMask:
push { r0 }
mov R0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
msr BASEPRI, R0
pop { R0 }

bx r14

vPortClearInterruptMask:
PUSH { r0 }
MOV R0, #0
MSR BASEPRI, R0
POP { R0 }

bx r14

3)直接切換任務(wù),用于vPortStartFirstTask第一次啟動(dòng)任務(wù)時(shí)初始化堆棧和各寄存器
vPortSVCHandler;
ldr r3, =pxCurrentTCB
ldr r1, [r3]
ldr r0, [r1]
ldmia r0!, {r4-r11}
msr psp, r0
mov r0, #0
msr basepri, r0
orr r14, r14, #13
bx r14

4)啟動(dòng)第一個(gè)任務(wù)的匯編實(shí)現(xiàn)
vPortStartFirstTask
通過(guò)中斷向量表的定位堆棧的地址
ldr r0, =0xE000ED08 向量表偏移量寄存器 (VTOR)
ldr r0, [r0]
ldr r0, [r0]
msr msp, r0 將堆棧地址保存到主堆棧指針msp中
觸發(fā)SVC軟中斷,由vPortSVCHandler()完成第一個(gè)任務(wù)的具體切換工作
svc 0

FreeRTOS內(nèi)核調(diào)度器啟動(dòng)的流程如下:

以上3個(gè)文件實(shí)現(xiàn)了FreeRTOS內(nèi)核調(diào)度所需的底層接口,相關(guān)代碼十分精簡(jiǎn)。

二、創(chuàng)建測(cè)試任務(wù):

下面創(chuàng)建第一個(gè)測(cè)試任務(wù),LED測(cè)試
int main( void )
{
設(shè)置系統(tǒng)時(shí)鐘,中斷向量表和LED使用的GPIO
使用stm32的固件包提供的初始化函數(shù),具體說(shuō)明見相關(guān)手冊(cè)
prvSetupHardware();

通過(guò)xTaskCreate()創(chuàng)建4個(gè)LED任務(wù)vLEDFlashTask(),
每個(gè)任務(wù)根據(jù)各自的頻率閃爍,分別對(duì)應(yīng)開發(fā)板上的4個(gè)LED
vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY );

? 創(chuàng)建一個(gè)IDLE任務(wù)后,通過(guò)xPortStartScheduler啟動(dòng)調(diào)度器
vTaskStartScheduler();

調(diào)度器工作不正常時(shí)返回
return 0;
}

portTASK_FUNCTION()是FreeRTOS定義的函數(shù)聲明,沒(méi)特殊作用
static portTASK_FUNCTION( vLEDFlashTask, pvParameters )
{
……省略……,具體為計(jì)算各LED的閃爍頻率
for(;;)
{
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
vParTestToggleLED( uxLED );

vTaskDelayUntil()的延時(shí)時(shí)間xFlashRate,是從上一次的延時(shí)時(shí)間xLastFlashTime算起的,
相對(duì)vTaskDelay()的直接延時(shí)更為精準(zhǔn)。
vTaskDelayUntil( &xLastFlashTime, xFlashRate );
vParTestToggleLED( uxLED );
}
}

FreeRTOS的任務(wù)創(chuàng)建與UC/OSII差異不大,主要參數(shù)為任務(wù)函數(shù),堆棧大小和任務(wù)的優(yōu)先級(jí)。如:
xTaskCreate( vLEDFlashTask, ( signed portCHAR * ) "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( xTaskHandle * ) NULL );

下面再創(chuàng)建一個(gè)LCD顯示任務(wù),以最低優(yōu)先級(jí)運(yùn)行:
xTaskCreate( vLCDTask, ( signed portCHAR * ) "LCD", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

void vLCDTask( void *pvParameters )
{
……省略……
for( ;; )
{
vTaskDelay(1000);
printf("%c ", usDisplayChar);
}
}
該任務(wù)很簡(jiǎn)單,每隔1000個(gè)ticks(就是1000ms),從LCD上刷新一個(gè)數(shù)字。

至此,F(xiàn)reeRTOS在STM32上的移植基本完成。與UC/OSII相比,F(xiàn)reeRTOS精簡(jiǎn)的實(shí)現(xiàn)更適合用來(lái)學(xué)習(xí)實(shí)時(shí)操作系統(tǒng)的工作原理,對(duì)其進(jìn)行剖析也相對(duì)容易。

接下來(lái),我們將會(huì)移植CAN,RS485,SD卡和USB等接口到FreeRTOS,使其在STM32平臺(tái)上更加完善。

軟件標(biāo)簽: FreeRTOS

其他版本下載

發(fā)表評(píng)論

昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
查看所有(0)條評(píng)論 > 字?jǐn)?shù): 0/500

TOP
軟件下載