zoukankan      html  css  js  c++  java
  • Freertos学习:在Posix环境仿真FreeRTOS

    --- title: rtos-freertos-在Posix环境仿真FreeRTOS date: 2020-06-11 16:22:34 categories: tags: - freertos - posix - linux - config ---

    章节概述:

    介绍如何在POSIX(Linux)环境完成FreeRTOS仿真。

    下载源码

    成果地址:https://gitee.com/schips/FreeRTOS-on-Linux.git

    参考文档:《Posix/Linux Simulator for FreeRTOS》、《在Linux下实现FreeRTOS的简单模拟器

    1、进入官网上的例程,点击FreeRTOS contributed port下载,解压。

    2、进入源码下载地址,下载自己喜欢的版本

    解压以后,现在我们有下面的2个目录:

    FreeRTOSv10.3.1 
    Posix_GCC_Simulator
    

    3、新建2个目录:kerneluser;分别用来放置FreeRTOS的内核、与用户这块的程序。

    4、将FreeRTOSv10.3.1FreeRTOSSource下的文件拷贝到kernel

    • .h:拷贝所有
    • .c:拷贝croutine.clist.c queue.c以及tasks.c

    5、将Posix_GCC_SimulatorFreeRTOS_PosixFreeRTOS_Kernel下的portable拷贝到kernel

    6、将Posix_GCC_SimulatorFreeRTOS_Posix下的FreeRTOSConfig.h拷贝到user

    7、在user目录下创建main.c,并在其中预留一个空的main函数。

    #include <stdio.h>
    
    int main(int ac, char *av[])
    {
        return 0;
    }
    

    编译脚本

    参考官方示例的makefile,在根目录下创建Makefile文件,同样在子目录下也包含两个subdir.mk用来编译需要的对应的.o

    Makefile

    位于顶级目录

    RM := rm -rf
    
    PROJ_ROOT  :=.
    USERDIR    :=user
    KERINELDIR :=kernel
    
    BUILD_TMP  :=$(PROJ_ROOT)/tmp
    TARGET_INC := -I$(PROJ_ROOT)/$(USERDIR) 
                  -I$(PROJ_ROOT)/$(KERINELDIR)/include 
                  -I$(PROJ_ROOT)/$(KERINELDIR)/portable/GCC/Posix 
    
    -include $(PROJ_ROOT)/$(USERDIR)/user.mk
    -include $(PROJ_ROOT)/$(KERINELDIR)/kernel.mk
    
    ifneq ($(MAKECMDGOALS),clean)
    ifneq ($(strip $(C_DEPS)),)
    -include $(C_DEPS)
    endif
    endif
    
    all:simulator_linux.bin
    
    simulator_linux.bin: $(OBJS)
        @echo 'Building target: $@'
        gcc -pthread -lrt -o"simulator_linux.bin" $(OBJS) $(LIBS)
        @echo 'Finished building target: $@'
        @echo ' '
    
    clean:
        -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) simulator_linux.bin
        -@echo ' '
    
    .PHONY: all clean dependents
    .SECONDARY:
    

    kernel.mk

    C_SRCS += 
    $(PROJ_ROOT)/$(KERINELDIR)/croutine.c 
    $(PROJ_ROOT)/$(KERINELDIR)/list.c 
    $(PROJ_ROOT)/$(KERINELDIR)/queue.c 
    $(PROJ_ROOT)/$(KERINELDIR)/tasks.c 
    $(PROJ_ROOT)/$(KERINELDIR)/portable/GCC/Posix/port.c 
    $(PROJ_ROOT)/$(KERINELDIR)/portable/MemMang/heap_3.c 
    
    OBJS += 
    $(BUILD_TMP)/croutine.o 
    $(BUILD_TMP)/list.o 
    $(BUILD_TMP)/queue.o 
    $(BUILD_TMP)/tasks.o 
    $(BUILD_TMP)/port.o 
    $(BUILD_TMP)/heap_3.o 
    
    C_DEPS += 
    $(BUILD_TMP)/croutine.d 
    $(BUILD_TMP)/list.d 
    $(BUILD_TMP)/queue.d 
    $(BUILD_TMP)/tasks.d 
    $(BUILD_TMP)/port.d 
    $(BUILD_TMP)/heap_3.d 
    
    $(BUILD_TMP)/%.o: $(PROJ_ROOT)/$(KERINELDIR)/%.c
    	@echo 'Building file: $<'
    	gcc -DUSE_STDIO=1 -D__GCC_POSIX__=1 $(TARGET_INC) -O2 -Wall -c -fmessage-length=0 -pthread -lrt -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
    	@echo 'Finished building: $<'
    	@echo ' '
    
    $(BUILD_TMP)/%.o: $(PROJ_ROOT)/$(KERINELDIR)/portable/GCC/Posix/%.c
    	@echo 'Building file: $<'
    	gcc -DUSE_STDIO=1 -D__GCC_POSIX__=1 $(TARGET_INC) -O2 -Wall -c -fmessage-length=0 -pthread -lrt -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
    	@echo 'Finished building: $<'
    	@echo ' '
    
    $(BUILD_TMP)/%.o: $(PROJ_ROOT)/$(KERINELDIR)/portable/MemMang/%.c
    	@echo 'Building file: $<'
    	gcc -DUSE_STDIO=1 -D__GCC_POSIX__=1 $(TARGET_INC) -O2 -Wall -c -fmessage-length=0 -pthread -lrt -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
    	@echo 'Finished building: $<'
    	@echo ' '
    

    user.mk

    C_SRCS += 
    $(PROJ_ROOT)/$(USERDIR)/main.c 
    
    OBJS += 
    $(BUILD_TMP)/main.o 
    
    C_DEPS += 
    $(BUILD_TMP)/main.d 
    
    # Each subdirectory must supply rules for building sources it contributes
    $(BUILD_TMP)/%.o: $(PROJ_ROOT)/$(USERDIR)/%.c
        @echo 'Building file: $<'
        gcc -DUSE_STDIO=1 -D__GCC_POSIX__=1 $(TARGET_INC) -O2 -Wall -c -fmessage-length=0 -pthread -lrt -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"
        @echo 'Finished building: $<'
    @echo ' '
    

    编译与改动

    portmacro.h

    由于v6.0与现在的版本差异较大,所以需要在 kernel/portable/GCC/Posix/portmacro.h进行适配。

    添加:

    #define portPOINTER_SIZE_TYPE unsigned long
    

    添加:

    /*--------------------------v10.3---------------------------------*/
    typedef portSTACK_TYPE StackType_t;
    typedef portBASE_TYPE BaseType_t;
    typedef unsigned long UBaseType_t;
    
    #define portTICK_PERIOD_MS                                ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
    #if( configUSE_16_BIT_TICKS == 1 )
            typedef unsigned portSHORT TickType_t;
            #define portMAX_DELAY ( TickType_t ) 0xffff
    #else
            typedef unsigned portLONG TickType_t;
            #define portMAX_DELAY ( TickType_t ) 0xffffffff
    #endif
    /*----------------------------------------------------------------*/
    

    屏蔽掉:

    /*
    #if( configUSE_16_BIT_TICKS == 1 )
    	typedef unsigned portSHORT portTickType;
    	#define portMAX_DELAY ( portTickType ) 0xffff
    #else
    	typedef unsigned portLONG portTickType;
    	#define portMAX_DELAY ( portTickType ) 0xffffffff
    #endif
    */
    

    屏蔽掉:

    //#define portTICK_RATE_MS				( ( portTickType ) 1000 / configTICK_RATE_HZ )
    

    main.c

    新的

    #include <stdio.h>
    #include <stdlib.h>
    
    #include "FreeRTOS.h"
    #include "task.h"
    #include "queue.h"
    
    static void vTask1( void *pvParameters );
    static void vTask2( void *pvParameters );
    
    int main()
    {
        static xQueueHandle xTestQueue;
        xTestQueue = xQueueCreate( 10, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) );
        xTaskCreate( vTask1, "vTask1", configMINIMAL_STACK_SIZE, ( void * ) &xTestQueue, tskIDLE_PRIORITY, NULL );
        xTaskCreate( vTask2, "vTask2", configMINIMAL_STACK_SIZE, ( void * ) &xTestQueue, tskIDLE_PRIORITY, NULL );
    
        vTaskStartScheduler();
        return 1;
    }
    
    static void vTask1( void *pvParameters )
    {
    unsigned short usValue = 0, usLoop;
    xQueueHandle *pxQueue;
    const unsigned short usNumToProduce = 3;
    short sError = pdFALSE;
    
        pxQueue = ( xQueueHandle * ) pvParameters;
    
        for( ;; )
        {       
            for( usLoop = 0; usLoop < usNumToProduce; ++usLoop )
            {
                /* Send an incrementing number on the queue without blocking. */
                printf("Task1 will send: %d
    ", usValue);
                if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( portTickType ) 0 ) != pdPASS )
                {
                    sError = pdTRUE;
                }
                else
                {
                    ++usValue;
                }
            }
            vTaskDelay( 2000 );
        }
    }
    static void vTask2( void *pvParameters )
    {
    unsigned short usData = 0;
    xQueueHandle *pxQueue;
    
        pxQueue = ( xQueueHandle * ) pvParameters;
    
        for( ;; )
        {       
            while( uxQueueMessagesWaiting( *pxQueue ) )
            {
                if( xQueueReceive( *pxQueue, &usData, ( portTickType ) 0 ) == pdPASS )
                {
                    printf("Task2 received:%d
    ", usData);
                }
            }
            vTaskDelay( 5000 );
        }
    }
    
    /********************************************************/
    /* This is a stub function for FreeRTOS_Kernel */
    void vMainQueueSendPassed( void )
    {
        return;
    }
    
    /* This is a stub function for FreeRTOS_Kernel */
    void vApplicationIdleHook( void )
    {
        return;
    }
    
  • 相关阅读:
    UVa 1151 Buy or Build【最小生成树】
    UVa 216 Getting in Line【枚举排列】
    UVa 729 The Hamming Distance Problem【枚举排列】
    HDU 5214 Movie【贪心】
    HDU 5223 GCD
    POJ 1144 Network【割顶】
    UVa 11025 The broken pedometer【枚举子集】
    HDU 2515 Yanghee 的算术【找规律】
    Java基本语法
    Java环境变量,jdk和jre的区别,面向对象语言编程
  • 原文地址:https://www.cnblogs.com/schips/p/rtos-freertos-posix-simulator-for-freertos.html
Copyright © 2011-2022 走看看