span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-searching {background: #ffa; background: rgba(255, 255, 0, .4);}.cm-force-border { padding-right: .1px; }@media print { .CodeMirror div.CodeMirror-cursors {visibility: hidden;}}.cm-tab-wrap-hack:after { content: ""; }span.CodeMirror-selectedtext { background: none; }.CodeMirror-activeline-background, .CodeMirror-selected {transition: visibility 0ms 100ms;}.CodeMirror-blur .CodeMirror-activeline-background, .CodeMirror-blur .CodeMirror-selected {visibility:hidden;}.CodeMirror-blur .CodeMirror-matchingbracket {color:inherit !important;outline:none !important;text-decoration:none !important;}.CodeMirror-sizer {min-height:auto !important;}
-->
span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; }.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; }.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; }.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; }.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; }.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; }.cm-s-base16-light span.cm-comment { color: #8f5536; }.cm-s-base16-light span.cm-atom { color: #aa759f; }.cm-s-base16-light span.cm-number { color: #aa759f; }.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; }.cm-s-base16-light span.cm-keyword { color: #ac4142; }.cm-s-base16-light span.cm-string { color: #f4bf75; }.cm-s-base16-light span.cm-variable { color: #90a959; }.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }.cm-s-base16-light span.cm-def { color: #d28445; }.cm-s-base16-light span.cm-bracket { color: #202020; }.cm-s-base16-light span.cm-tag { color: #ac4142; }.cm-s-base16-light span.cm-link { color: #aa759f; }.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; }.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; }.cm-s-base16-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
-->
li {list-style-type:decimal;}.wiz-editor-body ol.wiz-list-level2 > li {list-style-type:lower-latin;}.wiz-editor-body ol.wiz-list-level3 > li {list-style-type:lower-roman;}.wiz-editor-body li.wiz-list-align-style {list-style-position: inside; margin-left: -1em;}.wiz-editor-body blockquote {padding: 0 12px;}.wiz-editor-body blockquote > :first-child {margin-top:0;}.wiz-editor-body blockquote > :last-child {margin-bottom:0;}.wiz-editor-body img {border:0;max-width:100%;height:auto !important;margin:2px 0;}.wiz-editor-body table {border-collapse:collapse;border:1px solid #bbbbbb;}.wiz-editor-body td,.wiz-editor-body th {padding:4px 8px;border-collapse:collapse;border:1px solid #bbbbbb;min-height:28px;word-break:break-word;box-sizing: border-box;}.wiz-editor-body td > div:first-child {margin-top:0;}.wiz-editor-body td > div:last-child {margin-bottom:0;}.wiz-editor-body img.wiz-svg-image {box-shadow:1px 1px 4px #E8E8E8;}.wiz-hide {display:none !important;}
-->

TF-A链接:
 
在阅读TF-A源代码时,看到其udelay是实现如下:
 
/***********************************************************
* Delay for the given number of microseconds. The driver must
* be initialized before calling this function.
***********************************************************/
void udelay(uint32_t usec)
{
assert((timer_ops != NULL) &&
(timer_ops->clk_mult != 0U) &&
(timer_ops->clk_div != 0U) &&
(timer_ops->get_timer_value != NULL)); uint32_t start, delta, total_delta; assert(usec < (UINT32_MAX / timer_ops->clk_div)); start = timer_ops->get_timer_value(); /* Add an extra tick to avoid delaying less than requested. */
total_delta =
div_round_up(usec * timer_ops->clk_div,
timer_ops->clk_mult) + 1U; do {
/*
* If the timer value wraps around, the subtraction will
* overflow and it will still give the correct result.
*/
delta = start - timer_ops->get_timer_value(); /* Decreasing counter */ } while (delta < total_delta);
}
 
第16行的get_timer_value返回的是一个从0xFFFFFFFF到0的递减的数,减到0后,再往下减的话,会重新变成0xFFFFFFFF。
其中第25到26行注释说即使发生了wraps around,也可以保证delta的值是正确的。下面我们看看是什么原理。
为此,下面是一个简单的模拟程序,看看发生wraps around后,两个数字相减的结果,假设下面的a,b,c的范围都是从0到0xFF,a表示第一次读到的数,b表示第二次读到的数。
 
#include <stdio.h>

int main(int argc, const char *argv[])
{
unsigned char a, b, c; a = 0x20;
b = 0x00;
c = a - b;
printf("a(0x%x) - b(0x%x) = %x\n", a, b, c); a = 0x00;
b = 0xE0;
c = a - b;
printf("a(0x%x) - b(0x%x) = %x\n", a, b, c); a = 0x00;
b = 0x20;
c = a - b;
printf("a(0x%x) - b(0x%x) = %x\n", a, b, c); a = 0xF0;
b = 0x10;
c = a - b;
printf("a(0x%x) - b(0x%x) = %x\n", a, b, c); return ;
}
 
下面是运行结果:
a(0x20) - b(0x0) =
a(0x0) - b(0xe0) =
a(0x0) - b(0x20) = e0
a(0xf0) - b(0x10) = e0

可以看到,如果是以无符号数输出的话,上面的大数减小数和小数减大数的结果是一样的。

原因是负数在计算机中是以补码的形式存放,关于补码的介绍可以参考:https://baike.baidu.com/item/%E8%A1%A5%E7%A0%81/6854613?fr=aladdin
 
可以直观的理解,在模为10的情况下,一个数加上A,跟减去(10-A)的结果一样:比如 (3 + 8)%10 = 1,而(3-(10-8))%10 = 1,二者一样。
 
或者可以手动计算一下:0 - 0xe0,理论上应该等于-0xe0,那么这个数字在计算机中如何表示呢?也就是-0xe0的补码是多少?根据负数求补码的方法,其绝对值各位取反然后再加1:
-0xe0 --> 0xe(绝对值) --> 0b11100000(二进制表示) --> 0b00011111(取反) --> 0b00100000(加一) --> 0x20,即在模为0x100的情况下,-0xe0跟0x20是一回事。
 
完。

delay timer的wrap around的更多相关文章

  1. java Timer 使用小结

    Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务.这种方式可以让程序按照某一个频度执行,但不能指定时间运行.用的较少. 任务的调用通过起的子线程进 ...

  2. Java Timer及TimerTarsk(摘自网络)

    Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务. 这种方式可以让程序按照某一个频度执行,但不能指定时间运行.用的较少.任务的调用通过起的子线程进 ...

  3. Linux时间子系统之(十七):ARM generic timer驱动代码分析

    专题文档汇总目录 Notes:ARM平台Clock/Timer架构:System counter.Timer以及两者之间关系:Per cpu timer通过CP15访问,System counter通 ...

  4. Linux时间子系统(十七) ARM generic timer驱动代码分析

    一.前言 关注ARM平台上timer driver(clocksource chip driver和clockevent chip driver)的驱动工程师应该会注意到timer硬件的演化过程.在单 ...

  5. 第一次用写一个3d轮播

    2016-07-11gallery  3d html <!doctype html><html lang="en"><head> <met ...

  6. 进程调度函数scheduler_tick()的触发原理:周期PERIODIC定时器

    参考文章: https://www.jb51.net/article/133579.htm https://blog.csdn.net/flaoter/article/details/77509553 ...

  7. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

  8. AFNetworking 3.0 源码解读(九)之 AFNetworkActivityIndicatorManager

    让我们的APP像艺术品一样优雅,开发工程师更像是一名匠人,不仅需要精湛的技艺,而且要有一颗匠心. 前言 AFNetworkActivityIndicatorManager 是对状态栏中网络激活那个小控 ...

  9. [WPF系列]-DataBinding(数据绑定) 自定义Binding

    自定义Binding A base class for custom WPF binding markup extensions BindingDecoratorBase Code: public c ...

随机推荐

  1. eclipse中自动生成serialVersionUID

     serialVersionUID作用:  序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性.       如果你修改代码重新部署后出现序列化错误,可以考虑给相应的类增加seri ...

  2. win10系统:VMware无法在Windows运行该怎么办?

     出现的问题: 解决方法: 点击“检查更新”或去官网下载最新版本 Vmware15.5.0(经过测试发现,Windows 10上面可以运行Vmware15.5.0 ) VMware Workstati ...

  3. 关于Keras 版本的安装与修改

    神经协同过滤(Neural Collaborative Filtering)神作的源码的实验设置要求是: 然而,我们使用控制台 (命令:)或者是PyCharm直接安装的版本均是 最新版本(即 2.0版 ...

  4. SourceTree安装

    SourceTree安装教程 作为程序员,不可避免的要在github上查询代码,而在企业项目中,为了使得项目好管理需要使用项目管理客户端,所以接下来详细讲解一下基于git的sourceTree在win ...

  5. Python 3.X 练习集100题 04

    输入某年某月某日,判断这一天是这一年的第几天? 方法1: import time test_time = input("请输入日期(年-月-日):") time_struct = ...

  6. putty常用配置修改

    1.修改putty默认的颜色方案 初次使用putty时,发现默认的配色的方案看得非常难受,特别是黑色背景,深蓝色的字体,根本看不清楚,下面介绍如何更改默认的配色方案: (1)下载配置文件 首先下载注册 ...

  7. 13. Scala函数式编程(高级部分)

    13.1 偏函数(partial function) 13.1.1 需求 -> 思考 一个集合val list = List(1,2,3,4,"abc"),完成如下要求 1) ...

  8. Python做一个计时器的动画

    一.问题在做连连看的时候需要加一个计时器的动画,这样就完成了计时功能的设计. 二.解决主要思路: 1.先产生一个画布,用深颜色填充满. 2.产生一个新的矩阵用来覆盖画布,背景用白色,就可以渲染出来递减 ...

  9. python turtle画花

    turtle是一个功能强调大的绘图的库,可以用来绘制各种所需要的图案,但是在使用时需要计算好角度等一系列的问题. 代码(源自<Python语言程序设计>)如下: 运行结果:

  10. Java的表达式和运算符

    一.算术运算符 运算符 + - * / % 说明 加 减 乘 除 取模(余数) 例子 1+2 5-3 20*5 6/4 30%9 结果 3 2 100 1 3 int x = 10; int y = ...