[MID project] Daily Report from voidjack

发布于 2022-09-18 11:24:27 字数 1111 浏览 21 评论 0

在内核启动过程中,会调用calibrate_delay()函数,该函数通过两个tick之间的间隔可以比较精确地计算出udelay(x)函数正真能够delay的时间。
  在linux中,有个全局变量jiffies纪录了从开机开始时钟中断发生的次数,每秒触发多少次中断有一个CONFIG_HZ宏来定义,在2.6.33的内核中,pxa168
  的CONFIG_HZ定义为100,这就是说每秒触发100次时钟中断,当然,这样的时钟精度是非常低的。有个这个参数后,我们可以通过编程获取udelay()
  比较精确的时间,比如说两个tick之间间隔为udelay(100000)(1/100秒),那么可以计算出udelay(10)就是延迟1/1000000秒,即1微秒。

  既然内核中可以通过这个方法获取比较精确的udelay时间,那么在g-bios中,也可以采用相同的方法。但是需要注意的是,采用这个方法的前提是中断是可用的。
  那在没有中断的情况下,能计算出udelay(x)精确的delay时间么?
  以gbios所支持的9261为例,9261的时钟中断是PIT模块实现的,在PIT的PIT_MR寄存器中写入一个数值,然后打开PIT,这时PIT会以MASKCLOCK/16的频率
  从0开始累加,当数值累加到PIT_MR寄存器所存储的值时,会发出一个时钟中断。在中断不可用的情况下,我们可以通过poll方式轮询PIT的状态寄存器来获取是
  否有中断发出(这个中断无需处理),从而获取一个精确的时间基准来计算udelay(x)函数的延迟时间,伪代码如下:
  enable_pit();
  while (pit_not_send_interrupt)
  {
      udelay(x);
      count++;
  }
  通过这样的方式,可以计算出udelay(x)实际延迟的时间,当然,x越大,count越小,udelay(x)延迟时间可能会计算得更加精确一些。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

花心好男孩 2022-09-25 11:24:27

今天在g-bios中实现了calibrate_delay()函数,通过该函数可以计算出比较精确的loops_for_perjiffies,该值表示的是,udelay(x)延迟的时间等于
一个时钟中断间隔,loops_for_perjiffies 就是x。udelay()函数有多种实现方式,但在相同的系统上,相同的udelay测试出来的loops_for_perjiffies
几乎是相同的,calibrate_delay()函数通过两轮循环来测试loops_for_perjiffie,第一轮以一个给定数字做为loops_for_perjiffie来测试,如果测试失败
则loops_for_perjiffie = loops_for_perjiffie * 2;直到测试成功;第二轮,在前面的基础上,以测试通过的前一个loops_for_perjiffie值为基础测试,测
试 失败则loops_for_perjiffie = loops_for_perjiffie + 1;通过两轮测试,可以获取相对精确和稳定的值,以我今天在at91sam9261上测试的结果,
10次测试中,6次测试的结果都是6090,其余4个结果和6090的差值都小于3.

为了测试loops_for_perjiffies的值是否准确,我做了测试,伪代码如下:
print jiffies
udelay(loops_for_perjiffies *1000*10) //在at91sam9261系统中,每秒产生1000次时钟中断,loops_for_perjiffies *1000*10意味着延迟10秒
print jiffies

在at91sam9261系统上,测试出来的loops_for_perjiffies为6090
三次测试的实际结果如下:
    2073                                                                                                                                                     
    12059

    2073
    12059

    2073
    12059
理论上,10秒延迟,如果jiffies值原是2073,那么10秒后应该为2073 +10000 = 12073,这样,可以计算出udelay(60900000)的误差为千分之14秒。
因为udelay(6090)是一毫秒,那么延迟一微秒应该是udelay(6),这样计算,延迟一微妙的误差在14/1000 0000 000秒,约1.4纳秒。

垂暮老矣 2022-09-25 11:24:27

本帖最后由 voidjackjiang 于 2010-03-11 11:18 编辑

今天想了一下g-bios的udelay的实现方法。
  udelay()本身是需要跨平台的,因此该函数应该在base/timer.c目录里实现。但是udelay()里面的调用的__udelay()函数则不同的平台有不同实现,该函数应该在arch/arm中实现。这样,前面帖子讨论的计算loop_for_perjiffies的方法则无须考虑arch。
  计算好loops_for_perjiffies后,udelay()函数依据传入的参数计算实际所需要循环的次数,调用__udelay()即可。

天暗了我发光 2022-09-25 11:24:27

本帖最后由 voidjackjiang 于 2010-03-12 21:21 编辑

在2440下点亮了7寸的lcd屏幕
但是在pxa下lcd没有任何反应,分析可能原因如下:

1)lcd的clock没有正确设置,目前我写了APMU_LCD_CLK_RES_CTL寄存器。
2)lcd的gpio没有正确设置,从pxa的sch中的tsc的原理图还没看出端倪,从pxa的datasheet来看,目前我的理解好像gpio不需要设置。
3)lcd的reg没有正确设置,pxa的lcd寄存器是在太多,需要多读几遍。

落日海湾 2022-09-25 11:24:27

本帖最后由 voidjackjiang 于 2010-03-15 08:05 编辑

继续昨天的pxa下的fb的开发,datasheet又读了一遍,lcd部分配置分了好几种模式,其中模式4是16bit数据为无需SPI总线的,因为不熟悉SPI总线,因此我选择了这个模式,并按照这个模式配置了相关引脚,但是这些引脚并非GPIO,而是MFPR,在配置的过程中,有个参数叫driver stength,对这些参数的设置我还不是很清楚,但我梳理了一下lcd驱动开发的三个步骤:
1 配置clock,pxa的lcd clock大考是在APMU单元中设置的,APMU所有寄存器中有关lcd的寄存器我已经检查并设置,这个部分应该是没有问题的;
2 配置引脚,这个就是我今天做的,模式4 lcd的数据线以及时钟信号线怎么连接是可以确定的,但是对相关引脚的配置并不是很清楚;
3 设置lcd相关寄存器的值,这部分目前还没有开始;

  因为这样的进展实在是太慢了,我打算参考一下linux源码里面是如何做的,虽然编译的kernel在pxa的板子上并没有跑起来!

甜尕妞 2022-09-25 11:24:27

本帖最后由 voidjackjiang 于 2010-03-15 23:03 编辑

DONE:
     1.了解pxa比较特殊的Multi-Function Pin Drive Strength设置,这个是设置lcd引脚的基础
     2. 弄清楚了APMU中设置lcd clock的设置方法

TODO:
      1. 找到打开lcd背光的方法
      2. 阅读lcd的相关寄存器的配置方法,使得lcd可以正常工作

隱形的亼 2022-09-25 11:24:27

DONE:
      1. 今天主要在研究Multi-Function Pin Drive Strength作为fast io的pin的设置,主要是Driver域的设置
      2. 查看了原理图,查看了LCD的连接电路图。

TODO:
      1. 依据原理图和pxa的电气特性来设置Multi-Function Pin Drive Strength的fast io pin的设置
      2. 确认一个最简化的使得lcd能工作的模式。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文