nano130 移植 freertos 8.2.3 基于Nano100B_Series_BSP_CMSIS_V3.02.000

从新唐 官网下载的:BSP
Nano100B_Series_BSP_CMSIS_V3.02.000.zip

从freertos 网站下载的:
FreeRTOSV8.2.3.zip

参考文档:
FreeRTOS在Nano100上的移植.pptx
参考例程:
[Nano100B]FREERTOS.zip

1 解压 Nano100B_Series_BSP_CMSIS_V3.02.000.zip

进入如下目录,
打开keil工程

E:\freertos\nano100\Nano100B Series BSP_CMSIS_V3.02.000\SampleCode\StdDriver\UART_TxRx_Function\KEIL
双击:UART_TxRx_Function.uvproj

UART0:
这里写图片描述

这里写图片描述

这里写图片描述

在此项目的基础上,添加 Freertos的支持。
注意实际上使用如下模板工程,效果更好
E:\freertos\nano100\Nano100B Series BSP_CMSIS_V3.02.000\SampleCode\Template\Keil\

2 解压FreeRTOSV8.2.3.zip

建立 目录 E:\freertos\nano100\Nano100B Series BSP_CMSIS_V3.02.000\
在此目录下,解压FreeRTOSV8.2.3.zip
得到,如下目录结构
E:\freertos\nano100\Nano100B Series BSP_CMSIS_V3.02.000\ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source

3 添加文件FreeRTOS到UART_TxRx_Function

这里写图片描述

添加分组:Freertos
添加文件:
E:\freertos\nano100\Nano100B Series BSP_CMSIS_V3.02.000\ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source

list.c
queue.c
tasks.c
timers.c
ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source\portable\RVDS\ARM_CM0
port.c
ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source\portable\MemMang
heap_2.c

最后的效果图:
这里写图片描述

4 添加 include路径到 keil 工程

这里写图片描述

……..\ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source\include
……..\ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Source\portable\RVDS\ARM_CM0
……..\ThirdParty\FreeRTOSV8.2.3\FreeRTOS\Demo\Common\include
….\UART_TxRx_Function

这里写图片描述

5 添加 FreeRTOSConfig.h文件

添加FreeRTOSConfig.h文件到目录
Nano100B Series BSP_CMSIS_V3.02.000\SampleCode\StdDriver\UART_TxRx_Function\ 下面:
内容为:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * 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.
 *
 * See http://www.freertos.org/a00110.html.
 *----------------------------------------------------------*/

/* Ensure stdint is only used by the compiler, and not the assembler. */
#ifdef __ICCARM__
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif

#ifdef __ARMCC_VERSION
#include "nano100series.h"
#endif

#define configUSE_PREEMPTION            1
#define configUSE_IDLE_HOOK             1
#define configUSE_TICK_HOOK             1
#define configCPU_CLOCK_HZ              ( SystemCoreClock )
#define configTICK_RATE_HZ              ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES            ( ( unsigned portBASE_TYPE ) 5 )
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 50 )
#define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 8 * 1024 ) )
#define configMAX_TASK_NAME_LEN         ( 10 )
#define configUSE_TRACE_FACILITY        1
#define configUSE_16_BIT_TICKS          0
#define configIDLE_SHOULD_YIELD         1
#define configUSE_MUTEXES               1
#define configQUEUE_REGISTRY_SIZE       8
#define configCHECK_FOR_STACK_OVERFLOW  0
#define configUSE_RECURSIVE_MUTEXES     1
#define configUSE_MALLOC_FAILED_HOOK    1
#define configUSE_APPLICATION_TASK_TAG  0
#define configUSE_COUNTING_SEMAPHORES   1
#define configGENERATE_RUN_TIME_STATS   0
#define configUSE_QUEUE_SETS            1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS                1
#define configTIMER_TASK_PRIORITY       ( 2 )
#define configTIMER_QUEUE_LENGTH        10
#define configTIMER_TASK_STACK_DEPTH    ( configMINIMAL_STACK_SIZE * 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   1
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay              1

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS             __NVIC_PRIO_BITS
#else
#define configPRIO_BITS             4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0xf

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

6 编译错误

会出现如下错误:

.\obj\UART.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
.\obj\UART.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
.\obj\UART.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_2.o).
Not enough information to produce a FEEDBACK file.
Not enough information to list image symbols.
Finished: 2 information, 0 warning and 3 error messages.
".\obj\UART.axf" - 3 Error(s), 0 Warning(s).

7 修改main.c文件

添加如下函数:

vApplicationTickHook

void vApplicationTickHook(void)
{
    /* This function will be called by each tick interrupt if
    configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
    added here, but the tick hook is called from an interrupt context, so
    code must not attempt to block, and only the interrupt safe FreeRTOS API
    functions can be used (those that end in FromISR()).  */

}

vApplicationIdleHook

void vApplicationIdleHook(void)
{
    /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
    to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
    task.  It is essential that code added to this hook function never attempts
    to block in any way (for example, call xQueueReceive() with a block time
    specified, or call vTaskDelay()).  If the application makes use of the
    vTaskDelete() API function (as this demo application does) then it is also
    important that vApplicationIdleHook() is permitted to return to its calling
    function, because it is the responsibility of the idle task to clean up
    memory allocated by the kernel to any task that has since been deleted. */
}

vApplicationMallocFailedHook

void vApplicationMallocFailedHook(void)
{
    /* vApplicationMallocFailedHook() will only be called if
    configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
    function that will get called if a call to pvPortMalloc() fails.
    pvPortMalloc() is called internally by the kernel whenever a task, queue,
    timer or semaphore is created.  It is also called by various parts of the
    demo application.  If heap_1.c or heap_2.c are used, then the size of the
    heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
    FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
    to query the size of free heap space that remains (although it does not
    provide information on how the remaining heap might be fragmented). */
    taskDISABLE_INTERRUPTS();
    for(;;);
}

添加如下头文件:

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

8 编译成功

9 修改main.c

添加如下函数:

#define THREAD_TEST_STACK_SIZE  configMINIMAL_STACK_SIZE    
#define THREAD_TEST_PRIORITY    ( tskIDLE_PRIORITY + 1 )

void Thread_Task1( void *pvParameters );
void Thread_Task2( void *pvParameters );

void vStartThreadTasks( void )
{
    xTaskCreate( Thread_Task1, (const  char * ) "Th_Task1", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
    xTaskCreate( Thread_Task2, (const  char * ) "Th_Task2", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
}

void Thread_Task1( void *pvParameters )
{
    portTickType xLastTime1;

    /* Get current system TickCount. */
    xLastTime1 = xTaskGetTickCount();

    for( ;; )
    {
        /* Run a time every 400 milliseconds. */
        vTaskDelayUntil( &xLastTime1, 400 );

        printf("Task1 called-\n");
    }   
}

void Thread_Task2( void *pvParameters )
{
    portTickType xLastTime2;

    /* Get current system TickCount. */
    xLastTime2 = xTaskGetTickCount();   

    for( ;; )
    {
        /* Run a time every 800 milliseconds. */
        vTaskDelayUntil( &xLastTime2, 800 );
        printf("Task2 called--\n");
    }
}

修改main函数:

int main(void)
{
    /* Init System, IP clock and multi-function I/O */
    SYS_Init();
    /* Init UART0 for printf */
    UART0_Init();

    /* Init UART1 for test */
    UART1_Init();

    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    printf("\n\nCPU @ %dHz\n", SystemCoreClock);

    printf("+---------------------+\n");
    printf("| UART function test  |\n");
    printf("+---------------------+\n");

    vStartThreadTasks();

    vTaskStartScheduler();

    while(1);
}

整体的main.c文件:

#include <stdio.h>
#include "Nano100Series.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

#include "uart.h"

#define RXBUFSIZE 1024

/*---------------------------------------------------------------------------------------------------------*/
/* Global variables                                                                                        */
/*---------------------------------------------------------------------------------------------------------*/
uint8_t g_u8SendData[12] = {0};
uint8_t g_u8RecData[RXBUFSIZE]  = {0};

volatile uint32_t g_u32comRbytes = 0;
volatile uint32_t g_u32comRhead  = 0;
volatile uint32_t g_u32comRtail  = 0;
volatile int32_t g_bWait         = TRUE;
volatile int32_t g_i32pointer = 0;

/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype                                                                              */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void);
void UART1_TEST_HANDLE(void);
void UART_FunctionTest(void);

void vApplicationTickHook(void)
{
    /* This function will be called by each tick interrupt if
    configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h.  User code can be
    added here, but the tick hook is called from an interrupt context, so
    code must not attempt to block, and only the interrupt safe FreeRTOS API
    functions can be used (those that end in FromISR()).  */

}

void vApplicationIdleHook(void)
{
    /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
    to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
    task.  It is essential that code added to this hook function never attempts
    to block in any way (for example, call xQueueReceive() with a block time
    specified, or call vTaskDelay()).  If the application makes use of the
    vTaskDelete() API function (as this demo application does) then it is also
    important that vApplicationIdleHook() is permitted to return to its calling
    function, because it is the responsibility of the idle task to clean up
    memory allocated by the kernel to any task that has since been deleted. */
}

void vApplicationMallocFailedHook(void)
{
    /* vApplicationMallocFailedHook() will only be called if
    configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
    function that will get called if a call to pvPortMalloc() fails.
    pvPortMalloc() is called internally by the kernel whenever a task, queue,
    timer or semaphore is created.  It is also called by various parts of the
    demo application.  If heap_1.c or heap_2.c are used, then the size of the
    heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
    FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
    to query the size of free heap space that remains (although it does not
    provide information on how the remaining heap might be fragmented). */
    taskDISABLE_INTERRUPTS();
    for(;;);
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Enable External XTAL (4~24 MHz) */
    CLK->PWRCTL |= (0x1 << CLK_PWRCTL_HXT_EN_Pos); // HXT Enabled

    /* Waiting for 12MHz clock ready */
    CLK_WaitClockReady( CLK_CLKSTATUS_HXT_STB_Msk);

    /* Switch HCLK clock source to XTAL */
    CLK->CLKSEL0 &= ~CLK_CLKSEL0_HCLK_S_Msk;
    CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HXT;

    /* Enable IP clock */
    CLK->APBCLK |= CLK_APBCLK_UART0_EN; // UART0 Clock Enable
    CLK->APBCLK |= CLK_APBCLK_UART1_EN; // UART1 Clock Enable

    /* Select IP clock source */
    CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
    CLK->CLKSEL1 |= (0x0 << CLK_CLKSEL1_UART_S_Pos);// Clock source from external 12 MHz or 32 KHz crystal clock

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
    SystemCoreClockUpdate();

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set PB multi-function pins for UART0 RXD and TXD  */
    SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB0_MFP_Msk | SYS_PB_L_MFP_PB1_MFP_Msk);
    SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB0_MFP_UART0_RX | SYS_PB_L_MFP_PB1_MFP_UART0_TX);

    /* Set PB multi-function pins for UART1 RXD, TXD, RTS, CTS  */
    SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB4_MFP_Msk | SYS_PB_L_MFP_PB5_MFP_Msk |
                       SYS_PB_L_MFP_PB6_MFP_Msk | SYS_PB_L_MFP_PB7_MFP_Msk);
    SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB4_MFP_UART1_RX | SYS_PB_L_MFP_PB5_MFP_UART1_TX |
                      SYS_PB_L_MFP_PB6_MFP_UART1_RTS  | SYS_PB_L_MFP_PB7_MFP_UART1_CTS);

    /* Lock protected registers */
    SYS_LockReg();

}

void UART0_Init()
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    UART_Open(UART0, 115200);
}






#define THREAD_TEST_STACK_SIZE  configMINIMAL_STACK_SIZE    
#define THREAD_TEST_PRIORITY    ( tskIDLE_PRIORITY + 1 )

void Thread_Task1( void *pvParameters );
void Thread_Task2( void *pvParameters );

void vStartThreadTasks( void )
{
    xTaskCreate( Thread_Task1, (const  char * ) "Th_Task1", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
    xTaskCreate( Thread_Task2, (const  char * ) "Th_Task2", THREAD_TEST_STACK_SIZE, NULL, THREAD_TEST_PRIORITY, ( xTaskHandle * ) NULL );
}

void Thread_Task1( void *pvParameters )
{
    portTickType xLastTime1;

    /* Get current system TickCount. */
    xLastTime1 = xTaskGetTickCount();

    for( ;; )
    {
        /* Run a time every 400 milliseconds. */
        vTaskDelayUntil( &xLastTime1, 400 );

        printf("Task1 called-\n");
    }   
}

void Thread_Task2( void *pvParameters )
{
    portTickType xLastTime2;

    /* Get current system TickCount. */
    xLastTime2 = xTaskGetTickCount();   

    for( ;; )
    {
        /* Run a time every 800 milliseconds. */
        vTaskDelayUntil( &xLastTime2, 800 );
        printf("Task2 called--\n");
    }
}



int main(void)
{
    /* Init System, IP clock and multi-function I/O */
    SYS_Init();
    /* Init UART0 for printf */
    UART0_Init();


    /*---------------------------------------------------------------------------------------------------------*/
    /* SAMPLE CODE                                                                                             */
    /*---------------------------------------------------------------------------------------------------------*/

    printf("\n\nCPU @ %dHz\n", SystemCoreClock);

    printf("+---------------------+\n");
    printf("| UART function test  |\n");
    printf("+---------------------+\n");

        vStartThreadTasks();

        vTaskStartScheduler();

    while(1);
}

运行log为:

CPU @ 12000000Hz

+---------------------+

| UART function test  |

+---------------------+


Task1 called-


Task2 called--

Task1 called-


Task1 called-


Task2 called--

Task1 called-

10 nuc140的移植freertos,并且LED闪烁

和上面的类似:
使用的是 NUC100_120BSP_v3.00.002.zip

FreeRTOSV8.2.3.zip
在如下工程的基础上修改,
E:\Nu_LB_Nuc140\NUC100_120BSP_v3.00.002_freertos\NUC100_120BSPv3.00.002\SampleCode\Template

修改后的工程为:
这里写图片描述

这里写图片描述

资源下载地址:
https://download.youkuaiyun.com/download/wowocpp/10622226

对应的板子为Nu_LB_Nuc140
对应的LED为:
这里写图片描述

对应的UART为:
这里写图片描述

12 需要删除掉的东西

FreeRTOSV8.2.3\FreeRTOS\Demo\ 中的 其他平台的东西
保留 Common 目录

这个大小就变得小了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值