---
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. VGA显示文字

    VGA显示文字 VGA字符显示的原理 把要显示的字符转换成字符点阵,然后编码存储,着色的部分为1,其它为0.然后在VGA上输出显示. 字符点阵生成软件: https://www.zhetao.com/ ...

  2. Node.js 万字教程

    0. 基础概念 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,使用了一个事件驱动.非阻塞式 I/O 模型,让 JavaScript 运行在服务端的开发平台. ...

  3. Competition Set - AtCoder I

    这里记录的是这个账号的比赛情况. ARC172 2024-2-18 Solved:4/6 D(Hard-,2936) 给定所有数对 \((i,j),1\le i\lt j\le n\) 的一个排列 \ ...

  4. go 操作 Excel

    文档地址: https://xuri.me/excelize/zh-hans/ package main import ( "fmt" "github.com/xuri/ ...

  5. 09. rails 创建user用户列表

    gem添加分页的依赖 #列表分页 gem 'will_paginate', '~> 3.0.pre2' bundle 安装依赖 用户列表控制器 before_filter :auth_user, ...

  6. Swift中的变量与常量

    在Swift里面,声明变量用关健字var,声明常量用关健字let.虽然仅仅是声明变量这样的简单功能,但是还是有需要注意的地方. 变量和常量使用之前必须有一次赋值 var a: Int let b: I ...

  7. 网络安全—模拟ARP欺骗

    文章目录 网络拓扑 安装 使用 编辑数据包 客户机 攻击机 验证 仅做实验用途,禁止做违法犯罪的事情,后果自负.当然现在的计算机多无法被欺骗了,开了防火墙ARP欺骗根本无效. 网络拓扑 均使用Wind ...

  8. Spring源码阅读 ------------------- SpringFrameWork 5.2 术语理解(三)

    一.一定要理解的概念 1.控制反转 对象A和对象B,对象A中需要new 一个对象B,但是,现在需要对象A,不在自己内部new 对象B,把new 对象B的权限交给第三方(IOC框架),操作的过程,就是控 ...

  9. pageoffice 6版本隐藏office工具栏和自定义按钮,并修改标题栏内容

    在实际项目集成调用PageOffice的过程中: (1)有时需要把Office的工具栏隐藏,比如只读模式打开文件的时候,Office工具栏上的按钮几乎都是灰掉的,此时显示Office工具栏没有任何意义 ...

  10. 前后端分离项目集成PageOffice——实现在线编辑Word文件的版本控制

    PageOffice本身提供了SaveFilePage的js方法,但是由于该方法不支持代理且不能跨域导致在前后端分离项目中无法使用 功能:实现三个按钮分别保存不同版本的文件 1.PageOffice可 ...