RT-OS 对比

OS名称

公司

文件大小 移植硬件要求 功能特点 应用场合

RTX51

Keil

个级KB(占用900字节) 针对8051系列处理器 Keil中公开了RTX51 Tiny版的源代码,RTX51可以简化那些复杂而且时间要求严格的工程的软件设计。 Tiny版免费,Full版收费,适用于8051系列处理器

FreeRTOS

十级KB 小RAM单片机(例AVR、PIC、C8051F都没问题) 基本满足较小系统需要的情况下降低系统成本、简化开发难度。系统的服务功能不及uCOS-II 免费,适用于51及以上单片机

embOS

Segger

十级KB 小RAM单片机 高度模块化的,只有需要的函数才被调用。 超快响应速度、灵活性、省电的、多进程 收费, 超快响应速度、灵活性、省电的、多进程要求的微控制器系统应用都是embOS的合适应用范围

salvo

十级KB 小RAM单片机 功能强大、内核简洁高效、占用资源少、可配置性强 免费,适用于51及以上单片机

TinyOS

UC Berkeley

十级KB 可以移植到CC2430 开源, TinyOS的应用程序都是基于事件驱动模式的,采用事件触发去唤醒传感器工作。 免费,专为嵌入式无线传感网络设计

uCOS-II

商业用途须通过Micrium获得商用许可

十级KB 可以移植到几乎所有知名的CPU 上(大多数8位及16位以上) 源代码,执行效率高、占用空间小、实时性能优良和可扩展性强等。仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。 收费,一般在裸机无法实现的低端嵌入式中多考虑此系统,实时性好、应用简单

RT-Thread

RT-Thread工作室

内核十级KB 内核和uCOS-II相似 起初只是一个和uCOS-II相似的内核,但现在正逐渐被工程师完善成一个带GUI,文件系统的操作系统 免费,从内核到完善的操作系统,应用面广泛

uClinux

Lineo

百级KB

(最简500

KB左右)

针对没有MMU的CPU,2M以上RAM 开源,针对目标处理器没有存储管理单元MMU的嵌入式系统而设计。其性能稳定、移植性好、功能强大。 免费,是实时性要求不高的低端平台的最佳选择

eCos

Redhat

百级KB

(最简100

KB左右)

16位以上单片机,百KB级RAM 大部分代码用C++编写。功能强大的配置系统,可以在源码级实现对系统的配置和裁减。具有实时性。 免费,97年完成,所以还比较新颖

Nucleus

ATI

百级KB ARM6/7,StrongARM等 NucleusPLUS是为实时嵌入式应用而设计的一个抢先式多任务操作系统内核 免费,实时嵌入式应用

OSE epsilon

百级KB 针对MCU 性能高、代码小和可确定性实时操作系统 有免费和收费两个版本。通信设备(接入网、核心网)以及终端设备

Rtems

OAR公司负责版本的升级与维护

M级,裁剪的最小内核为十级KB(60KB左右) 最好是32位以上,裁剪后可支持8位和16位 开源,早期的名称为实时导弹系统,支持多处理器体系结构(如ARM+DSP) 免费,在国内,RTEMS主要用在航空航天和军工领域

QNX

QNX

M级,QNX核心 (12Kb左右) QNX是一个微内核实时操作系统,其核心仅提供4种服务:进程调度、进程间通信、底层网络通信和中断处理,其进程在独立的地址空间运行。 收费,通用型

ThreadX

M级 32位控制器以上 成熟的商用强实时嵌入式操作系统 收费,适用于深嵌入式应用中

VxWorks

WindRiver

M级 嵌入式最强的OS。400多个小目标模块组成,由用户裁剪和配置系统;提供基于优先级的任务调度、任务间同步与通信、定时器以及内存管理等功能,内建符合POSIX规范的内存管理,能够以及多处理器控制程序 收费,通用型,大企业,军工

WinCE

微软

M级

FreeRTOS之系统配置

freeRTOS 配置在:FREERTOS_CONFIG.H 里面,条目如下:

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* Here is a good place to include header files that are required across your application. */
#include “something.h”

/* 是否配置成抢先先多任务内核,是1的时候,优先级高的任务优先执行。 为0任务就没有优先级之说,用时间片轮流执行 */
#define configUSE_PREEMPTION 1

/* IDLE任务的HOOK函数,用于OS功能扩展,需要你自己编相应函数, 名字是void vApplicationIdleHook( void ) */
#define configUSE_IDLE_HOOK 0

/* SYSTEM TICK的HOOK函数,用于OS功能扩展,需要你自己编相应函数, 名字是 void vApplicationTickHook(void ) */
#define configUSE_TICK_HOOK 0

/* 系统CPU频率,单位是Hz */
#define configCPU_CLOCK_HZ 58982400

/* 系统SYSTEM TICK每秒钟的发生次数, 数值越大系统反应越快,但是CPU用在任务切换的开销就越多 */
#define configTICK_RATE_HZ 250
/* 系统任务优先级数。5 说明任务有5级优先度。这个数目越大耗费RAM越多 */
#define configMAX_PRIORITIES 5

/* 系统最小堆栈尺寸,注意128不是128字节,而是128个入栈。比如ARM32位,128个入栈就是512字节 */
#define configMINIMAL_STACK_SIZE 128

/* 系统可用内存。一般设成除了操作系统和你的程序所用RAM外的最大RAM。 比如20KRAM你用了2K,系统用了3K,剩下15就是最大HEAP 尺寸。你可以先设小然后看编译结果往大里加*/
#define configTOTAL_HEAP_SIZE 10240

/* 任务的PC名字最大长度,因为函数名编译完了就不见了,所以追踪时不知道哪个名字。16表示16个char */
#define configMAX_TASK_NAME_LEN 16

/* 是否设定成追踪,由PC端TraceCon.exe记录,也可以转到系统显示屏上 */
#define configUSE_TRACE_FACILITY 0

/* 就是SYSTEM TICK的长度,16是16位,如果是16位以下CPU, 一般选1;如果是32位系统,一般选0 */
#define configUSE_16_BIT_TICKS 0

/* 简单理解以下就是和IDLE TASK同样优先级的任务执行情况。建议设成1,对系统影响不大 */
#define configIDLE_SHOULD_YIELD 1

/* 是否用MUTEXES。 MUTEXES是任务间通讯的一种方式,特别是用于任务共享资源的应用,比如打印机,任务A用的时候就排斥别的任务应用,用完了别的任务才可以应用 */
#define configUSE_MUTEXES 0

/* 确定是否用递归式的MUTEXES */
#define configUSE_RECURSIVE_MUTEXES 0

/* 是否用计数式的SEMAPHORES,SEMAPHORES也是任务间通讯的一种方式 */
#define configUSE_COUNTING_SEMAPHORES 0

/* 是否应用可切换式的API。freeRTOS 同一功能API有多个,有全功能但是需求资源和时间较多的,此项使能后就可以用较简单的API, 节省资源和时间,但是应用限制较多 */
#define configUSE_ALTERNATIVE_API 0

/* 此项用于DEBUG,来看是否有栈溢出,需要你自己编相应检查函数void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName ) */
#define configCHECK_FOR_STACK_OVERFLOW 0

/* 用于DEBUG,登记SEMAPHORESQ和QUEUE的最大个数,需要在任务用应用函数vQueueAddToRegistry()和 vQueueUnregisterQueue() */
#define configQUEUE_REGISTRY_SIZE 10

/* 设定可以改变任务优先度 */
#define INCLUDE_vTaskPrioritySet 1

/* 设定可以查询任务优先度 */
#define INCLUDE_uxTaskPriorityGet 1

/* 设定可以删除任务 */
#define INCLUDE_vTaskDelete 1

/* 据说是可以回收删除任务后的资源(RAM等)*/
#define INCLUDE_vTaskCleanUpResources 0

/* 设置可以把任务挂起 */
#define INCLUDE_vTaskSuspend 1
/* 设置可以从中断恢复(比如系统睡眠,由中断唤醒 */
#define INCLUDE_vResumeFromISR 1

/* 设置任务延迟的绝对时间,比如现在4:30,延迟到5:00。时间都是绝对时间 */
#define INCLUDE_vTaskDelayUntil 1

/* 设置任务延时,比如延迟30分钟,相对的时间,现在什么时间,不需要知道 */
#define INCLUDE_vTaskDelay 1

/* 设置 取得当前任务分配器的状态 */
#define INCLUDE_xTaskGetSchedulerState 1

/* 设置当前任务是由哪个任务开启的 */
#define INCLUDE_xTaskGetCurrentTaskHandle 1

/* 是否使能这一函数,还数的目的是返回任务执行后任务堆栈的最小未用数量,同样是为防止堆栈溢出 */
#define INCLUDE_uxTaskGetStackHighWaterMark 0

/* 是用用协程。协程公用堆栈,节省RAM,但是没有任务优先级高,也无法和任务通讯 */
#define configUSE_CO_ROUTINES 0

/* 所有协程的最大优先级数,协程优先级永远低于任务。就是系统先执行任务,所有任务执行完了才执行协程。*/
#define configMAX_CO_ROUTINE_PRIORITIES 1

/* 系统内核的中断优先级,中断优先级越低,越不会影响其他中断。一般设成最低 */
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]

/* 系统SVC中断优先级,这两项都在在M3和PIC32上应用 */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]

#endif /* FREERTOS_CONFIG_H */

房贷计算公式

通常银行的房贷计算公式有两种,1.等本息还款2.等本金还款。经常有人问哪种计算方式更省钱,通常我给的回答是哪个都不省钱,主要是看哪个还款方式更适合你,不要用“省”字,不贷款省钱,这是银行蒙蔽你的,等我给你讲清楚利息是怎么得出来的你就会明白所谓的谓钱之说了。”
等额本息就是每月的还款额是一样的,等本金指在贷款期内,每月还银行的本金都是一样的,由于利息逐月递减,所以每月的还款额越来越少。

等额本息每月还的本和息加起来是相等的,这是用一个数学公式推导出来的,你不用考虑这是公式是怎么来的,你只用知道当月利率是多少,你这个月的贷款本金是多少,你上个月了多少本金,你的总本金减去上个月的本金,就是这个月欠银行的本金,当月所欠银行本金乘以月利率就是当月应给银行的利息。看了下面的公式应该更明

1、在利率不变的情况下,等本息法的月还款额是固定的,房贷计算公式如下:

·

· 本月月还利息 = 上月剩余贷款余额 x 月利率

· 本月月还本金 = 月还款额 – 本月月还利息

· 本月剩余贷款余额 = 上月剩余贷款余额 – 本月月还本金

2、在利率不变的情况下,等本金法的月还本金是固定的,计算公式如下:

· 月还本金 = 贷款金额 / 期数

· 本月月还利息 = 上月剩余贷款余额 x 月利率

· 本月月还款额 = 月还本金 + 本月月还利息

· 本月剩余贷款余额 = 上月剩余贷款余额 – 月还本金
如果你看明白了这两种还款方式的计算方法,你就不会再问哪个更省钱,就像你问我贷30万5年省钱还10年省钱,让人觉得可笑。利息就是本金产生的,你这个月还银行的本金多下个月就欠银行的本金少,你负的利息就会减少。银行推出再多的还款方式,无非就是本金产生利息,怎么着就是赚你的利息,除非你不贷款。关键是根据个人的能力来定还款方式,而不是问哪个省钱,所谓的省钱是银行用的“彰眼法。”

一:按等额本金还款法:
设贷款额为a,月利率为i,年利率为I,还款月数为n,an第n个月贷款剩余本金a1=a,a2=a-a/n,a3=a-2*a/n…以次类推
还款利息总和为Y
每月应还本金:a/n
每月应还利息:an*i
每期还款a/n +an*i
支付利息Y=(n+1)*a*i/2
还款总额=(n+1)*a*i/2+a

二:按等额本息还款法:
设贷款额为a,月利率为i,年利率为I,还款月数为n,每月还款额为b,还款利息总和为Y
1:I=12×i
2:Y=n×b-a
3:第一月还款利息为:a×i
第二月还款利息为:〔a-(b-a×i)〕×i=(a×i-b)×(1+i)^1+b
第三月还款利息为:{a-(b-a×i)-〔b-(a×i-b)×(1+i)^1-b〕}×i=(a×i-b)×(1+i)^2+b
第四月还款利息为:=(a×i-b)×(1+i)^3+b
…..

第n月还款利息为:=(a×i-b)×(1+i)^(n-1)+b
求以上和为:Y=(a×i-b)×〔(1+i)^n-1〕÷i+n×b
4:以上两项Y值相等求得
月均还款:b=a×i×(1+i)^n÷〔(1+i)^n-1〕
支付利息:Y=n×a×i×(1+i)^n÷〔(1+i)^n-1〕-a
还款总额:n×a×i×(1+i)^n÷〔(1+i)^n-1〕

注:a^b表示a的b次方。
据此公式可以用excel制作房贷计算器
等额本息:月还款额的计算在Excel中有专门的函数PMT。其用法是PMT(rate,nper,pv,fv,type),即PMT(月利率,还款期限,贷款总额)

等额本金:顾名思意,每个月还的本金是一样的,那么每个月的本金为贷款总额除以总期数。而利息每月是递减的:利息=(贷款总额-以还本金)*贷款利率/12

如何将SQLite数据库(dictionary.db文件)与apk文件一起发布

可以将dictionary.db文件复制到Eclipse Android工程中的res\raw目录中,如图1所示。所有在res\raw目录中的文件不会被压缩,这样可以直接提取该目录中的文件。
使用openDatabase方法来打开数据库文件,如果该文件不存在,系统会自动创建/sdcard/dictionary目录,并将res\raw目录中的 dictionary.db文件复制到/sdcard/dictionary目录中。openDatabase方法的实现代码如下:

代码
private SQLiteDatabase openDatabase()
{
try
{
// 获得dictionary.db文件的绝对路径
String databaseFilename = DATABASE_PATH + “/” + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
// 如果/sdcard/dictionary目录中存在,创建这个目录
if (!dir.exists())
dir.mkdir();
// 如果在/sdcard/dictionary目录中不存在
// dictionary.db文件,则从res\raw目录中复制这个文件到
// SD卡的目录(/sdcard/dictionary)
if (!(new File(databaseFilename)).exists())
{
// 获得封装dictionary.db文件的InputStream对象
InputStream is = getResources().openRawResource(R.raw.dictionary);
FileOutputStream fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[8192];
int count = 0;
// 开始复制dictionary.db文件
while ((count = is.read(buffer)) > 0)
{
fos.write(buffer, 0, count);
}

fos.close();
is.close();
}
// 打开/sdcard/dictionary目录中的dictionary.db文件
SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
databaseFilename, null);
return database;
}
catch (Exception e)
{
}
return null;
}

在openDatabase方法中使用了几个常量,这些常量是在程序的主类(Main)中定义的,代码如下:

代码
public class Main extends Activity implements OnClickListener, TextWatcher
{
private final String DATABASE_PATH = android.os.Environment
.getExternalStorageDirectory().getAbsolutePath()
+ “/dictionary”;
private final String DATABASE_FILENAME = “dictionary.db”;
}

Problem 1003 Fibonacci Numbers

Problem 1003 Fibonacci Numbers
Description
The Fibonacci numbers (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …) are defined by the recurrence:
An = An-1 + An-2, if n >= 2

#include
#include

using namespace std;

int main()
{
vector fibonacci;
fibonacci.push_back(0);
fibonacci.push_back(1);

int tempFibo;
for (int i=0;i<39;i++)
{
fibonacci.push_back( fibonacci[i]+fibonacci[i+1]);
}

int n=0;
while (cin >> n)
{
cout <<”The Fibonacci number for ” << n << ” is ” <<fibonacci[n] << endl;
}

return 0;
}

Problem 1002 Analyzing algorithm

此题以著名的叙古拉猜想为原型。要求我们求两个自然数之间“飞行距离”最长的自然数的飞行距离。

这道题目显然是动态规划的算法。因为在求一个数字的飞行长度时,实际上,可以连带求出许多数字的飞行长度。比如,我们知道,8的飞行长度一定比16少1,因为16/2=8,16的下一个数字肯定是8。又由于我们要的是最长的长度,因此飞行路径中经过的数字可以不予考虑了(如直接置为-1)。

在我的程序中,a是用来存储最大飞行长度的一个数组,路径中的数字所对应的元素被cycle_length函数置为-1。

#include
#include

int *a,m,n,x,y;

int cycle_length(int num) //求飞行长度
{
int i=1;
while(num!=1)
{
if(num%2==1) num=num*3+1;
else num/=2;
if(num>=m&&num<=n) *(a+num-m)=-1;
i++;
}
return i;
}

main()
{
int k,max;
while(scanf("%d%d",&x,&y)==2)
{
m=x; n=y;
if(m>n)
{
k=m;
m=n;
n=k;
}
if(m<=0)m=1;
max=0;
a=(int *)calloc(sizeof(int),(unsigned)(n-m+1));
for(k=n;k>=m;k–)
if(*(a+k-m)!=-1)
*(a+k-m)=cycle_length(k);
for(k=n;k>=m;k–)
if(*(a+k-m)>max) max=*(a+k-m);
printf(“%d %d %dn”,x,y,max);
free(a);
}
}

  50年代开始,在国际数学界广泛流行着这样一个奇怪有趣的数学问题:任意给定一个自然数x,如果是偶数,则变换成x/2,如果是奇数,则变换成3x+1.此后,再对得数继续进行上述变换.例如x=52,可以陆续得出26,13,40,20,10,5,16,8,4,2,1.如果再做下去就得到循环:
  (4,2,1).再试其他的自然数也会得出相同的结果.这个就是叙古拉猜想.
  上述变换,实际上是进行下列函数的迭代
  { x/2 (x是偶数)
  C(x)=
  3x+1 (x是奇数)
  问题是,从任意一个自然数开始,经过有限次函数C迭代,能否最终得到循环(4,2,1),或者等价地说,最终得到1?据说克拉茨(L.Collatz)在1950年召开的一次国际数学家大会上谈起过,因而许多人称之为克拉茨问题.但是后来也有许多人独立地发现过同一个问题,所以,从此以后也许为了避免引起问题的归属争议,许多文献称之为3x+1问题.
  克拉茨问题吸引人之处在于C迭代过程中一旦出现2的幂,问题就解决了,而2的幂有无穷多个,人们认为只要迭代过程持续足够长,必定会碰到一个2的幂使问题以肯定形式得到解决.正是这种信念使得问题每到一处,便在那里掀起一股”3x+1问题”狂热,不论是大学还是研究机构都不同程度地卷入这一问题.许多数学家开始悬赏征解,有的500美元,有的1000英镑.
  日本东京大学的米田信夫已经对240大约是11000亿以下的自然数做了检验.1992年李文斯(G.T.Leavens)和弗穆兰(M.Vermeulen)已经对5.6*1013的自然数进行了验证,均未发现反例.题意如此清晰,明了,简单,连小学生都能看懂的问题,却难到了20世纪许多大数学家.著名学者盖伊(R.K.Guy)在介绍这一世界难题的时候,竟然冠以”不要试图去解决这些问题”为标题.经过几十年的探索与研究,人们似乎接受了大数学家厄特希(P.Erdos)的说法:”数学还没有成熟到足以解决这样的问题!”有人提议将3x+1问题作为下一个费尔马问题.

Easy or not

Description
We are wondering how easy a problem can be. According to recent research, the most easy problem may be the one which requires to output exactly the input, other than the classical A+B Problem.
As our best programmer, you are asked to write a program to prove the conclusion.
Input
Lots of characters.
Output
Characters exactly the same as input.
Sample Input
The quick brown fox jumps over the lazy dog.
question = to ? be : !be;
Sample Output
The quick brown fox jumps over the lazy dog.
question = to ? be : !be;Hint
Huge input

代码如下

#include

int main()
{
int c;

while((c=getchar())!=EOF)
putchar(c);

return 0;
}

该实现,耗时较多。

getchar 由宏实现:#define getchar() getc(stdin)。getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.
getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回。

这道题提示的难点是大量输入的处理,因为无法输入大小,所以直接输出。

A + B Problem

#include

int main()
{
int a,b;
while(scanf(“%d %d”, &a, &b)!=EOF)
{
printf(“%dn”, a+b);
}
return 0;
}

scanf的返回值由后面的参数决定
scanf(“%d%d”, &a, &b);
如果a和b都被成功读入,那么scanf的返回值就是2
如果只有a被成功读入,返回值为1
如果a和b都未被成功读入,返回值为0
如果遇到错误或遇到end of file,返回值为EOF(在头文件stdio.h中定义)。
且返回值为int型。

频谱动态共享

频谱动态共享功能来源于欧洲运营商的Refarming需求。所谓Refarming是指运营商对自己的频谱资源进行重复利用,通过新的无线通信技术提升频谱效率和数据吞吐率。例如运营商可以将自己占用的900GSM频段中划分5MHz出来部署UMTS网络。

目前,动态频谱共享主要有GU和GL两种。