当前位置:嗨网首页>书籍在线阅读

10-借用芯片厂商的范例程序

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

23.2.3 借用芯片厂商的范例程序

在外围芯片上市之前,芯片厂商往往进行了严格的验证,在他们的验证过程中,必然会编写代码去访问和控制这些芯片。很多时候,这些代码稍经整理就被芯片厂商随同datasheet一起在网站上作为参考代码发布。

范例程序往往停留在无操作系统的层次上,只是最底层的硬件操作代码,这一部分代码对驱动工程师的意义如下。

● 帮助工程师进一步理解芯片与CPU的接口原理、芯片的访问和控制方法。

● 直接加以改进后搬到Linux设备驱动中。

Linux设备驱动的硬件操作方法会与无操作系统时的硬件操作方法有如下差异。

● 无操作系统的硬件访问方法中往往没有物理地址到虚拟地址的映射过程,因此,在搬到Linux系统中的时候,要注意以静态映射或ioremap()等方式映射到虚拟地址。

● 硬件访问中往往夹杂着延时,因此,在无操作系统的源码中,经常会出现xxx_delay()这样的for循环延迟,这些代码应该被内核中的ndelay()或udelay()替换。如果延迟时间达到数十ms,应该使用msleep()或msleep_interruptible()等函数。

● 芯片范例程序只是对芯片的操作方法进行示范,它并不会考虑真实应用场景中对CPU的资源占用以及代码的时间性能。例如,如果在写寄存器REGA后,要判断寄存器REGB的第0位为1后才能进行下一次写,则无操作系统中的代码呈现为:

write_rega(int value)

{

rega = value;

while (!(regb &0x1));

}

第2句的while (!(regb &0x1))是比较致命的,如果系统中用的Linux不支持抢占调度,而REGB的第0位变成1需要相当长的时间(如数十ms),这种忙等待会导致其他的进程全部得不到机会执行。即使Linux支持抢占调度,进行这样的忙等待也毫无意义,Linux中理想的做法是进行在这种情况下调度其他进程执行或者调用cpu_relax():

while (my_variable != what_i_want)

cpu_relax();

其中的cpu_relax()的作用是降低CPU的消耗,同时也起到内存屏障(memory barrier)的作用,因此在内核的Document/volatile-considered-harmful.txt文档中,建议这种忙等待也不要使用volatile关键字。

使用while (!(regb &0x1))这样的判断还有一个问题,如果硬件出现了故障,REGB的第0位总是变不成1的话,在系统不支持抢占调度的情况下,就“死机”了,所以在进行忙等待的时候,许多场合下会设置一个超时机制。