Threadx 定时器timer

2023-11-01


Threadx 操作系统定时器提供单次定时和周期性定时功能。定时器由周期性定时中断驱动,每一个定时中断称为一个时钟节拍(tick)。时钟节拍值由系统平台决定,比如5ms一个时钟节拍,需要综合硬件条件和应用需求,系统性能决定。
定时时间长度用时钟节拍个数衡量,比如时钟节拍为5ms,应用程序设置定时时间为1.5s,那么1.5s/5ms=300,调用_tx_timer_create创建定时器时,定时器值设置为300。

定时器管理结构

TX_TIMER为定时器管理结构,包含了TX_INTERNAL_TIMER公共结构。

/* Define the basic timer management structures.  These are the structures
   used to manage thread sleep, timeout, and user timer requests.  */

/* Define the common internal timer control block.  */

typedef  struct TX_INTERNAL_TIMER_STRUCT
{

    /* Define the remaining ticks and re-initialization tick value.  */
    ULONG       tx_remaining_ticks;
    ULONG       tx_re_initialize_ticks;

    /* Need to define remaining ticks, type, next and previous pointers, etc.  */
    VOID (*tx_timeout_function)(ULONG);
    ULONG       tx_timeout_param;


    /* Define the next and previous internal link pointers for active
       internal timers.  */
    struct TX_INTERNAL_TIMER_STRUCT
        *tx_active_next,
        *tx_active_previous;

    /* Keep track of the pointer to the head of this list as well.  */
    struct TX_INTERNAL_TIMER_STRUCT
        **tx_list_head;
    ULONG       os_timer_type;
} TX_INTERNAL_TIMER;
意义
tx_remaining_ticks 定时剩余的节拍数
tx_re_initialize_ticks 周期性定时器节拍数
tx_timeout_function 定时超时处理函数
tx_timeout_param 定时超时函数参数
tx_active_next 指向下一个TX_INTERNAL_TIMER指针
tx_active_previous 指向前一个TX_INTERNAL_TIMER指针
tx_list_head 指向TX_INTERNAL_TIMER头部指针的指针
os_timer_type 定时器类型
/* Define the timer structure utilized by the application.  */

typedef  struct TX_TIMER_STRUCT
{

    /* Define the timer ID used for error checking.  */
    ULONG       tx_timer_id;

    /* Define the timer's name.  */
    CHAR_PTR    tx_timer_name;

    /* Define the expiration routine, parameter, initial expiration, and
       reschedule expiration.  */

    /* Define the actual contents of the timer.  This is the block that
       is used in the actual timer expiration processing.  */
    TX_INTERNAL_TIMER   tx_timer_internal;

    /* Define the pointers for the created list.  */
    struct TX_TIMER_STRUCT
        *tx_timer_created_next,
        *tx_timer_created_previous;
} TX_TIMER;
意义
tx_timer_id 定时器id
tx_timer_name 定时器名字指针
tx_timer_internal 定时器内部公共管理结构
tx_timer_created_next 指向下一个定时器指针
tx_timer_created_previous 指向前一个定时器指针

tx_timer_created_next,tx_timer_created_previous和tx_timer_created_next,tx_timer_created_previous不同,指向管理结构不同。tx_timer_created_next,tx_timer_created_previous用于指向系统定时器结构,tx_timer_created_next,tx_timer_created_previous用于定时器激活链表中指向内部结构TX_INTERNAL_TIMER 。
后面再详解。

定时器链表

定时器_tx_timer_created_ptr用来记录系统中所有创建的定时器,管理结构是TX_TIMER。不论定时器是否激活,只要创建后就插入这个链表。

在这里插入图片描述

定时器激活链表

threadx 定义了_tx_timer_list[TX_TIMER_ENTRIES]定时器激活链表数组,数组元素是指向TX_INTERNAL_TIMER 指针,也就是指向激活链表的头指针。_tx_timer_list数组有32个元素
#define TX_TIMER_ENTRIES 32

/* Define the thread and application timer entry list.  This list provides a direct access
   method for insertion of times less than TX_TIMER_ENTRIES.  */

TIMER_DECLARE TX_INTERNAL_TIMER *_tx_timer_list[TX_TIMER_ENTRIES];


/* Define the boundary pointers to the list.  These are setup to easily manage
   wrapping the list.  */

TIMER_DECLARE TX_INTERNAL_TIMER **_tx_timer_list_start;
TIMER_DECLARE TX_INTERNAL_TIMER **_tx_timer_list_end;


/* Define the current timer pointer in the list.  This pointer is moved sequentially
   through the timer list by the timer interrupt handler.  */

TIMER_DECLARE TX_INTERNAL_TIMER **_tx_timer_current_ptr;

tx_timer_created_next,tx_timer_created_previous用于定时器激活链表中指向内部结构TX_INTERNAL_TIMER
tx_list_head都执行链表中第一个TX_INTERNAL_TIMER 的指针的指针。
在这里插入图片描述

定时器工作原理

1,创建优先级为0定时器线程。
2,所有激活的定时器挂载到定时器激活链表中
3,定时器时钟中断,中断处理函数中唤醒定时器线程
4,定时器线程中检查链表中定时器是否超时,如果超时就回调超时处理函数。处理完后挂起定时器线程,等待下一次中断。

定时器线程创建
在 系统初始化时,_tx_timer_initialize定时器初始函数中创建系统定时器线程,处理函数为_tx_timer_thread_entry。
线程优先级为0,最高优先级,保证定时事件能够最快的响应处理。

   #define TX_TIMER_THREAD_PRIORITY    0       /* Default timer thread priority    */
   
   _tx_thread_create(&_tx_timer_thread, "System Timer Thread", _tx_timer_thread_entry,
                      (ULONG) TX_TIMER_ID,  _tx_timer_stack_start, _tx_timer_stack_size,
                      _tx_timer_priority, _tx_timer_priority, TX_NO_TIME_SLICE, TX_DONT_START);

定时器激活链表维护
定时器激活链表_tx_timer_list有32个元素,从0-31,每个元素指向一个链表,同时也表示节拍计数。
0代表节拍0,1代表节拍1,。。31代表节拍31,_tx_timer_list[0]代表节拍0, _tx_timer_list[0]代表节拍31。
_tx_timer_current_ptr全局指针初始化时指向_tx_timer_list[0], 每一个时钟中断到来,_tx_timer_current_ptr加1,如果到了31,就从0开始,再次指向_tx_timer_list[0]。中断处理函数会判断*_tx_timer_current_ptr是否为空,也就是对应链表是否用激活定时器,如果不为空,就唤醒定时器线程进行处理。
定时器线程,获取*_tx_timer_current_ptr链表中激活定期器,判断激活定时剩余时间是否为0.如果为0,说明超时,调用超时处理函数处理。如果激活定时剩余时间不为0,再次插入tx_timer_list 激活链表中。
如果是周期性定时器,定时器超时处理后,要再次把定时器插入激活链表中。

TX_INTERNAL_TIMER *_tx_timer_list[TX_TIMER_ENTRIES];

/* Define the current timer pointer in the list.  This pointer is moved sequentially
   through the timer list by the timer interrupt handler.  */

TX_INTERNAL_TIMER **_tx_timer_current_ptr;

定时器激活链表插入
定时器激活时,或周期性定时器超时后,需要把定时器TX_INTERNAL_TIMER 再次插入激活链表。
插入_tx_timer_list[TX_TIMER_ENTRIES]中哪一个链表呢?
首先tx_remaining_ticks剩余节拍是否大于32,如果tx_remaining_ticks大于32就从当前节拍开始找到32个节拍中最后一个,也就是(_tx_timer_current_ptr+32)%32 对应的链表:_tx_timer_list[(_tx_timer_current_ptr+32)%32];如果tx_remaining_ticks小于32,就选择(_tx_timer_current_ptr+tx_remaining_ticks)%32对应的链表:_tx_timer_list[(_tx_timer_current_ptr+tx_remaining_ticks)%32]。
也就是大于32时直接从当前开始找到最后一个(加32)个链表,因为至少需要32个节拍,定时器也不会超时,所以放到最后一个,在每个时钟中断到来时判断*_tx_timer_current_ptr为空时,不用唤醒定时器线程,减少了线程切换开销。
总之使用数组+链表方式,为了减少系统开销。只有当前节拍对应数组链表不为空时,才唤醒线程。

当前节拍下对应数组链表不为空时,线程被唤醒处理,但并不代表定时已经超时,tx_remaining_ticks不一定为0,至少过了32个节拍周期,需要重新把定时器重新计算合适位置插入链表。如何设计能够减少这种无效唤醒呢?

激活链表按照先进先出FIFO原则处理,并没有优先级属性。

在这里插入图片描述
在这里插入图片描述

定时器API

函数 描述
tx_timer_create 创建定时器
tx_timer_delete 删除定时器
tx_timer_activate 激活定时器
tx_timer_deactivate 去激活定时器
tx_timer_change 修改定时器定时值
tx_timer_info_get 获取定时信息

定时器创建_tx_timer_create

参数 意义
timer_ptr 指向创建定时器的指针
name_ptr 指向定时器名字字符串指针
expiration_function 定时器超时处理函数
expiration_input 定时器超时处理函数参数
initial_ticks 定时器第一次定时值
reschedule_ticks 定时器重启定时值
auto_activate 定时器自动激活标志

定时器超时后会回调函数expiration_function;
激活定时器后第一次超时时间为initial_ticks,如果reschedule_ticks不为0,使用reschedule_ticks作为定时器值重新激活定时器,后续一直使用reschedule_ticks作为定时器值。
auto_activate为true时表示创建定时器并激活定时器,否则需要单独调用tx_timer_activate激活定时器。
把定时器timer_ptr插入_tx_timer_created_ptr链表

UINT    _tx_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr,
                         VOID (*expiration_function)(ULONG), ULONG expiration_input,
                         ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate)
{

    TX_INTERRUPT_SAVE_AREA

    TX_TIMER        *tail_ptr;                  /* Working timer pointer      */


    /* Setup the basic timer fields.  */
    #def 保持初始化值
    timer_ptr -> tx_timer_name =                            name_ptr;
    timer_ptr -> tx_timer_internal.tx_remaining_ticks =     initial_ticks;
    timer_ptr -> tx_timer_internal.tx_re_initialize_ticks = reschedule_ticks;
    timer_ptr -> tx_timer_internal.tx_timeout_function =    expiration_function;
    timer_ptr -> tx_timer_internal.tx_timeout_param =       expiration_input;
    timer_ptr -> tx_timer_internal.tx_list_head =           TX_NULL;
    timer_ptr -> tx_timer_internal.os_timer_type = OS_TIMER_TYPE_REL;

    /* Disable interrupts to put the timer on the created list.  */
    #def 禁止中断,禁止中断后,下面代码不会被中断或其它线程打断。处理全局变量
    TX_DISABLE

    /* Setup the timer ID to make it valid.  */
    timer_ptr -> tx_timer_id =  TX_TIMER_ID;

    /* Place the timer on the list of created application timers.  First,
       check for an empty list.  */
     #def 定时器插入_tx_timer_created_ptr列表
    if (_tx_timer_created_ptr)
    {

        /* Pickup tail pointer.  */
        tail_ptr =  _tx_timer_created_ptr -> tx_timer_created_previous;

        /* Place the new timer in the list.  */
        _tx_timer_created_ptr -> tx_timer_created_previous =  timer_ptr;
        tail_ptr -> tx_timer_created_next =                   timer_ptr;

        /* Setup this timer's created links.  */
        timer_ptr -> tx_timer_created_previous =  tail_ptr;
        timer_ptr -> tx_timer_created_next =      _tx_timer_created_ptr;
    }
    else
    {

        /* The created timer list is empty.  Add timer to empty list.  */
        _tx_timer_created_ptr =                   timer_ptr;
        timer_ptr -> tx_timer_created_next =      timer_ptr;
        timer_ptr -> tx_timer_created_previous =  timer_ptr;
    }

    /* Increment the number of created timers.  */
    _tx_timer_created_count++;

    /* Restore interrupts.  */
    TX_RESTORE

    /* Determine if this timer needs to be activated.  */
    if (auto_activate)
		#def 如果设置了auto_activate标志,激活定时器
        /* Call actual activation function.  */
        _tx_timer_activate(&(timer_ptr -> tx_timer_internal));

    /* Return TX_SUCCESS.  */
    return (TX_SUCCESS);
}

删除定时器_tx_timer_delete

删除定时器,清除一些相关数据结构,从_tx_timer_created_ptr 链表中删除定时器。

UINT    _tx_timer_delete(TX_TIMER *timer_ptr)
{

    TX_INTERRUPT_SAVE_AREA


    /* Determine if the timer needs to be deactivated.  */
    #def 定时器在激活链表中,说明已经激活,去激活
    if (timer_ptr -> tx_timer_internal.tx_list_head)

        /* Yes, deactivate the timer before it is deleted.  */
        _tx_timer_deactivate(&(timer_ptr -> tx_timer_internal));

    /* Disable interrupts to remove the timer from the created list.  */
    TX_DISABLE

    /* Decrement the number of created timers.  */
    _tx_timer_created_count--;

    /* Clear the timer ID to make it invalid.  */
    #def 设置定时器为无效
    timer_ptr -> tx_timer_id =  0;
	#def 从_tx_timer_created_ptr 移除定时器
    /* See if the timer is the only one on the list.  */
    if (timer_ptr == timer_ptr -> tx_timer_created_next)
    {

        /* Only created timer, just set the created list to NULL.  */
        _tx_timer_created_ptr =  TX_NULL;
    }
    else
    {

        /* Link-up the neighbors.  */
        (timer_ptr -> tx_timer_created_next) -> tx_timer_created_previous =
            timer_ptr -> tx_timer_created_previous;
        (timer_ptr -> tx_timer_created_previous) -> tx_timer_created_next =
            timer_ptr -> tx_timer_created_next;

        /* See if we have to update the created list head pointer.  */
        if (_tx_timer_created_ptr == timer_ptr)

            /* Yes, move the head pointer to the next link. */
            _tx_timer_created_ptr =  timer_ptr -> tx_timer_created_next;
    }

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return TX_SUCCESS.  */
    return (TX_SUCCESS);
}

修改_tx_timer_change

修改定时器定时initial_ticks值和reschedule_ticks值,定时器去激活状态才能修改。

UINT    _tx_timer_change(TX_TIMER *timer_ptr, ULONG initial_ticks, ULONG reschedule_ticks)
{

    TX_INTERRUPT_SAVE_AREA


    /* Disable interrupts to put the timer on the created list.  */
    TX_DISABLE

    /* Determine if the timer is active.  */
    #def 定时器不在激活链表,没有激活;tx_list_head指向激活链表头部
    if (!(timer_ptr -> tx_timer_internal.tx_list_head))
    {

        /* Setup the new expiration fields.  */
        timer_ptr -> tx_timer_internal.tx_remaining_ticks =     initial_ticks;
        timer_ptr -> tx_timer_internal.tx_re_initialize_ticks = reschedule_ticks;
    }

    /* Restore interrupts.  */
    TX_RESTORE

    /* Return TX_SUCCESS.  */
    return (TX_SUCCESS);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Threadx 定时器timer 的相关文章

  • 手写RTOS-PendSV中断

    今天这一篇 xff0c 我们说一下操作系统都要用到的PendSV中断 xff0c 整个操作系统中 xff0c 要自己写的的汇编代码不超过20行 xff0c 全部都在PendSV中断里 以下是 Cotex M3权威指南 里对PendSV的描述
  • 【RTOS的最通俗理解】行业大佬用一篇文章带你快速理解RTOS

    文章目录 单片机 RTOS 架构 1 RTOS的概念 1 1 用人来类比单片机程序和RTOS 1 1 1 我无法一心多用1 2 2 我可以一心多用 1 2 程序简单示例 2 架构的概念 2 1 用人来类比电子产品2 2 要深入理解RTOS就
  • 玩RTOS这么久,一问原子操作,蒙了~

    已剪辑自 https mp weixin qq com s kvxcOHT xHtMAjQqJu7Y2g 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img C3f9Rrei 1668695258073 https
  • stm32f103c8移植Free RTOS遇到的bug和解决措施

    一 SVC系统调度错误 1 现象 xff1a 进入不了task 2 解决措施 xff1a xff08 1 xff09 将stm32f1xx it c里的void SVC Handler xff08 void xff09 函数给注释了 原因
  • RTOS流和消息缓冲器

    RTOS流和消息缓冲器 任务间通信和同步 可从FreeRTOS V10 0 0获得 介绍 流缓冲区是 RTOS任务 的RTOS任务 xff0c 并且是任务通信原语的中断 与大多数其他FreeRTOS通信原语不同的是 xff0c 它们针对单读
  • 手写RTOS(课程回顾)

    什么是程序 X86 X86在调用函数的时候传递在参数是从栈中取出的 xff0c 需要哪些参数提前按一定顺序入栈即可 第一个出栈的就对应第一个参数 xff0c 依次类推 函数返回值存在eax中 ARM arm函数调用参数传递顺序是从r0 r3
  • 基于Cortex-M的RTOS上下文切换详解及FreeRTOS实例

    文章目录 1 Cortex M MCU特性 1 1 操作模式 1 2 寄存器 1 2 1 核心寄存器 1 2 2 浮点寄存器 Floating Point registers 1 2 3 特殊寄存器 Special Registers 1
  • 【01】初识ThreadX

    目录 简介 微内核 资料链接 入门索引 简介 ThreadX是一个成熟的商用硬实时嵌入式操作系统 xff0c 被广泛应用于消费电子 航空航天 通信 工业控制与医疗等应用领域中 xff0c 至今已服务超过62亿设备 它以轻量级的规模 xff0
  • RTOS论文笔记(二)

    李在林 韩宏克 嵌入式Linux实时性分析及改造 2010 Linux 的实时性测试 中断延迟测试 在Linux中 xff0c 内核或驱动程序显式地关 开中断 xff0c 一般是通过调用 cli sti 来进行操作的 在调用 cli 时 x
  • Zephyr-环境搭建

    目录 1 前言 2 安装主机依赖 3 获取源码 4 安装工具链 5 编译一个Demo 1 前言 Zephyr支持Ubuntu macOS Windows环境下开发 本文介绍基于Ubuntu的环境搭建 包括 Ubuntu开发环境搭建 主要是工
  • RT-Thread uart2串口dma idle接收不断帧

    硬件STM32F407 IDE使用RT Thread Studio uart2串口使用这两个引脚 功能 IO端口 UART2 TX PA2 UART2 RX PA3 UART2 DMA接收配置 先使能DMA接收 RX缓冲区可以稍微调大些 b
  • Azure RTOS定价(ThreadX 等)

    Azure RTOS定价 Azure RTOS定价 https azure microsoft com zh cn pricing details rtos 使嵌入式 IoT 开发和连接变得轻松 Azure RTOS 是一种易于使用 经过市
  • PlatformIO - 静态代码分析(Static Code Analysis)

    关于 静态代码分析 相信大部分的嵌入式开发者或多或少在日常的开发中都有所了解 但可能在实际的开发中我们使用的并不多也不习惯通过工具对我们编写的代码进行静态扫描而是完全依赖于在开发板上运行然后基于运行结果来判断自己所编写的代码的好坏 是否有b
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 将 DKM 项目链接到内核映像 (VIP) 项目作为 VxWorks Workbench4 中的子项目/额外模块

    如何将 DKM 项目与内核映像 VIP 项目链接 加载 以便我可以从内核映像项目的 usrAppInit c 调用 DKM 项目 应用程序 的入口点函数 以在启动时自动启动应用程序 有人可以描述步骤或向我指出任何文档吗 将 DKM 项目添加
  • RT-Thread 内核基础(六)

    RT Thread内核配置示例 RT Thread的一个重要特性是高度可裁剪性 支持对内核进行精细调整 对组件进行灵活拆卸 配置主要是通过修改工程目录下的rtconfig h文件来进行 用户可以通过打开 关闭该文件中的宏定义来对代码进行条件
  • RT-Thread 内核基础(四)

    自动初始化机制 自动初始化机制是指初始化函数不需要被显示调用 只需要在函数定义处通过宏定义的方式进行申明 就会在系统启动过程中被执行 例如在串口驱动中调用一个宏定义告知系统初始化需要调用的函数 代码如下 int rt hw usart in
  • RT-Thread 内核基础(五)

    使用static修饰全局变量作用 限制作用域 如果全局变量前面加上 static 关键字 那么该变量的作用域将被限制在声明它的源文件中 即它将成为一个文件作用域的静态变量 其它源文件无法访问这个变量 这对于控制变量的可见性和避免命名冲突是有
  • 线程堆栈指针

    在Linux 2 6 32 32中 有没有一种方法可以在a中以编程方式查找有关线程的以下信息pthreads程序 我需要 运行计数 堆栈指针 堆栈开始 结束 堆栈大小 堆栈使用情况 我猜是类似 ThreadX 的东西 但在程序中 谢谢 pt

随机推荐

  • 计图:5秒训好NeRF!已开源

    金磊 转载整理自 图形学与几何计算量子位 公众号 QbitAI 计图 Jittor 框架的NeRF模型库JNeRF正式开源了 通过JNeRF可以5秒训练好NeRF模型 见图1 Jittor成为首个支持Instant NGP的深度学习框架 图
  • 实时车道线检测和智能告警

    导读 车道线检测 距离告警 转弯曲率半径计算 代码 https github com MaybeShewill CV lanenet lane detection 来自模型的车道线预测 介绍 自动驾驶将在未来十年给旅行带来革命性的变化 目前
  • 揭秘:谷歌是如何考核员工的?看看他们的OKR制度

    谷歌一直给人具有创新精神和人文关怀的公司 但其内部考评制度的曝光让人觉得 谷歌员工的压力也不小 谷歌还是小规模初创公司时 就开始使用一个叫做 目标和关键成果 Objectives and Key Results OKR的内部员工考核制度 O
  • git pull 与 git push 区别

    git pull 与 git push 区别 结论先行 1 git pull git fetch git merge 2 git fetch 只会将本地库所关联的远程库commit ID 更新到最新 3 git pull 将本地库所关联的远
  • ubuntu怎么关防火墙

    1 关闭ubuntu的防火墙 ufw disable2 卸载了iptables apt get remove iptables1 用iptables F这个命令来关闭防火墙 但是使用这个命令前 千万记得用iptables L查看一下你的系统
  • 【Qt】使用Qss设置QPushButton图标和显示文本的位置

    使用Qss设置QPushButton图标和显示文本的位置 一 背景 在开发中 经常使用到按钮作为一种输入部件 然而很多时候按钮又有不同的开发设计需求 本文重点分享 如何使用Qss来设置按钮的图标和按钮文本的位置 从而实现预期的开发效果 效果
  • ARouter(四) _ARouter类

    相对于ARouter类 ARouter类是真正内部开始做事的类 这里重点讲几个方法的作用 1 inject 方法 static void inject Object thiz AutowiredService autowiredServic
  • JS 循环发起请求

    写在前面 要求是等上一个请求完毕之后 再发起下一个请求 一般用不到 写的时候 发现forEach不行 得用for 注 我这里用setTimeOut与promise去模拟请求 步骤1 先写一个模拟请求的方法 function simulati
  • 配合小皮系统搭建Droabox靶场

    什么你还不会搭建 教你两招 无需使用命令行 即可搭建 一 将下载好的哆啦盒放进小皮系统的WWW目录下 二 启动小皮数据库 创建一个数据库 设置密码及用户 三 导入在哆啦盒文件下的pentest sql 四 打开刚刚放进小皮系统WWW目录下的
  • 前端若依框架路由跳转报错 Error: Cannot find module “@/views/xxx/xxx/xxx“

    前言 前端代码打包dist文件之后 部署后发现只有首页可以显现 然后跳转路由没生效 控制台报错 Error Cannot find module views xxx xxx xxx 原因 webpack4 不支持变量方式的动态 import
  • 十进制浮点数转成二进制(IEEE 754 在线计算器)

    IEEE 754 单精度浮点数转换 在线计算器 http www styb cn cms ieee 754 php 十进制小数的二进制表示 整数部分 除以2 取出余数 商继续除以2 直到得到0为止 将取出的余数逆序 小数部分 乘以2 然后取
  • [多尺度物体目标检测]技术概述/综述

    目录 1 绪论 1 1 引言 1 2 研究背景 1 3 研究意义 1 4 目前存在的问题 2 传统目标检测方法 2 1 HOG SVM 2 1 1 简介 2 1 2 检测流程 2 2 DPM 2 2 1 简介 2 2 2 检测流程 3 基于
  • C++拷贝构造器(Copy contructor)

    定义 由己存在的对象 创建新对象 也就是说新对象 不由构造器来构造 而是由拷贝构造器来完成 拷贝构造器的格式是固定的 class 类名 类名 const 类名 another 拷贝构造体 classA A const A another 规
  • 题目 1041: [编程入门]宏定义之找最大数

    分别用函数和带参的宏 从三个数中找出最大的数 输入格式 3个实数 输出格式 最大的数 输出两遍 先用函数 再用宏 保留3位小数 样例输入 复制 1 2 3 样例输出 复制 3 000 3 000 核心解法 我的是用三目运算符 int Max
  • feign的加解密封装

    功能描述 通过覆盖 feign codec Encoder 和 feign codec Decoder 实现 feign 请求的加解密操作 采用动态的 feignClient 调用 平台统一的通信加解密策略 同一个服务节点可以同时使用非加密
  • C++基础知识 - 类模板与静态数据成员

    类模板与静态数据成员 include
  • AUTOSAR汽车电子嵌入式编程精讲300篇-基于AUTOSAR架构的AT控制系统研究与实现

    目录 前言 国内外研究现状 国外研究现状 国内研究现状 2 AUTOSAR规范及开发流程
  • vscode clang-format不生效

    问题 ubuntu下clang format不生效 解决方法 全局搜setting json 看着哪个像 找到对应的设置文件 我的是 config Code User settings json 里面改成 editor formatOnSa
  • Redis事务——锁机制

    1 redis事务定义 1 redis事务是一个单独隔离的操作 事务中所有操作都会按顺序进行执行 事务操作过程中 不会被其他客户端发送来到命令打断 2 redis事务是将命令进行串联操作 防止有其他命令插队 2 事务执行流程 如下图 1 m
  • Threadx 定时器timer

    文章目录 定时器管理结构 定时器链表 定时器激活链表 定时器工作原理 定时器API 定时器创建 tx timer create 删除定时器 tx timer delete 修改 tx timer change Threadx 操作系统定时器