2008年10月18日星期六

驱动函数中变量的高效分配

如果一个函数常常被其他程序调用,那么如何在该函数中进行变量分配呢?常见做法有以下3种:
1. 频繁地为参数分配栈内存是一种低效的做法;
2.
使用动态内存好象可以解决上面的问题,但它没有考虑到频繁地使用malloc-free会产生大量的内存碎片。在嵌入式系统环境中,一般内存大小有限,所以这种做法最终会导致分配失败。
3.
对于处理大流量数据问题,一种比较常用的高效方法就是在函数内部使用静态数组(全局静态数组在这个应用中不建议使用,因为全局变量会增加函数间的耦合度)。
关键字static有以下明显的作用:
(1).static变量分配到静态内存中,这一点和全局非静态变量相同。
(2).在函数体,static变量只要不进行修改操作,在被调用过程中其值将保持不变。
(3).在模块内,全局static变量可以被模块内所有函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量,具有私有特点。
(4).在模块内,一个static函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用,也具有私有特点。

But,千万要小心"代码可重入(reentrance)"可能产生的问题!
使用静态数组的确不用频繁地分配动态或栈内存,但同时引入了代码不可重入的问题。因为函数内的static变量分配在静态内存区,供所有对象共用。在多任务系统中,如果有一个以上的任务同时访问该内存,很可能会出现问题。因此必须要用其它手段来消除这个不可重入问题。使用信号量semaphore是一个很好解决不可重入问题的方法。

在编写设备驱动程序时,也有此问题。驱动功能主要有两个:操作底层硬件和提供上层接口。不推荐直接在驱动硬件层使用semaphore进行代码可重入保护,因为semaphore是操作系统提供的。推荐将驱动分层:硬件相关层和硬件无关层。硬件相关层主要处理硬件设备初始化及具体操作;硬件无关层来处理防止函数重入/封装接口/同异步调用/调用排队等操作。

没有评论: