Freertos学习:在Posix环境仿真FreeRTOS
title: rtos-freertos-在Posix环境仿真FreeRTOS
date: 2020-06-11 16:22:34
categories:
tags:
- freertos
- posix
- linux
- config
---
章节概述:
介绍如何在POSIX(Linux)环境完成FreeRTOS仿真。
下载源码
参考文档:《Posix/Linux Simulator for FreeRTOS》、《在Linux下实现FreeRTOS的简单模拟器》
1、进入官网上的例程,点击FreeRTOS contributed port下载,解压。
解压以后,现在我们有下面的2个目录:
FreeRTOSv10.3.1
Posix_GCC_Simulator
3、新建2个目录:kernel、user;分别用来放置FreeRTOS的内核、与用户这块的程序。
4、将FreeRTOSv10.3.1\FreeRTOS\Source下的文件拷贝到kernel:
.h:拷贝所有.c:拷贝croutine.c、list.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的更多相关文章
- 【零基础学习FreeRTOS嵌入式系统】之一:FreeRTOS环境搭建
[零基础学习FreeRTOS嵌入式系统]之一:FreeRTOS环境搭建 一:FreeRTOS系统下载 在官网上https://www.freertos.org/,找到下载入口. 或直接进入下载地址ht ...
- FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅
1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 准备F ...
- 【FreeRTOS学习02】源码结构/数据类型/命名规则总结
个人不是很喜欢FreeRTOS的编程风格,但是没办法,白嫖人家的东西,只能忍了,这里先简单总结一下: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 ...
- 【FreeRTOS学习01】CubeIDE快速整合FreeRTOS创建第一个任务
整个专栏主要是博主结合自身对FreeRTOS的实战学习以及源码分析,基于STM32F767 Nucleo-144平台,在CubeIDE下进行开发,结合官方的HAL库,将硬件环节的问题减少到最小,将精力 ...
- 020 - FreeRTOS学习路线总结
零.为什么写? 在H7-tools预售群里,有位朋友提出如何学习FreeRTOS这类的问题,便由此总结下自己的学习路线.最近又打算接触RTT,和FreeRTOS做个对比. 文章分两步来讲,学习路线和学 ...
- 【FreeRTOS学习05】深度解剖FreeRTOSConfig.h实现对系统的自定义剪裁
ROM/RAM太小,因此要对系统进行剪裁: 相关文章 [FreeRTOS实战汇总]小白博主的RTOS学习实战快速进阶之路(持续更新) 文章目录 相关文章 1 系统的剪裁 2 FreeRTOSConfi ...
- (45)FreeRTOS学习之二
一:架构概述 FreeRTOS是一个相对较小的应用程序.最小化的FreeRTOS内核仅包括3个(.c)文件和少数头文件,总共不到9000行代码,还包括了注释和空行.一个典型的编译后(二进制)代码映像小 ...
- reactjs学习一(环境搭配react+es6+webpack热部署)
reactjs学习一(环境搭配react+es6+webpack热部署) 本文的源码在这里下载 https://github.com/tianxiangbing/webpack-study 或者使 ...
- 一、Android学习第一天——环境搭建(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 一. Android学习第一天——环境搭建 Android 开发环境的搭建 ...
- Java学习-032-JavaWeb_001 -- Tomcat环境部署及基本配置
首先到 Tomcat 官网,下载对应的版本,我本机的系统是 WIN7 64BIT 的,因而我选择的是64bit 的zip包,如下图所示:
随机推荐
- C++ 异常处理机制详解:轻松掌握异常处理技巧
C++ 异常处理 C++ 异常处理机制允许程序在运行时处理错误或意外情况.它提供了捕获和处理错误的一种结构化方式,使程序更加健壮和可靠. 异常处理的基本概念: 异常: 程序在运行时发生的错误或意外情况 ...
- 【爬虫数据集】李子柒YouTube频道TOP10热门视频的TOP2000热门评论,共计2W条
目录 一.背景 二.爬取目标 三.结果展示 四.演示视频 五.附完整数据 一.背景 这段时间,有超多小伙伴找我要YouTube数据,做数据分析.情感分析之类的研究工作,但很多人并不是计算机软件相关专业 ...
- Oracle数据库下的DDL、DML、DQL、TCL、DCL
首发微信公众号:SQL数据库运维 原文链接:https://mp.weixin.qq.com/s?__biz=MzI1NTQyNzg3MQ==&mid=2247485212&idx=1 ...
- vue3语法糖script setup
在vue3种setup的写法,可以单独写setup()也可以写到script标签中,当然我们推荐后面这种 他的好处有很多,代码也简洁很多. 1.属性和方法无需return,可直接使用 /*原先*/ & ...
- lca总结+树上差分
lca lca简称最近公共祖先--简介在此,不过多赘述 这里主要写的是倍增算法,oi-wiki上用的是vector,由于本人不会,只会用链表,所以这里就放链表的代码了 例题 加一个数组按倍增数组的方式 ...
- IPv6 — 地址格式与寻址模式
目录 文章目录 目录 前文列表 IPv6 的地址格式 站点前缀 地址生成方式 IPv6 地址的分类以及寻址模式 单播(Unicast)地址 Interface ID 全球唯一地址(Global Uni ...
- 5GC 关键技术之 CUPS(控制与用户面分离)
目录 文章目录 目录 前文列表 CUPS(控制与用户面分离) 前文列表 <简述移动通信网络的演进之路> <5G 第五代移动通信网络> <5GC 关键技术之 SBA(基于服 ...
- kubernets之横向伸缩pod与集群节点
一 pod的自动伸缩容的应用背景 在面对负载并发过高的时候,我们或许希望能够提高RS,RC以及Deployment等的replicas的参数来增加pod的cpu,mem等,或者是通过提高每个容器的r ...
- dpkg和rpm对比及常用命令
dpkg(Debian Package)和rpm(RPM Package Manager)是两种不同的Linux包管理工具,它们各自在特定的Linux发行版中占据核心地位.两者之间对比如下: 所属发行 ...
- 鸿蒙极速入门(五)-路由管理(Router)
页面路由指在应用程序中实现不同页面之间的跳转和数据传递.HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面. 一.基础使用 Router模块提 ...