---
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.1\FreeRTOS\Source下的文件拷贝到kernel

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

5、将Posix_GCC_Simulator\FreeRTOS_Posix\FreeRTOS_Kernel\下的portable拷贝到kernel

6、将Posix_GCC_Simulator\FreeRTOS_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\r\n", 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\r\n", 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;
}

Freertos学习:在Posix环境仿真FreeRTOS的更多相关文章

  1. 【零基础学习FreeRTOS嵌入式系统】之一:FreeRTOS环境搭建

    [零基础学习FreeRTOS嵌入式系统]之一:FreeRTOS环境搭建 一:FreeRTOS系统下载 在官网上https://www.freertos.org/,找到下载入口. 或直接进入下载地址ht ...

  2. FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅

    1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 准备F ...

  3. 【FreeRTOS学习02】源码结构/数据类型/命名规则总结

    个人不是很喜欢FreeRTOS的编程风格,但是没办法,白嫖人家的东西,只能忍了,这里先简单总结一下: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 ...

  4. 【FreeRTOS学习01】CubeIDE快速整合FreeRTOS创建第一个任务

    整个专栏主要是博主结合自身对FreeRTOS的实战学习以及源码分析,基于STM32F767 Nucleo-144平台,在CubeIDE下进行开发,结合官方的HAL库,将硬件环节的问题减少到最小,将精力 ...

  5. 020 - FreeRTOS学习路线总结

    零.为什么写? 在H7-tools预售群里,有位朋友提出如何学习FreeRTOS这类的问题,便由此总结下自己的学习路线.最近又打算接触RTT,和FreeRTOS做个对比. 文章分两步来讲,学习路线和学 ...

  6. 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁

    ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...

  7. (45)FreeRTOS学习之二

    一:架构概述 FreeRTOS是一个相对较小的应用程序.最小化的FreeRTOS内核仅包括3个(.c)文件和少数头文件,总共不到9000行代码,还包括了注释和空行.一个典型的编译后(二进制)代码映像小 ...

  8. reactjs学习一(环境搭配react+es6+webpack热部署)

    reactjs学习一(环境搭配react+es6+webpack热部署) 本文的源码在这里下载 https://github.com/tianxiangbing/webpack-study   或者使 ...

  9. 一、Android学习第一天——环境搭建(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 一. Android学习第一天——环境搭建 Android 开发环境的搭建 ...

  10. Java学习-032-JavaWeb_001 -- Tomcat环境部署及基本配置

    首先到 Tomcat 官网,下载对应的版本,我本机的系统是 WIN7 64BIT 的,因而我选择的是64bit 的zip包,如下图所示:

随机推荐

  1. vue-cli快速搭建项目的几个文件(三)

    ==========有加载动画的app.vue=========== <template>   <div id="app">     <keep-al ...

  2. 路由跳转报错:Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated",...

    记录一个路由跳转的报错: 将换成

  3. Competition Set - AtCoder II

    这里记录的是这个账号的比赛情况. ABC310 2023-7-15 Solved:6/8 1973->2053 七场ABC,两场打得蛮烂的,都因为AT炸掉Unrated了:另外五场全部满Perf ...

  4. 手把手教你整Win10的Linux子系统(Ubuntu)

    手把手教你整Win10的Linux子系统(Ubuntu) https://www.bilibili.com/read/cv7770224/ 设置root用户的密码 可以通过 sudo passwd r ...

  5. GESP 202312 游记

    day 0 把一本通上的指针扫了一遍,睡觉! day 1 9:00入场,在第二个考场. 冲进昌平二中,码了Hello,World!. 9:30发网址,开题 监考老师居然说阅读程序题可以打代码!···· ...

  6. 密码学—重合指数法Python程序

    重合指数(Ic) 计算重合指数就是用来验证在Kasiski测试法中猜测出来的各种密钥长度哪一个才是最接近真实密钥长度的. 计算重合指数步骤 按照Kasiski测试法猜测的密钥长度分组 ↓ 分好组之后将 ...

  7. VRRP 虚拟路由器冗余协议

    目录 文章目录 目录 为什么要使用 VRRP 技术? VRRP VRRP 的概念 VRRP 的工作原理 VRRP 的状态机 VRRP 的工作过程 VRRP 的选举机制 VRRP 的报文格式 VRRP ...

  8. 将自己喜欢的网页保存为单个文件包括图片(mhtml文件)

    from selenium import webdriver driver = webdriver.Chrome(r'C:\chromedriver_win32\chromedriver.exe') ...

  9. es命令大全,elasticsearch命令详解

    参考链接 Relational DB Elasticsearch 数据库(database) 索引(indices) 表(tables) types 行(rows) documents 字段(colu ...

  10. 高分辨率食道测压(HRM)

    高分辨率测压(High resolution Manometry) HRM的优势 高分辨率食管测压不但实现了从咽部到胃部的全程功能监测,而且插管无需牵拉,操作十分方便.更为重要的是,临床医生经过简单的 ...