freertos vxworks系统的优点和缺点

freertos vxworks系统的优点和缺点,第1张

1、FreeRTOS是一个迷你的实时 *** 作系统内核。最大的特点是“小”,占用资源小,支持8位、16位、32位MCU平台。FreeRTOS提供了 *** 作系统基本的功能和组件,包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等。此外FreeRTOS还有一个最大的优势就是就是免费。不足之处,一方面体现在系统的服务功能上,如FreeRTOS只提供了消息队列和信号量的实现,无法以后进先出的顺序向消息队列发送消息;另一方面,FreeRTOS只是一个 *** 作系统内核,需外扩第三方的GUI(图形用户界面)、TCP/IP协议栈、FS(文件系统)等才能实现一个较复杂的系统,不像μC/OS-II可以和μC/GUI、μC/FS、μC/TCP-IP等无缝结合。

2、雹轿梁VxWorks不帆猛仅是一种嵌入式实时 *** 作系统,源运又是可以运行的最小基本程序。其内部有BSP(BoardSupportPackage,板级支持包),便于进行驱动程序的编写。此外,VxWorks具有强实时性、微内核设计、可裁剪性、可移植性和可靠性等特点,能较好地满足嵌入式开发的需求。缺点就是昂贵的价格让开发者望而却步。

FreeRTOS 的移植主要需要改写如下三个文件。

1.        portmacro.h

2.        port.c

3.  物哪      port.asm

如果采用的C编译器允许在C 代码中插入汇编,并且支持用C语言写中断处理函数。则port.asm 文件的内容是可以合并到port.c 中的。

下面以将 FreeRTOS 移植到FreeScale 68HCS12 内核的单片机为例,开发环境采用:CodeWarriorDevelopment Studio V5.9.0

之所以采用FreeScale 68HCS12 作为示例 CPU,是因为我以前写过一篇将uC/OS-II移植到FreeScale 68HCS12 核单片机的笔记。采用同样的CPU,同样的开发环境,可以方便我们比较两种不同实时 *** 作系统的移植代码的异同。另外,FreeScale 68HCS12 相对ARM、MIPS 等构架要简单的多。移植代码量相对来说也要小一些,因此也更容易入门。

portmacro.h

portmacro.h 主要包括两部分内容,第一部分定义了一系列内核代码中用到的数据类型。FreeRTOS 与 uC/OS-II 一样,并不直接使用char、int 等这些原生类型,而是将其重新定义为一系列以port开头的新类型。在uC/OS-II的移植代码中,通常采用 typedef 来定义新的类型,而FreeRTOS的作者似乎更喜欢用宏定义。下面是相应的代码片段。

portTickType 既可以定义为16位的无符号整数,也可以定义为32位的无符号整数。具体用那种定义,要看 FreeRTOSConfig.h 文件中如何设置configUSE_16_BIT_TICKS。

然后是一些硬件相关的定义。包括数据对其方式,堆栈增长方向,Tick Rate,还有任务切换的宏。

portBYTE_ALIGNMENT 在uC/OS-II 是不需要的,FreeRTOS的代码中在分配任务堆栈空间时用到这个宏定义。

portSTACK_GROWTH 定义为1 表示堆栈是正向生长的,-1为逆向生长的。一般来说堆栈都是倒生的,68HCS12 也不例外,因此这里定义为 (-1)。

多说一句在 uC/OS-II 中,对应的宏是OS_STK_GROWTH, 1 表示逆向生长,0表示正向生长。

portTICK_RATE_MS 只在应用代码中可能会用到,表示的是Tick 间间隔多少 ms。

portYIELD() 实现的是任务切换,相当于 uC/OS-II中的 OS_TASK_SW()。

portNOP() 顾名思义就是对空 *** 作定义了个宏。具体在FreeRTOS 代码中哪里用到了这个宏没注意过,但是想必是有地方用到了。

然罩谨码后是有关临界区的处理代码:

这部分的代码挺长的,不过其实是对 Small Memery Model 和Banked Memery Model 分别提供了如下两个宏定义:

portRESTORE_CONTEXT()

portSAVE_CONTEXT()

使用哪一套宏定义是通过BANKED_MODEL 这个宏是否被定义来确定的。其实,CodeWarrior Development Studio V5.9.0 中提供的官方代码中给出了一种更正规的判断方法:

FreeRTOS中保存和恢复任务上下文环境的代码与uC/OS-II中的大同小异,唯一有点区别的晌皮就是要保存uxCriticalNesting 的值。原因上面已经介绍过了。

之所以要搞这两个宏,是为了利用某些C编译器的扩展功能对任务函数进行更好的优化。CodeWarrior 并不提供相关的功能,所以在这里任务就是普通的函数。

*                1. 学习FreeRTOS的任务栈溢出检测方法一(模拟栈溢出)。

*                2. FreeRTOS的任务栈溢出检测方法一说明:

*                  a. FreeRTOSConfig.h文件中配置宏定义:

*                      #define  configCHECK_FOR_STACK_OVERFLOW  1

*                  b. 在任务切换时检测任务栈指针是否过界了,如果过界了,在任务切换的时候会触发栈溢出钩子函数。

*                      void vApplicationStackOverflowHook( TaskHandle_t xTask,

*                                                          signed char *pcTaskName )

*                      用户可以在钩子函数里面做一些处理。本实验是在钩子函数中打印出现栈溢出的任务。

*                  c. 这种方法不能保证所有的栈溢出都能检测到。比如任务在执行的过程中发送过栈溢出。任务切换前

*                      栈指针又恢复到了正常水平,这种情况在任务切换的时候是检测不到的。又比如任务栈溢出后,把

*                      这部分栈区的数据修改了,这部分栈区的数据不重要或者暂时没有用到还好,如果是重要数据被修

*                      改将直接导致系统进入硬件异常。这种情况下,栈溢出检测功能也是检测不到的。

*                  d. 本实验就是简单的在任务vTaskUserIF中申请过大的栈空间,模拟出一种栈溢出的情况,溢出后触

*                      发钩子函数,因为我们将溢出部分的数据修改了,进而造成进入硬件异常。

 #define  configCHECK_FOR_STACK_OVERFLOW  1

/*

*********************************************************************************************************

* 函 数 名: StackOverflowTest

* 功能说明: 任务栈溢出测试

* 形    参: 无

* 返 回 值: 无

*********************************************************************************************************

*/

static void StackOverflowTest(void)

{

int16_t i

uint8_t buf[2048]

(void)buf/* 防止警告 */

/*

  1. 为了能够模拟任务栈溢出,并触发任务栈溢出函数,这里强烈建议使用数组的时候逆着赋值。

    因为对于M3和M4内核的MCU,堆栈生长方向是向下生长的满栈。即高地址是buf[2047], 低地址

    是buf[0]。如果任务栈溢出了,也是从高地址buf[2047]到buf[0]的某个地址开始溢出。

        因此,如果用户直接修改的是buf[0]开始的数据且这些溢出部分的数据比较重要,会直接导致

    进入到硬件异常。

  2. 栈溢出检测是在任务切换的时候执行的,我们这里加个延迟函数,防止修改了重要的数据导致直接

    进入硬件异常。

  3. 任务vTaskTaskUserIF的栈空间大小是2048字节,在此任务的入口已经申请了栈空间大小

------uint8_t ucKeyCode

    ------uint8_t pcWriteBuffer[500]

    这里再申请如下这么大的栈空间

    -------int16_t i

-------uint8_t buf[2048]

    必定溢出。

*/

for(i = 2047i >= 0i--)

{

buf[i] = 0x55

vTaskDelay(1)

}

}

/*

*********************************************************************************************************

* 函 数 名: vApplicationStackOverflowHook

* 功能说明: 栈溢出的钩子函数

* 形    参: xTask        任务句柄

*            pcTaskName  任务名

* 返 回 值: 无

*********************************************************************************************************

*/

void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )

{

printf("任务:%s 发现栈溢出\r\n", pcTaskName)

}

实验目的:

*                1. 学习FreeRTOS的任务栈溢出检测方法二(模拟栈溢出)。

*                2. FreeRTOS的任务栈溢出检测方法二说明:

*                  a. FreeRTOSConfig.h文件中配置宏定义:

*                      #define  configCHECK_FOR_STACK_OVERFLOW  2

*                  b. 在任务切换时检测任务栈指针是否过界了,如果过界了,在任务切换的时候会触发栈溢出钩子函数。

*                      void vApplicationStackOverflowHook( TaskHandle_t xTask,

*                                                          signed char *pcTaskName )

*                      用户可以在钩子函数里面做一些处理。本实验是在钩子函数中打印出现栈溢出的任务。

*                  c. 任务创建的时候将任务栈所有数据初始化为0xa5,任务切换时进行任务栈检测的时候检测末尾

*                      的16个字节是否都是0xa5,通过这种方式来检测任务栈是否溢出了。相比方法一,这种方法的速度

*                      稍慢些,但是这样就有效的避免了方法一里面的部分情况。不过依然不能保证所有的栈溢出都能检测

*                      到,比如任务栈末尾的16个字节没有用到,即没有被修改,但是任务栈已经溢出了,这种情况是检

*                      测不到的。另外任务栈溢出后,任务栈末尾的16个字节没有修改,但是溢出部分的栈区的数据修改

*                      了,这部分栈区的数据不重要或者暂时没有用到还好,如果是重要数据被修改将直接导致系统进入硬

*                      件异常。这种情况下,栈溢出检测功能也是检测不到的。

*                  d. 本实验就是简单的在任务vTaskUserIF中申请过大的栈空间,模拟出一种栈溢出的情况,溢出后触

*                      发钩子函数,因为我们将溢出部分的数据修改了,进而造成进入硬件异常。

#define  configCHECK_FOR_STACK_OVERFLOW  2

函数内容和上面一样:

static void StackOverflowTest(void)

void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12294972.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存