标题：rf5
DSP软件开发参考框架
RF5是一种DSP软件开发的起步代码参考框架，它以DSP/BIOS为基础，利用其中的数据处理元素和数据通信元素方便快捷地完成DSP软件的设计与开发RF5是RF的最新版本，其区别于RF1和RF3的显著特点是其支持动态对象创建和支持线程（任务）挂起功能，因此适合系统较复杂的应用场合。
RF5 主要实现三个功能，存储管理，线程模型和通道封装，对于不同的应用，我们只需在这三个元素上做修改，而对于整个应用程序，不用从头设计，这样大大简化了开发者的开发难度，缩短了开发时间。
RF5适用于包含大量的算法，且要求多线程，多通道的应用，如图像处理，多媒体应用等，以Ti提供的实例mpeg2loopback为例，对RF5进行分析。
RF5包含的元素有：
1 线程(Thread)：
RF5框架包含四个基本的数据处理元素，处在最顶层的是线程，线程总是顺序的执行所包含的通道，线程在一个比较高级的级别上把数据组织在一起，他们可以与别的线程，设备驱动以及别的类似结构进行通讯，在mpeg2lookback实例中，创建了三个线程分别是tskVideoInput，tskVideoOutput和tskProcess。每个线程都在不断的等待消息，处理数据，并将结果发送给其他的线程，同时有可能还要发送同步消息给其他线程已实现线程间的通讯，这里使用的机制是SCOM模块。
每个线程都是进行数据处理的一个单元，有的是处理简单的，有的处理是相对复杂的过程，简单的线程可以不包括任何的通道，而进行复杂数据处理的线程有可能包含多个的通道。
2 通道(Channel):
RF5提供了一种通道结构是为了更方便的封装算法，这可以理解通道为并行里的串行，因为线程的执行就是由通道的串行执行来完成的，一个通道包含一组核（Icell），其主要任务就是依次顺序的执行所包含的核，主要执行的流程为：首先需要初始化通道模块，然后建立通道对象，注册该通道所包含的核对象，接着依次执行每个核，执行完成了后就销毁对象，最后退出。每个通道可以包含多个核，每个核都要进行初始化后在调用CHAN_regCell注册。
通道对象的结构如下：
typedef struct CHAN_Obj {
ICELL_Obj *cellSet; /* set of cells in the channel */
Uns cellCnt; /* number of cells in the cellSet */
CHAN_State state; /* state of the channel */
Bool (*chanControlCB)(CHAN_Handle chanHandle); /* optional control function */
} CHAN_Obj;
线程一般不定义通道对象，但是在CHAN_open()调用中初始化它们。CHAN_open()的最后一个参数是通道属性（CHAN_Attrs)结构体的地址。如果最后一个参数是NULL，那么CHAN_open()使用默认的参数。如果要想使用不同的参数，就要声明一个CHAN_Attrs的结构体，并需初始化为CHAN_ATTRS宏所定义的初值，然后根据需要可以修改其中相应的域的值，通常，其中的通道状态参数CHAN_State state域默认为CHAN_ACTIVE，以及通道控制回调函数参数域Bool (*chanControlCB)(CHAN_Handle chanHandle)默认为NULL。如果通道控制回调函数不是空，那么在任何的cell调用执行之前都会先调用此回调函数。
一个典型的设置，一个线程为每一个通道建立一个CHAN_Obj对象（或者一组类似的对象），并且为每一个cell建立一个ICELL_Obj对象(或者是与每个通道相对应的一组ICCE_Obj对象).在线程初始化ICELL_Obj之后就会调用下面的函数：
备注其中的cell 指向cell 对象的指针, inputIcc/outputIcc是相应的cell的 ICC 对象，这个调用计算单元需要的空间,并分配给定的ICC对象给单元cell。
CHAN_regCell( cell, inputIcc, 1, outputIcc, 1 );
当所有的cells都已经创建并初始化之后，线程调用CHAN_open()函数来为每一个指定的通道（chanNum）传递cell对象（cellList）。这个函数创建所有的XDAIS算法，并且如果单元细胞定义了cellOpen函数，则会调用每一个单元细胞的cellOpen函数,.
CHAN_open( chanList[ chanNum ], cellList, numCells, NULL/* default attributes */ );
最后，在运行时，线程为每一个通道（chanNum）调用CHAN_execute函数开始执行：
CHAN_execute( chanList[ chanNum ], NULL /* arg to cells */ );
3 核（Icell）：
核实际上就是ICELL接口对象，基于RF5的应用常常包含大量的算法和通道，为了便于算法集中到应用中，RF5提出了核的概念，一个核就是包含一种XDAIS算法的容器，一个RF5通道对象可以包含多个核，也即是包含多个算法，通道通过核来调用算法，实际上，真正的数据处理是在XDAIS算法，核只是提供一个调用算法的接口，这大大简化了工作量，便于移植。
该接口包含一个重要的结构：ICELL_Fxns,该结构包含一组函数指针。通道通过调用这些函数来调用算法，其中包含一个关键的函数cellExecute，这个函数的功能是调用XDAIS算法来执行，上面的通道执行函数CHAN_execute就包含了每个cellExecute的调用。
4 ICC模块
ICC模块是用来管理在核之间以及核与其他线程之间的数据通讯，我们知道线程间的数据传输是通过SCOM模块来实现的，每个ICC模块管理一个或者多个ICC对象，每个核都有一组输入和输出ICC对象。这些对象是通过CHAN_regCell（）来注册到相应的通道里。
5 同步通讯机制(SCOM)
ThrProcess中包含两个SCOM对象，RF5使用SCOM对象来实现线程的通讯。SCOM消息时用户自定义的一个机构，一个线程通过调用SCOM_putMsg()函数将SCOM消息放置一个SCOM队列中，发送给其他的线程，或者通过调用SCOM_getMsg()函数从队列中获取消息，一般情况下，发送消息指明接收线程所要读取的数据缓冲区的地址（以指针形式），接收消息指明发送线程所要写入的数据缓冲区的地址，在mape2loopback实例中，thrProcess要从thraVideoInput接收消息，并发送消息给thrVideoOutput输出图像。RF5使用SCOM来实现线程间的通讯：thrProcess拥有一些缓冲区，需要thrVideoInput写或thrVideoOutput读，所以thrProcess通过SCOM告诉thrVideoIput和thrVideoOutput线程数据缓冲区的地址，同时还要保证两个线程不会同时访问同一个缓冲区。thrProcess创建了两种消息以分别和两个线程进行通讯，scomMsgRx和scomMsgTx,scomMsgRx指定了被thrVideoInput写的缓冲区地址，scomMsgTx指定了被thrVideoOutput读的缓冲区地址。
在实际的操作中，可是将SCOM看作是种同步标记，她用来区分模块内存是否正在被其他线程所使用，这样就可以放置内存访问的冲突。整个系统中包含很多存储区，这些内存区很有可能在某一时刻正在被某一线程访问，为了保证在任意时刻只有一个线程访问某一块内存，当前正在访问这一内存块的线程通过发送SCOM消息给与这一内存块有关联的线程，告诉他，“我正在访问呢，你等会再来吧”。当他访问完后，放弃了这一内存块的占有权，再通过SCOM消息告诉相关联的线程，“我用完了，你可以用了。”于是相关联的线程就可以访问了。
6 ALGRF模块—算法的实例化Algorithm Instantiation
ALGRF Module用DSP/BIOSMEM内存管理器来创建和删除XDAIS算法的模块。参考框架服务简化XDAIS部件的使用。所有符合XDAIS标准的算法都必须使用一个标准的接口——IALG接口。ALGRF使用算法的IALG来实现对XDAIS算法的实例化。任何符合XDAIS标准的算法都可以被ALGRF所使用。
用户代码不必直接的调用ALGRF函数，这个工作由CHAN和其他的库函数来完成。例外的是cell wrappers中的ALGRF_activate/deactivate序列化：如果cell中的XDAIS算法执行IALG_active/deactivate函数,细胞需要调用两个ALGRF函数来完成。
三个模块来简化IALG接口创建算法对象，RF5使用ALGRF模块来创建，配置，删除XDAIS算法实例。ALG模块使用CCStudio作为通用目的使用,并且不用DSP/BIOS MEM模块分配内存.ALGMIN是三个中的最小应用。
一般情况下，三个模块是相互包含的，但是只有一个能在应用程序中使用。ALGRF适于RF5的需要和别的RF级别，而不适合紧凑和底端的如RF1级别的系统。
ALGRF与ALG相比，有以下的优势：
1　更小的代码脚本（代码量）：
作为一个通用的模块，ALG支持malloc/free 运行时库和DSP/BIOS MEM_alloc/MEM_free动态内存分配方式，ALGRF只支持DSP/BIOS分配，这为设计者省了代码空间，另外ALGRF保证没有无用代码的存在.只有被调用的函数才被连接到执行程序中。
2　暂存区支持：
下面的API在ALGRF中介绍的实例：
ALGRF_Handle ALGRF_createScratchSupport(IALG_Fxns *fxns, IALG_Handle parent,
IALG_Params *params, Void *scratchBuf, Uns scratchSize)
除了当IALG_SCRATCH内存区域（内部数据缓冲区）被请求，该函数能根据算法请求分配内存。作为替代，scratchBuf和scratchSize这两个参数表明这一缓冲区已经在应用中存在,而且可以被当前的算法重新使用.这就可以受约束的共享资源有限的内存区。
3　从DSP/BIOS堆标签中做提取：
ALGRF使用DSP/BIOS 的MEM模块动态分配内存。一个堆标记或内存段名可以传给
MEM_alloc()来表明分配到哪一个堆.如下:
/* Configure the ALGRF module to use:
* 1st argument - memory for internal heap
* 2nd argument - memory for external heap
*/
ALGRF_setup( INTERNALHEAP, EXTERNALHEAP );
这让我们可以指定算法的数据分配位置。例如,如果使用EXTERNALHEAP作为两个参数，那么算法的数据就被定位在外部存储器。
读书郎视频文件
.rf5文件，为读书郎 H6 H8 H10名师课堂文件，可以用相应机型打开。