---
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. LVGL 字体

    一.LVGL 内置字体 LVGL有几种不同大小的内置字体,可以通过 LV_FONT_MONTSERRAT_X 定义在 lv_conf.h 中启用. 普通字体 包含所有ASCII字符,度数符号(U + ...

  2. 01二分 [AGC006D] Median Pyramid Hard + P2824 [HEOI2016/TJOI2016] 排序

    [AGC006D] Median Pyramid Hard 考虑对于一个长度为 2n + 1 的 01 序列 b 如何快速确定堆顶元素. _ _ _ _ x _ _ _ 0 x _ _ 0 0 x _ ...

  3. golang中三种定时器的实现方式及周期定时

    一.定时器的创建 golang中定时器有三种实现方式,分别是time.sleep.time.after.time.Timer 其中time.after和time.Timer需要对通道进行释放才能达到定 ...

  4. 经验分享:春招零Offer,5月份还有机会吗?

    先说答案:5 月份依然有拿到 Offer 的机会. 5月份春招结束了吗? 对于应届大学生来说(也就是今年暑假毕业的学生),5 月中旬春招就陆续结束了,但是 5 月份会有很多补录的机会. 对于非应届的大 ...

  5. saltstack web 平台开发

    运维平台参考: https://wrapbootstrap.com/

  6. Django 视图views的基本使用

    在 Django 中,视图函数是一个 Python 函数或者类,开发者主要通过编写视图函数来实现业务逻辑.视图函数首先接受来自浏览器或者客户端的请求,并最终返回响应,视图函数返回的响应可以是 HTML ...

  7. Android 12(S) MultiMedia Learning(七)NuPlayer GenericSource

    本节来看一下NuPlayer Source中的GenericSource,GenericSource主要是用来播放本地视频的,接下来着重来看以下5个方法: prepare,start,pause,se ...

  8. Flutter(三):Flutter App 可行性分析

    一.生态建设 第三方Package https://pub.dev/packages?sort=popularity 截止2021年4月,第三方库达到17000+ 二.Devops 代码风格检查 An ...

  9. 一个或多个C文件编译KO

    参考文档:.c文件如何编译为ko的MAKEFILE文件编写 - young525 - 博客园 (cnblogs.com) 文档组织结构 header目录:存放头文件 source目录:存放源文件 单个 ...

  10. 算法金 | 读者问了个关于深度学习卷积神经网络(CNN)核心概念的问题

    ​大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 读者问了个关于卷积神经网络核心概念的问题,如下, [问]神经元.权重.激活函数.参数 ...