ucos-ii
风吹散了我们的记忆
嵌入式学习爱好者
展开
-
OSTickISR()
在9.03.05节中,我们已经提到过实时系统中时钟节拍发生频率的问题,应该在10到100Hz之间。但由于PC环境的特殊性,时钟节拍由硬件产生,间隔54.93ms (18.20648Hz)。我们将时钟节拍频率设为200Hz。PC时钟节拍的中断向量为0x08,µC/OS-II将此向量截取,指向了µC/OS的中断服务函数OSTickISR(),而原先的中断向量保存在中断129(0x81)中。为满足DOS原创 2017-05-19 09:03:15 · 2010 阅读 · 0 评论 -
OSTimeTickHook()
void OSTimeTickHook(void)File Called from Code enabled byOS_CPU_C.C OSTimeTick() OS_CPU_HOOKS_EN 只要发生时钟节拍,该函数就会被OSTimeTick()调用。一旦进入OSTimeTick()就会马上调用OSTimeTickHook()以允许执行用户的应用程序中的与时间密切相关的代码。用户还可以原创 2017-05-08 18:02:08 · 1886 阅读 · 0 评论 -
µC/OS-II在80x86上的移植
本章将介绍如何将µC/OS-II移植到Intel 80x86系列CPU上,本章所介绍的移植和代码都是针对80x86的实模式的,且编译器在大模式下编译和连接。本章的内容同样适用于下述CPU:80186802868038680486PentiumPentium II实际上,将要介绍的移植过程适用于所有与80x86兼容的CPU,如AMD,Cyrix,NEC (V-系列)等等。以Intel的原创 2017-05-09 16:17:33 · 948 阅读 · 0 评论 -
查询一个邮箱的状态, OSMboxQuery()
OSMboxQuery()函数使应用程序可以随时查询一个邮箱的当前状态。程序清单 L6.18是该函数的源代码。它需要两个参数:一个是指向邮箱的指针pevent。该指针是在建立该邮箱时,由OSMboxCreate()函数返回的;另一个是指向用来保存有关邮箱的信息的OS_MBOX_DATA(见uCOS_II.H)数据结构的指针pdata。在调用OSMboxCreate()函数之前,必须先定义该结构变量原创 2017-04-06 10:08:38 · 1195 阅读 · 0 评论 -
用邮箱作二值信号量
一个邮箱可以被用作二值的信号量。首先,在初始化时,将邮箱设置为一个非零的指针(如 void *1)。这样,一个任务可以调用OSMboxPend()函数来请求一个信号量,然后通过调用OSMboxPost()函数来释放一个信号量。程序清单 L6.19说明了这个过程是如何工作的。如果用户只需要二值信号量和邮箱,这样做可以节省代码空间。这时可以将OS_SEM_EN设置为0,只使用邮箱就可以了。程序清单原创 2017-04-07 08:50:21 · 615 阅读 · 0 评论 -
无等待地从邮箱中得到一个消息, OSMboxAccept()
应用程序也可以以无等待的方式从邮箱中得到消息。这可以通过程序清单 L6.17中的OSMboxAccept()函数来实现。OSMboxAccept()函数开始也是检查事件控制块是否是由OSMboxCreate()函数建立的 [L6.17(1)]。接着,它得到邮箱中的当前内容[L6.17(2)],并判断是否有消息是可用的[L6.17(3)]。如果邮箱中有消息,就把邮箱清空[L6.17(4)],而邮箱中原创 2017-04-05 10:00:30 · 2406 阅读 · 0 评论 -
Using Memory Partitions
图 F7.5是一个演示如何使用µC/OS-II中的动态分配内存功能,以及利用它进行消息传递[见第6章]的例子。程序清单 L7.8是这个例子中两个任务的示意代码,其中一些重要代码的标号和图 F7.5中括号内用数字标识的动作是相对应的。第一个任务读取并检查模拟输入量的值(如气压、温度、电压等),如果其超过了一定的阈值,就向第二个任务发送一个消息。该消息中含有时间信息、出错的通道号和错误代码等可以想象原创 2017-04-25 09:11:31 · 321 阅读 · 0 评论 -
查询一个内存分区的状态,OSMemQuery()
在µC/OS-II 中,可以使用OSMemQuery()函数来查询一个特定内存分区的有关消息。通过该函数可以知道特定内存分区中内存块的大小、可用内存块数和正在使用的内存块数等信息。所有这些信息都放在一个叫OS_MEM_DATA的数据结构中,如程序清单 L7.6。程序清单 L7.6 OS_MEM_DATA数据结构typedef struct { void *OSAddr; /原创 2017-04-24 15:43:53 · 975 阅读 · 0 评论 -
释放一个内存块,OSMemPut()
当用户应用程序不再使用一个内存块时,必须及时地把它释放并放回到相应的内存分区中。这个操作由OSMemPut()函数完成。必须注意的是,OSMemPut()并不知道一个内存块是属于哪个内存分区的。例如,用户任务从一个包含32字节内存块的分区中分配了一个内存块,用完后,把它返还给了一个包含120字节内存块的内存分区。当用户应用程序下一次申请120字节分区中的一个内存块时,它会只得到32字节的可用空间,原创 2017-04-23 20:44:10 · 2313 阅读 · 0 评论 -
分配一个内存块,OSMemGet()
图 F7.4是OSMemCreate()函数完成后,内存控制块及对应的内存分区和分区内的内存块之间的关系。在程序运行期间,经过多次的内存分配和释放后,同一分区内的各内存块之间的链接顺序会发生很大的变化。应用程序可以调用OSMemGet()函数从已经建立的内存分区中申请一个内存块。该函数的唯一参数是指向特定内存分区的指针,该指针在建立内存分区时,由OSMemCreate()函数返回。显然,应用程序原创 2017-04-21 08:42:32 · 4076 阅读 · 0 评论 -
建立一个内存分区,OSMemCreate()
在使用一个内存分区之前,必须先建立该内存分区。这个操作可以通过调用OSMemCreate()函数来完成。程序清单 L7.2说明了如何建立一个含有100个内存块、每个内存块32字节的内存分区。程序清单 L7.2 建立一个内存分区OS_MEM *CommTxBuf;INT8U CommTxPart[100][32];void main (void){ INT8U err;原创 2017-04-20 08:38:23 · 2086 阅读 · 0 评论 -
内存管理
我们知道,在ANSI C中可以用malloc()和free()两个函数动态地分配内存和释放内存。但是,在嵌入式实时操作系统中,多次这样做会把原来很大的一块连续内存区域,逐渐地分割成许多非常小而且彼此又不相邻的内存区域,也就是内存碎片。由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到。在4.02节的任务堆栈中,我们讲到过用malloc()函数来分配堆栈时,曾经讨论过内存碎片的问题。另外原创 2017-04-19 10:04:25 · 441 阅读 · 0 评论 -
OSTaskStatHook()
void OSTaskStatHook(void)File Called from Code enabled byOS_CPU_C.C OSTaskStat() OS_CPU_HOOKS_EN 该函数每秒钟都会被µC/OS-Ⅱ的统计任务调用。OSTaskStatHook()允许用户加入自己的统计功能。参数 无返回值 无注意事项 统计任务大概在调用OSStart()后再过5秒开原创 2017-05-07 08:45:49 · 805 阅读 · 0 评论 -
OSTaskDelHook()
void OSTaskDelHook(OS_TCB *ptcb)File Called from Code enabled byOS_CPU_C.C OSTaskDel() OS_CPU_HOOKS_EN 当用户通过调用OSTaskDel()来删除任务时都会调用该函数。这样用户就可以处理OSTaskCreateHook()所分配的内存。OSTaskDelHook()就在TCB从TCB链中原创 2017-05-05 15:45:27 · 373 阅读 · 0 评论 -
OSTaskCreateHook()
void OSTaskCreateHook(OS_TCB *ptcb)File Called from Code enabled byOS_CPU_C.C OSTaskCreate() and OSTaskCreateExt() OS_CPU_HOOKS_EN 无论何时建立任务,在分配好和初始化TCB后就会调用该函数,当然任务的堆栈结构也已经初始化好了。OSTaskCreateHook原创 2017-05-04 20:58:43 · 1056 阅读 · 0 评论 -
OSIntCtxSw()
在µC/OS-II中,由于中断的产生可能会引起任务切换,在中断服务程序的最后会调用OSIntExit()函数检查任务就绪状态,如果需要进行任务切换,将调用OSIntCtxSw()。所以OSIntCtxSw()又称为中断级的任务切换函数。由于在调用OSIntCtxSw()之前已经发生了中断,OSIntCtxSw()将默认CPU寄存器已经保存在被中断任务的堆栈中了。程序清单L9.5给出的代码大部分原创 2017-05-17 09:12:15 · 1372 阅读 · 0 评论 -
OSCtxSw()
OSCtxSw()是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw())。在80x86系统上,它通过执行一条软中断的指令来实现任务切换。软中断向量指向OSCtxSw()。在µC/OS-II中,如果任务调用了某个函数,而该函数的执行结果可能造成系统任务重新调度(例如试图唤醒了一个优先级更高的任务),则在函数的末尾会调用OSSched(),如果OSSched()判原创 2017-05-16 09:51:06 · 2545 阅读 · 0 评论 -
OSStartHighRdy()
µC/OS-II 的移植需要用户改写OS_CPU_A.ASM中的四个函数:OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()该函数由SStart()函数调用,功能是运行优先级最高的就绪任务,在调用OSStart()之前,用户必须先调用OSInit(),并且已经至少创建了一个任务(请参考OSTaskCreate()和OSTaskCreateExt原创 2017-05-15 18:39:20 · 6111 阅读 · 0 评论 -
OS_CPU.H
数据类型由于不同的处理器有不同的字长,µC/OS-II的移植需要重新定义一系列的数据结构。使用Borland C/C++编译器,整数(int)类型数据为16位,长整形(long)为32位。为了读者方便起见,尽管µC/OS-II中没有用到浮点类型的数,在源代码中笔者还是提供了浮点类型的定义。由于在80x86实模式中堆栈都是按字进行操作的,没有字节操作,所以Borland C/C++编译器中堆栈数原创 2017-05-13 08:42:15 · 440 阅读 · 0 评论 -
OS_CPU.H文件
OS_CPU.H 文件中包含与处理器相关的常量,宏和结构体的定义。程序清单L9.2是为80x86编写的OS_CPU.H文件的内容。程序清单L 9.2 OS_CPU.H.#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif/*****************************原创 2017-05-11 21:10:16 · 785 阅读 · 0 评论 -
等待一个内存块
有时候,在内存分区暂时没有可用的空闲内存块的情况下,让一个申请内存块的任务等待也是有用的。但是,µC/OS-II本身在内存管理上并不支持这项功能。如果确实需要,则可以通过为特定内存分区增加信号量的方法,实现这种功能(见6.05节,信号量)。应用程序为了申请分配内存块,首先要得到一个相应的信号量,然后才能调用OSMemGet()函数。整个过程见程序清单 L7.9。程序代码首先定义了程序中使用到的各原创 2017-04-26 10:11:37 · 312 阅读 · 0 评论 -
移植µC/OS-Ⅱ
这一章介绍如何将µC/OS-Ⅱ移植到不同的处理器上。所谓移植,就是使一个实时内核能在某个微处理器或微控制器上运行。为了方便移植,大部分的µC/OS-Ⅱ代码是用C语言写的;但仍需要用C和汇编语言写一些与处理器相关的代码,这是因为µC/OS-Ⅱ在读写处理器寄存器时只能通过汇编语言来实现。由于µC/OS-Ⅱ在设计时就已经充分考虑了可移植性,所以µC/OS-Ⅱ的移植相对来说是比较容易的。如果已经有人在您使原创 2017-04-27 09:21:03 · 1053 阅读 · 0 评论 -
OS_CPU.H
OS_CPU.H包括了用#defines定义的与处理器相关的常量,宏和类型定义。OS_CPU.H的大体结构如程序清单 L8.1所示。程序清单 L 8.1 OS_CPU.H.#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif/***************************原创 2017-04-28 15:43:12 · 476 阅读 · 0 评论 -
OS_CPU_A.ASM
µC/OS-Ⅱ的移植实例要求用户编写四个简单的汇编语言函数: OSStartHighRdy() OSCtxSw() OSIntCtxSw() OSTickISR() 如果用户的编译器支持插入汇编语言代码的话,用户就可以将所有与处理器相关的代码放到OS_CPU_C.C文件中,而不必再拥有一些分散的汇编语言文件。.01 OSStartHighRdy() 使就绪状态的任务开始运行的原创 2017-04-30 08:46:09 · 742 阅读 · 0 评论 -
OS_CPU_C.C
µC/OS-Ⅱ的移植实例要求用户编写六个简单的C函数: OSTaskStkInit() OSTaskCreateHook() OSTaskDelHook() OSTaskSwHook() OSTaskStatHook() OSTimeTickHook() 唯一必要的函数是OSTaskStkInit(),其它五个函数必须得声明但没必要包含代码。OSTaskStkInt()原创 2017-05-01 09:04:25 · 914 阅读 · 0 评论 -
OSTaskCreateHook(),OSTaskDelHook(),OSTaskSwHook(),OSTaskStatHook(),OSTimeTickHook()
当用OSTaskCreate()或OSTaskCreateExt()建立任务的时候就会调用OSTaskCreateHook()。该函数允许用户或使用用户的移植实例的用户扩展µC/OS-Ⅱ的功能。当µC/OS-Ⅱ设置完了自己的内部结构后,会在调用任务调度程序之前调用OSTaskCreateHook()。该函数被调用的时候中断是禁止的。因此用户应尽量减少该函数中的代码以缩短中断的响应时间。 当OST原创 2017-05-02 09:09:15 · 929 阅读 · 0 评论 -
使用一个消息队列作为计数信号量
在消息队列初始化时,可以将消息队列中的多个指针设为非NULL值(如void* 1),来实现计数信号量的功能。这里,初始化为非NULL值的指针数就是可用的资源数。系统中的任务可以通过OSQPend()来请求“信号量”,然后通过调用OSQPost()来释放“信号量”,如程序清单 L6.28。如果系统中只使用了计数信号量和消息队列,使用这种方法可以有效地节省代码空间。这时将OS_SEM_EN设为0,就可原创 2017-04-18 08:58:45 · 833 阅读 · 0 评论