FreeRtos在RH850 D1L芯片上移植
1. FreeRTOS下载包的文件结构
在FreeRTOS官方网站可以下载到最新版的FreeRTOS包,我这里使用的是V9.0.0版本。
下载包根目录下包含两个子目录:FreeRTOS和FreeRTOS-Plus。其中,FreeRTOS-Plus文件夹中包含一些FreeRTOS+组件和演示例程(组件大都收费),我们不对这个文件夹下的内容多做了解,重点说一下FreeRTOS文件夹。
FreeRTOS文件夹下包含两个子目录:Demo和Source。其中,Demo包含演示例程的工程文件,Source包含实时操作系统源代码文件。
FreeRTOS实时操作系统内核仅包含三个必要文件,此外还有三个可选文件。RTOS核心代码位于三个源文件中,分别是tasks.c、queue.c和list.c。这三个文件位于FreeRTOS/Source目录下,在同一目录下还有3个可选的文件,叫做timers.c、event_groups.c和croutine.c,分别用于软件定时器、事件组和协程。
2. 移植前的一些准备
- 一块具有RH850微处理器的硬件板子,并且保证板子可以正常运转。
- http://www.freertos.org/,下载FreeRTOS程序包,压缩文件大概50M。
- https://www.renesas.com/zh-cn/products/microcontrollers-microprocessors/rh850/rh850d1x/rh850d1l.html#downloads下载RH850 D1L的编译器CS+,该软件有60天的使用期,对移植OS已完全够用。
3.移植过程
3.1、打开CS+,File-New-Create New Project
3.2、新建项目如下:其中Boot.asm是定义中断向量的地方,Freertos需要将Tick中断移植在该文件中,后续会具体介绍。
cstart.asm主要是数据段初始化,不需要关注。
iodefine.h是编译器生成的寄存器结构体,在设置OS Tick时钟时需要关注下。
Main.c,这个不讲了。
3.3、在该工程中添加文件夹,如下:
OS文件夹:存放FreeRtos代码
SRC:Kernel C文件
Include:Kernel 头文件
Portable:针对不同编译器和硬件需要移植的文件。
3.4、首先添加OS的Kernel C文件,解压官网下载的FreeRTOSv9.0.0.zip,将\FreeRTOS\Source下的文件拷贝到当前工程目录下:
3.5、在CS+下将上述文件添加工程目录:
3.6、添加OS的Kernel 头文件,解压官网下载的FreeRTOSv9.0.0.zip,将\FreeRTOS\Source\include下的文件拷贝到当前工程目录下:
3.7、添加OS的Kernel portable文件,解压官网下载的FreeRTOSv9.0.0.zip,在FreeRTOS\Source\portable\下有很多官方的Demo,对应各个编译器和芯片。我用的芯片是RH850 D1L系列,当前官方并没有支持。所以我选了指令集相近的V850ES Demo。位置在FreeRTOS\Source\portable\IAR\V850ES,将文件夹下的文件拷贝到当前工程目录下:
3.8、将以上文件添加到CS+工程:
3.9、下面进行最关键的部分,修改Portable中的文件
3.9.1、首先将ISR_Support.h,portasm_Fx3.s85,portasm_hx2.s85文件从工程中删除,这几个文件没有用到。
3.9.2、编辑Port.c文件,找到static void prvSetupTimerInterrupt( void )函数,这个函数是设置OS的Tick时钟中断
3.9.3、将Portasm.s85中的汇编函数移植到Port.c中,随后将Portasm.s85从工程中删除。
下面是移植后的代码:
=========================================================
#pragma inline_asm trap_set
void trap_set(void)
{
trap 0x00
}
#pragma inline_asm portSAVE_CONTEXT
void portSAVE_CONTEXT(void)
{
//add -0x0C,sp //prepare stack to save necessary values
//st.w lp,8[sp] //store LP to stack
// stsr 0,r31,0
//st.w lp,4[sp] //store EIPC to stack
//stsr 1,lp,0
//st.w lp,0[sp] //store EIPSW to stack
#if configDATA_MODE == 1 // Using the Tiny data model
prepare r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,76,sp // save general purpose registers
sst.w r19,72[ep]
sst.w r18,68[ep]
sst.w r17,64[ep]
sst.w r16,60[ep]
sst.w r15,56[ep]
sst.w r14,52[ep]
sst.w r13,48[ep]
sst.w r12,44[ep]
sst.w r11,40[ep]
sst.w r10,36[ep]
sst.w r9,32[ep]
sst.w r8,28[ep]
sst.w r7,24[ep]
sst.w r6,20[ep]
sst.w r5,16[ep]
sst.w r4,12[ep]
#else // Using the Small/Large data model
prepare r20,r21,r22,r23,r24,r26,r27,r28,r29,r30,72,sp //save general purpose registers
sst.w r19,68[ep]
sst.w r18,64[ep]
sst.w r17,60[ep]
sst.w r16,56[ep]
sst.w r15,52[ep]
sst.w r14,48[ep]
sst.w r13,44[ep]
sst.w r12,40[ep]
sst.w r11,36[ep]
sst.w r10,32[ep]
sst.w r9,28[ep]
sst.w r8,24[ep]
sst.w r7,20[ep]
sst.w r6,16[ep]
sst.w r5,12[ep]
#endif /* configDATA_MODE */
sst.w r2,8[ep]
sst.w r1,4[ep]
MOVHI highw1(#_usCriticalNesting),r0,r1 //save usCriticalNesting value to stack
ld.w loww(#_usCriticalNesting)[r1],r2
sst.w r2,0[ep]
MOVHI highw1(#_pxCurrentTCB),r0,r1 // save SP to top of current TCB
ld.w loww(#_pxCurrentTCB)[r1],r2
st.w sp,0[r2]
}
/*-----------------------------------------------------------*/
#pragma inline_asm portRESTORE_CONTEXT
void portRESTORE_CONTEXT(void)
{
MOVHI highw1(#_pxCurrentTCB),r0,r1 // get Stackpointer address
ld.w loww(#_pxCurrentTCB)[r1],sp
MOV sp,r1
ld.w 0[r1],sp // load stackpointer
MOV sp,ep // set stack pointer to element pointer
sld.w 0[ep],r1 // load usCriticalNesting value from stack
MOVHI highw1(#_usCriticalNesting),r0,r2
st.w r1,loww(#_usCriticalNesting)[r2]
sld.w 4[ep],r1 // restore general purpose registers
sld.w 8[ep],r2
#if configDATA_MODE == 1 //Using Tiny data model
sld.w 12[ep],r4
sld.w 16[ep],r5
sld.w 20[ep],r6
sld.w 24[ep],r7
sld.w 28[ep],r8
sld.w 32[ep],r9
sld.w 36[ep],r10
sld.w 40[ep],r11
sld.w 44[ep],r12
sld.w 48[ep],r13
sld.w 52[ep],r14
sld.w 56[ep],r15
sld.w 60[ep],r16
sld.w 64[ep],r17
sld.w 68[ep],r18
sld.w 72[ep],r19
dispose 76,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30
#else //Using Small/Large data model
sld.w 12[ep],r5
sld.w 16[ep],r6
sld.w 20[ep],r7
sld.w 24[ep],r8
sld.w 28[ep],r9
sld.w 32[ep],r10
sld.w 36[ep],r11
sld.w 40[ep],r12
sld.w 44[ep],r13
sld.w 48[ep],r14
sld.w 52[ep],r15
sld.w 56[ep],r16
sld.w 60[ep],r17
sld.w 64[ep],r18
sld.w 68[ep],r19
dispose 72,r20,r21,r22,r23,r24,r26,r27,r28,r29,r30
#endif /* configDATA_MODE */
//ld.w 0[sp],lp //restore EIPSW from stack
//ldsr lp,1,0
//ld.w 4[sp],lp //restore EIPC from stack
// ldsr lp,0,0
//ld.w 8[sp],lp //restore LP from stack
//add 0x0C,sp //set SP to right position
//EIRET
}
#pragma inline_asm vPortStart
void vPortStart(void)
{
jarl _portRESTORE_CONTEXT,lp // Restore the context of whichever task the ...
ld.w 0[sp],lp
ldsr lp,5 //restore PSW
DI
ld.w 4[sp],lp //restore LP
ld.w 8[sp],lp //restore LP
ADD 0x0C,sp //set SP to right position
EI
jmp [lp]
}
#pragma inline_asm vPortYield
void vPortYield(void)
{
add -0x0C,sp // prepare stack to save necessary values
st.w lp,8[sp] // store LP to stack
stsr 0,r31
st.w lp,4[sp] // store EIPC to stack
stsr 1,lp
st.w lp,0[sp] // store EIPSW to stack
jarl _portSAVE_CONTEXT,lp // Save the context of the current task.
jarl _vTaskSwitchContext,lp // Call the scheduler.
jarl _portRESTORE_CONTEXT,lp //Restore the context of whichever task the ...
// ... scheduler decided should run.
ld.w 0[sp],lp // restore EIPSW from stack
ldsr lp,1
ld.w 4[sp],lp // restore EIPC from stack
ldsr lp,0
ld.w 8[sp],lp //restore LP from stack
add 0x0C,sp // set SP to right position
EIRET
}
#pragma inline_asm MD_INTTM0EQ0
void MD_INTTM0EQ0(void)
{
add -0x0C,sp // prepare stack to save necessary values
st.w lp,8[sp] // store LP to stack
stsr 0,r31
st.w lp,4[sp] // store EIPC to stack
stsr 1,lp
st.w lp,0[sp] // store EIPSW to stack
jarl _portSAVE_CONTEXT,lp // Save the context of the current task.
jarl _xTaskIncrementTick,lp // Call the timer tick function.
jarl _vTaskSwitchContext,lp // Call the scheduler.
jarl _portRESTORE_CONTEXT,lp // Restore the context of whichever task the ...
//... scheduler decided should run.
ld.w 0[sp],lp // restore EIPSW from stack
ldsr lp,1
ld.w 4[sp],lp //restore EIPC from stack
ldsr lp,0
ld.w 8[sp],lp // restore LP from stack
add 0x0C,sp // set SP to right position
EIRET
}
===============================================================
3.9.4、修改StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
中的编译开关,将#if (__DATA_MODEL__ == 0) || (__DATA_MODEL__ == 1)---》#if (configDATA_MODE == 1 )
3.9.5、增加函数声明
3.9.6、修改portmacro.h,找到如下宏定义,修改成如下语句。
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __asm ( "DI" )
#define portENABLE_INTERRUPTS() __asm ( "EI" )
==》
/* Interrupt control macros. */
#define portDISABLE_INTERRUPTS() __DI()
#define portENABLE_INTERRUPTS() __EI()
#define portYIELD() __asm ( "trap 0" )
#define portNOP() __asm ( "NOP" )
=》
#define portYIELD() trap_set()
#define portNOP() (__nop())
3.9.5、FreeRTOSConfig.h,Freertos配置文件,从官方下载目录FreeRTOS\Demo\NEC_V850ES_IAR拷贝到工程目录下
FreeRTOSConfig.h文件内容如下:
/*
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
All rights reserved
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
***************************************************************************
>>! NOTE: The modification to the GPL is included to allow you to !<<
>>! distribute a combined work that includes FreeRTOS without being !<<
>>! obliged to provide the source code for proprietary components !<<
>>! outside of the FreeRTOS kernel. !<<
***************************************************************************
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Full license text is available on the following
link: http://www.freertos.org/a00114.html
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that is more than just the market leader, it *
* is the industry's de facto standard. *
* *
* Help yourself get started quickly while simultaneously helping *
* to support the FreeRTOS project by purchasing a FreeRTOS *
* tutorial book, reference manual, or both: *
* http://www.FreeRTOS.org/Documentation *
* *
***************************************************************************
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
the FAQ page "My application does not run, what could be wrong?". Have you
defined configASSERT()?
http://www.FreeRTOS.org/support - In return for receiving this top quality
embedded software for free we request you assist our global community by
participating in the support forum.
http://www.FreeRTOS.org/training - Investing in training allows your team to
be as productive as possible as early as possible. Now you can receive
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
Ltd, and the world's leading authority on the world's leading RTOS.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and commercial middleware.
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
engineered and independently SIL3 certified version for use in safety and
mission critical applications that require provable dependability.
1 tab == 4 spaces!
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include "iodefine.h"
/* only include in C files */
#ifdef __IAR_SYSTEMS_ICC__
#pragma language=extended
#pragma system_include
#include <intrinsics.h>
#endif /* __IAR_SYSTEMS_ICC__ */
/* V850ES/Fx3 Memory Model
* 1 = Tiny data model
* 0 = Small/Large data model
*/
#define configDATA_MODE 0
/*
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*/
#define configUSE_PREEMPTION 1
/* only include in C files */
//#ifdef __IAR_SYSTEMS_ICC__
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 85 )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 1
#define configUSE_QUEUE_SETS 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configUSE_COUNTING_SEMAPHORES 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_xTaskResumeFromISR 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_TIMERS 1 // 使能软件定时器
#define configTIMER_TASK_PRIORITY 1 // 确定软件定时器进程优先级(根据具体应用而定,不要设的过低,否则精度也会随之下降)
#define configTIMER_QUEUE_LENGTH 10 // 定时器命令队列(Timer Command Queue)长度
#define configTIMER_TASK_STACK_DEPTH 512 // 分配给软件定时器任务的内存大小
#define INCLUDE_eTaskGetState 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* This IAR workspace contains several different projects - each of which
is targeted at a different device variant. The definitions past this point
are dependent on the variant being used. */
//#ifdef __IAR_V850ES_Fx3__
//#include "io70f3385.h"
#define configTOTAL_HEAP_SIZE ( (size_t ) ( 20000 ) )
#define configCPU_CLOCK_HZ ( ( unsigned long ) 120000000 )
//#endif
#ifdef __IAR_V850ES_Jx3__
#include "io70f3746.h"
#define configTOTAL_HEAP_SIZE ( (size_t ) ( 9000 ) )
#define configCPU_CLOCK_HZ ( ( unsigned long ) 16000000 )
#endif
#ifdef __IAR_V850ES_Jx3_L__
#include "io70f3738.h"
#define configTOTAL_HEAP_SIZE ( (size_t ) ( 9000 ) )
#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 )
#endif
#ifdef __IAR_V850ES_Jx2__
#include "io70f3717.h"
#define configTOTAL_HEAP_SIZE ( (size_t ) ( 9000 ) )
#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 )
#endif
#ifdef __IAR_V850ES_Hx2__
#include "io70f3707.h"
#define configTOTAL_HEAP_SIZE ( (size_t ) ( 9000 ) )
#define configCPU_CLOCK_HZ ( ( unsigned long ) 20000000 )
#endif
//#endif /* __IAR_SYSTEMS_ICC__ */
#endif /* FREERTOS_CONFIG_H */
3.9.6、将FreeRTOSConfig.h添加到CS+工程,编译,会有类型编译错误。
1)、FreeRTOS.h中删除stdint.h,这个文件找不到
//#include <stdint.h> /* READ COMMENT ABOVE. */
2)增加类型宏定义文件r_typedefs.h到工程:
/**********************************************************************************************************************
* Library : Code Flash Access Library for Renesas RH850 devices, based on the RV40 Flash technology
*
* File Name : $Source: r_typedefs.h $
* Lib. Version : $RH850_FCL_LIB_VERSION_T01: V2.00 $
* Mod. Revision : $Revision: 1.9 $
* Mod. Date : $Date: 2014/09/01 13:40:54MESZ $
* Device(s) : RV40 Flash based RH850 microcontroller
* Description : This file contains standard C99 type definitions used by FCL
**********************************************************************************************************************/
/**********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with
* Renesas products. No other uses are authorized. This software is owned by Renesas Electronics
* Corporation and is protected under all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING THIS SOFTWARE,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR
* ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the
* availability of this software. By using this software, you agree to the additional terms and conditions
* found by accessing the following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2014 Renesas Electronics Corporation. All rights reserved.
**********************************************************************************************************************/
#ifdef ENABLE_QAC_TEST
#pragma PRQA_MESSAGES_ON 0292
#endif
/**********************************************************************************************************************
* MISRA Rule: MISRA-C 2004 rule 3.1 (QAC message 0292)
* Reason: To support automatic insertion of revision, module name etc. by the source
* revision control system it is necessary to violate the rule, because the
* system uses non basic characters as placeholders.
* Verification: The placeholders are used in commentars only. Therefore rule violation cannot
* influency code compilation.
**********************************************************************************************************************/
/*********************************************************************************************************************
* MISRA Rule: MISRA-C 2004 rule 20.1 (QAC message 4600)
* Reason: It is up to the customer to use standard libraries or not. Nevertheless, the standard definitions
* are necessary.
* Verification: Used definitions are similar to the definitions used in the standard library. Therefore rule
* violation is not a risk in this software module.
*********************************************************************************************************************/
#ifndef R_TYPEDEFS_H
#define R_TYPEDEFS_H
/**********************************************************************************************************************
Macro definitions
**********************************************************************************************************************/
#define bool rBool /* PRQA S 4600 */
#define false 0 /* PRQA S 4600 */
#define true 1 /* PRQA S 4600 */
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483647 - 1)
#define INT64_MIN (-9223372036854775807LL - 1LL)
#define INT8_MAX (127)
#define INT16_MAX (32767)
#define INT32_MAX (2147483647)
#define INT64_MAX (9223372036854775807LL)
#define UINT8_MAX (255)
#define UINT16_MAX (65535)
#define UINT32_MAX (4294967295U)
#define UINT64_MAX (18446744073709551615ULL)
/**********************************************************************************************************************
Typedef definitions
**********************************************************************************************************************/
typedef signed char int8_t; /**< Signed 8 bit integer values */
typedef unsigned char uint8_t; /**< Unsigned 8 bit integer values */
typedef signed short int16_t; /**< Signed 16 bit integer values */
typedef unsigned short uint16_t; /**< Unsigned 16 bit integer values */
typedef signed long int32_t; /**< Signed 32 bit integer values */
typedef unsigned long uint32_t; /**< Unsigned 32 bit integer values */
typedef unsigned long long uint64_t;/**< Unsigned 64 bit integer values */
typedef unsigned char rBool; /**< Boolean value is 8 bit unsigned */
/**********************************************************************************************************************
Exported global variables
**********************************************************************************************************************/
/**********************************************************************************************************************
Exported global functions (to be accessed by other files)
**********************************************************************************************************************/
#endif /* end of R_TYPEDEFS_H */
3.9.7、在FreeRTOSConfig.h中增加头文件
#include "iodefine.h"
#include "r_typedefs.h"
3.9.8、我的工程使用了静态分配内存和Timer,main.c内容如下:
/***********************************************************************//* */
/* FILE :Main.c */
/* DATE :Mon, Oct 24, 2016 */
/* DESCRIPTION :Main Program */
/* CPU TYPE : */
/* */
/* NOTE:THIS IS A TYPICAL EXAMPLE. */
/* */
/***********************************************************************/
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "event_groups.h"
void main(void);
#define STACK_SIZE 100
StaticTask_t IdleTaskBuffer;
StackType_t IdleStack[ STACK_SIZE ];
StaticTask_t TimerTaskBuffer;
StackType_t TimerStack[ STACK_SIZE ];
static void vLED_1_Task( void *pvParameters );
static void vLED_2_Task( void *pvParameters );
static void vLED_3_Task( void *pvParameters );
unsigned int testcount1 = 0;
unsigned int testcount2 = 0;
unsigned int testcount3 = 0;
StaticTask_t TaskBuffer1;
StackType_t Stack1[ STACK_SIZE ];
StaticTask_t TaskBuffer2;
StackType_t Stack2[ STACK_SIZE ];
StaticTask_t TaskBuffer3;
StackType_t Stack3[ STACK_SIZE ];
void main(void)
{
}
void vApplication*Hook( TaskHandle_t xTask, char *pcTaskName )
{
/* This will be called if a task overflows its stack. pxCurrentTCB
can be inspected to see which is the offending task. */
xTaskCreateStatic( vLED_1_Task, ( signed portCHAR * ) "LED1", STACK_SIZE, NULL, tskIDLE_PRIORITY+1, Stack1,&TaskBuffer1 );
xTaskCreateStatic( vLED_2_Task, ( signed portCHAR * ) "LED2", STACK_SIZE, NULL, tskIDLE_PRIORITY+3, Stack2,&TaskBuffer2 );
xTaskCreateStatic( vLED_3_Task, ( signed portCHAR * ) "LED3", STACK_SIZE, NULL, tskIDLE_PRIORITY+2, Stack3,&TaskBuffer3 );
vTaskStartScheduler();
for( ;; );
}
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
*pulIdleTaskStackSize = STACK_SIZE;
*ppxIdleTaskTCBBuffer = &IdleTaskBuffer;
*ppxIdleTaskStackBuffer = IdleStack;
}
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
*pulTimerTaskStackSize = STACK_SIZE;
*ppxTimerTaskTCBBuffer = &TimerTaskBuffer;
*ppxTimerTaskStackBuffer = TimerStack;
}
static void vLED_1_Task(void *pvParameters)
{
TickType_t xLastWakeTime;
const TickType_t xFrequency = 10;
xLastWakeTime = xTaskGetTickCount ();
for( ;; )
{
//vTaskDelay(1000/portTICK_RATE_MS);
// Wait for the next cycle.
vTaskDelayUntil( &xLastWakeTime, xFrequency );
testcount1++;
}
vTaskDelete( NULL );
}
static void vLED_2_Task(void *pvParameters)
{
for( ;; )
{
vTaskDelay(500/portTICK_RATE_MS);
/* Wait until it is time to check all the other tasks again. */
testcount2++;
//break;
}
vTaskDelete( NULL );
}
static void vLED_3_Task(void *pvParameters)
{
for( ;; )
{
vTaskDelay(2000/portTICK_RATE_MS);
testcount3++;
//break;
}
vTaskDelete( NULL );
}
3.9.9、编译通过,现在要把Tick和Trap中断函数挂到相应的中断向量上,打开boot.asm,找到trap0和priority0中断向量;将中断函数vPortYield和MD_INTTM0EQ0填写到相应位置上。
.align 16
jr32 _vPortYield ; TRAP0
jr32 _MD_INTTM0EQ0 ; INTn(priority0)
3.9.10,再次编译,通过,可下载到开发硬件上,能发现freertos可运行。
移植后的代码已上传,关键字 freertos