• 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;
    }
    
  • 相关阅读:
    Javascript优化
    网页设计单页和多页的选择
    让404页面变得更加实用
    优秀的主页设计
    CSS常见布局解决方案
    前端极限性能优化
    记一次项目实训心得经验
    部署windows2008虚拟机
    httprunner学习总结
    意见汇总
  • 原文地址:https://www.cnblogs.com/schips/p/rtos-freertos-posix-simulator-for-freertos.html
Copyright © 2020-2023  润新知