delay timer的wrap around

本文深入解析了TF-A项目中udelay()函数的实现原理,解释了如何通过递减计数器处理时间延迟,并详细说明了在计数值回绕情况下的正确处理方式,确保了延时的准确性。
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 0;
}
 
下面是运行结果:
a(0x20) - b(0x0) = 20
a(0x0) - b(0xe0) = 20
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是一回事。
 
完。

转载于:https://www.cnblogs.com/pengdonglin137/p/10990747.html

<think>好的,我现在需要处理用户关于logicaChannelSR-DelayTimer的查询。首先,我得确认这个术语的具体含义,因为看起来可能是一个特定领域或产品中的组件。用户提到的是“logicaChannelSR-DelayTimer”,可能拼写有误或组合了多个术语。比如,“Logical Channel SR”可能和无线通信中的逻辑信道相关,而“Delay Timer”通常是用于控制某种状态转换的定时器。 接下来,我应该考虑可能的领域,比如LTE、5G或某些工业协议中的配置。在LTE中,逻辑信道用于MAC层,调度请求(Scheduling Request, SR)用于UE请求上行资源。Delay Timer可能与SR的传输间隔或重传机制有关。例如,sr-ProhibitTimer就是用来控制SR重传的时间间隔。 用户可能是在配置这样的定时器时遇到问题,或者需要实现类似的功能。我需要检查3GPP规范,特别是MAC层的相关部分,比如36.321,其中可能涉及SR的配置参数。此外,一些厂商的设备配置指南可能有具体的实现步骤,比如华为或爱立信的文档。 另外,用户可能将“logicaChannelSR”误拼写,正确的可能是“Logical Channel SR”,即与特定逻辑信道关联的调度请求配置。在这种情况下,配置Delay Timer可能涉及设置sr-ProhibitTimer参数,该参数决定了UE在发送SR后需要等待多长时间才能再次发送。 需要验证这些信息是否正确,并查找相关的配置示例或代码片段。例如,在5G NR中,类似的定时器可能称为sr-ProhibitTimer,其取值和配置方式在规范中有详细说明。同时,不同的设备厂商可能有不同的配置命令或界面,需要参考具体设备的文档。 可能还需要考虑用户的具体应用场景,比如是在开发基站、UE模拟器,还是在优化网络性能。不同的场景下,配置和实现Delay Timer的方法可能有所不同。如果用户的问题涉及代码实现,可能需要查看相关的协议栈开源项目,如OAI(OpenAirInterface),看看他们是如何处理SR和定时器的。 最后,生成相关问题,帮助用户深入理解该主题,比如配置参数的影响、优化方法、与其他定时器的交互等。</think>关于logicaChannelSR-DelayTimer的技术实现,根据通信协议领域的技术特征,可能与无线通信系统中的调度请求(Scheduling Request)机制相关。以下是关键实现要素分析: 1. **协议层定位**: 在LTE/NR协议栈中,SR-DelayTimer属于MAC层控制单元,用于管理UE上行调度请求的发送频率。该定时器与逻辑信道优先级绑定,具体参数在RRC层的MAC-MainConfig中配置[^3GPP.36.331]。 2. **定时器工作机制**: 当UE发送SR后立即启动sr-ProhibitTimer,在此定时器超时前禁止再次发送SR。定时器时长通过公式计算: $$ T_{SR-prohibit} = \text{min}(sr-ProhibitTimer \times \text{slotDuration}, 2560ms) $$ 3. **典型配置参数**: ```python # 3GPP 38.321规定的SR配置单元示例 class SchedulerRequestConfig: def __init__(self): self.sr_ProhibitTimer = 4 # 取值1-64对应不同时长 self.sr_TransMax = 8 # 最大重传次数 self.logicalChannelID = 3 # 关联逻辑信道标识 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值