Skip to content

husthl/qos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

qos

A simply portable Non-preemptive embedded operating system.

what is qos? qos是一个简单、可移植性强的非抢先式嵌入式操作系统。可以看做操作系统隔离层。 用最小资源,产生一个小型的操作系统隔离层。为不同的嵌入式操作系统,提供了一个统一的接口, 在其上开发的代码,无需修改,可以移植到另外一个嵌入式系统中。 qos在如下方面,提供支持:任务机制,调试,内存管理,单元测试,算法、图形界面。 其最基本原则为:简单。因为所有嵌入式系统,都提供了自己的任务模型、内存管理模型, qos必须使用这些模型的共性,用最简单的原理,使其得到统一,否则,无法提供一致性,达到可移植性的目标。 qos用原生操作系统(例如linux、uC/OS)的一个进程(线程/任务),实现了非抢先式多任务机制。 如果你想避开处理多任务特性,又想使用多任务的一些特性,可以使用qos。

qos提供如下特性:

1 定时器、空闲两种任务机制。 2 单元测试。 3 防御式编程。 4 内存未释放(内存泄露)。 5 内存越界写检查。 6 非定长数组。 7 链表。 8 虚拟文件。

下面,详述qos提供的各种特性。

任务机制: 1 非抢先的任务机制。 2 任务分为两种:定时任务、空闲任务。 定时任务在每个tick都必然会被调用。空闲任务则根据cpu空闲状态,按照平等机会,依次调用。 用如下3个tick周期,来说明任务调度情况: | tick1 | tick2 | tick3 | | t1 t2 t3 i1 i2 | t1 t2 t3 i3 | t1 t2 t3 i1 i2 i3 i1 | tick,qos的一个周期,可以设置其频率。 t1,t2,t3,为定时任务task。 i1,i2,i3,为空闲任务idle。 每个周期,定时任务在空闲任务之前被调用。 可以看到,t1,t2,t3在每个tick都会被调用。 而i1,i2,i3则不一定了,下面说明空闲任务如何被调用的。 在tick1,i1,i2被调用后,下一个tick已经快到了,因此,i3没有运行。 在tick2,轮到i3被调用了,但i3运行的时间很长,运行完后,下一个tick快到了,因此,没有运行i1,i2。 在tick3,i1,i2,i3都被调用了。且因为有赋予的时间,i1运行了两遍。 3 任务个数没有限制。 4 在使用cpu资源超过限制时,提供警告。警示程序员调整系统设置,或者优化程序。 qos任务,当cpu资源使用超过限制时,应该告知开发者知晓,开发者改变系统设置、调整程序编写方式、 改变业务流程、或者提升硬件性能。 5 非常容易移植。移植接口,只要实现几个函数即可,无需汇编。

调试支持: 1 支持防御式编程。uverify(),return_false_if(),return_0_if(), 能够在函数出错的第一地点,打印出出错的表达式内容、文件名、源代码行数。 甚至,能够继续打印函数调用层次。 例如: uverify FAIL: 53@file1.c !f1() uverify FAIL:123@file2.c !f2() 可以看出,f1()出错,f1()被f2()调用。f1()在file1.c中第53行;f2()在file2.c中第123行。 2 必要时,用uverify()检验数据是否符合期望。例如,假设有如下函数: void f( void* p ){ if( NULL == p ){ return; } do something... } 上面函数的问题在于: (1) 没有在错误的第一地点,显示错误。如果传入p为NULL,只是简单返回,这会使调用f()的函数行为出错, 使错误发生的地点上移,而不是在f()函数内提供告警。 (2) 浪费cpu资源和空间资源。if( NULL == p )这一句,无论在调试时,还是正式发布运行时,都会执行, 而且占用代码空间。如果我们的代码,经过严格测试,正式运行时,这一句话,正常情况下,是没有机会执行的, 也无需这一句话的。因此,正式运行时,如果将这一句话去掉,不但可以节省cpu资源,也可以节省代码空间。 改动为如下即可: void f( void* p ){ uverify( NULL != p ); do something... } uverify()在调试状态下检查p是否为NULL,如果p为NULL,显示类似下面的内容: uverify FAIL: 行号@文件名 NULL != p 开发者到该文件名,找到该行号,查找原因,修改代码。 正式发布状态,uverify()无效,这一句话是没有的。 3 当要发布正式版本时,一个宏定义开关GCFG_DEBUG_EN,可以关闭所有调试状态代码。 4 每个文件一个编号。使错误记录所需空间最省。

单元测试: 1 单元测试已经作为qos的一部分。 2 单元测试分为两种:函数式单元测试、任务式单元测试。 普通的测试,通过函数式单元测试完成,例如:测试 1 + 2是否等于3。 任务式单元测试,是为了进行一些和时间有关的单元测试。例如:串口接收超时测试。

内存管理: 1 内存边界检查。 2 内存分配、释放记录。 3 内存自动回收机制。 为了加快运行,当调用qfree()时,并没有立即释放内存,而是做一个内存释放标记。 在系统空闲状态,才释放全部内存。 4 一个宏定义,可以关闭以上特性,使用标准的malloc()和free()。

算法: 1 链表。 2 可以自动扩展的数组。 3 两叉树。 4 先进先出FIFO。 5 环状队列。

文件: 1 虚拟文件vfs。开发者可以扩展添加自己的文件接口。

qos没有什么? 1 没有多任务。 2 没有信号量。 3 没有同步。 qos基于非常简单的原理,因此,容易理解。而且代码执行速度快,效率高,稳定可靠。

test test1: a heavy idle & timer test2: task notify test3: unit test in task test4: virtual file system. test5: serial test6: serial shell, xmodem protocol

no more---------------------------------

About

A simply portable Non-preemptive embedded operating system.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published