使用weak(弱函数)构建跨平台的C语言代码

嵌入式电子 2023-05-23 22:14


弱符号

弱符号是指在定义或者声明一个对象(变量、结构体成员、函数)时,在对象的前面添加 __attribute__((weak)) 标志所得到的对象符号。如下所示函数即为一个弱对象符号 void test_weak_attr(void),或者称该函数是弱函数属性的、虚函数。

__attribute__((weak)) void test_weak_attr(void)// 或者使用如下样式的定义,两者等效void __attribute__((weak)) test_weak_attr(void){    printf("Weak Func!\r\n");}


弱符号的作用与示例

弱符号是相对于强符号而言的,在定义或者声明变量、函数时,未添加 __attribute__((weak)) 标识的就默认为强符号。如下,最普通的函数定义,就是定义了一个强符号 void test_strong_ref(void):

void test_weak_attr(void){    printf("this is a strong func\r\n");}

驱动程序往往需要考虑兼容性,因为要兼任很多厂商的不同型号的设备。若驱动程序中使用强符号定义一些与适配的设备的特性相关的功能,则下次适配其他设备时,该强符号函数可能需要被修改,以兼容新的设备。当适配的设备很多时,频繁地更改驱动代码将破坏驱动的可维护性。

弱符号的出现可以很好地解决该问题。弱符号的对象具有可以被重定义的功能(即可以被重载)。下面通过测试说明弱符号这种可被重载的特性。

在 test_weak_attr.c 程序中定义如下弱函数:

// test_weak_attr.c#include  __attribute__((weak)) void test_weak_attr(void){    printf("this is a weak func\r\n");}

在 main.c 中定义如下程序:

// main.cvoid test_weak_attr(void){    printf("this is a strong func\r\n");} void app_main(void){    printf("init done\r\n");         test_weak_attr();}

编译运行该 main.c 程序,得到的结果是什么样子的呢?

1

this is a strong func

将 main.c 中的 void test_weak_attr(void) 函数注释掉,再重新编译运行程序得到的结果是:

1

this is a weak func

小结:在使用弱符号函数时,我们可以重新定义一个同名的强符号函数来替代它;若没有重新定义一个强函数来替换它,就使用弱函数的实现。弱函数就好像是一个可以被替换的“默认函数”。

值得一提的是,旧版本的编译器还可以使用如下方式的定义(仅声明无效)将一个对象定义为一个弱对象:

1

2

3

4

__weak void f(void)

{

//code

}

在 linux 的一些代码中,__weak 其实就是通过 __attribute__((weak))的重命名,两者等效。

弱引用

弱引用是在声明一个对象时,通过__attribute__ ((weakref()) 定义一个符号的引用关系。如下所示即定义 test_weakref() 函数弱引用 test_weak_ref() 函数。

1

static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));

弱引用是相对于强引用而言的。未通过 __attribute__ ((weakref()) 的符号和实现代码之间的关系是强引用。如下即为一个强引用函数。它直接给出了 函数 test_strong_ref(void) 的实现。

1

2

3

4

static void test_strong_ref(void)

{

    printf("this is a strong ref\r\n");

}

在编译程序的时候,我们可以直接使用 test_strong_ref(void) 而不必担心编译不通过。如果,我没有时间去实现 test_strong_ref(void) ,还想在程序里先使用该函数那该如何呢?(是的,就是想白嫖,不想实现,还想先在程序里使用这个函数)。

这个时候弱引用就派上用场了。可以先将该函数定义为弱引用插入到代码中,待后期有时间再慢慢优化代码实现这个函数完整的功能。下面结合测试进行说明。

测试代码1:

static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));void app_main(void){    printf("init done\r\n");    if (test_weakref) {        test_weakref();    } else {        printf("There is no weakref\r\n");    }}

测试结果:

There is no weakref

测试代码2:

void test_weak_ref(void){    printf("this is a weak ref\n");}static void test_weakref(void) __attribute__ ((weakref("test_weak_ref")));void app_main(void){    printf("init done\r\n");    if (test_weakref) {        test_weakref();    } else {        printf("There is no weakref\r\n");    }}

测试结果:

this is a weak ref

小结:强引用,在未定义该强引用的实现时,编译会报错误:未定义的引用。弱引用允许定义一个未实现(未实例化)的对象,这在编译的时候会将该对象处理成 NULL,编译器并不会报错。通过使用弱引用可以实现后期优化代码的功能。而避免改动使用该函数的地方。使用弱函数可以实现类似“钩子(hook)"函数的功能。

实际上,包括C、python、go 编程语言在内的很多语言 都有类似用法,本篇文章叙述的方法同样适用于这些语言的相关开发。

注意:弱引用仅在静态编译中有效,动态链接中可能无效。

总结:

弱符号、弱引用都是增强程序的可维护性的方法。弱符号通过可以被重定义的特性,实现可以被替换实现。弱引用通过可以暂时使用一个未定义的函数的功能,实现允许后期再实现该函数具体功能,而不必担心编译不通过。

为了方便理解,我们先预设一个应用场景:

我们编写了一个模拟IIC的驱动,希望它能够在不同的的平台运行,目标的平台就设为 stm32 标准库,stm32 HAL 库,stm32 LL 库,和 RT-Thread Driver 驱动库。

或许读者有疑惑,为什么同样是 stm32 ,却分成三个平台呢?这是因为从跨平台软件编写者的角度看,只要调用的库的 API 不一致,就和换一个不同的平台没有什么本质的差别,如果在代码中写死了 API 的调用,即使是同一个平台,仍然像多平台一样不能运行。

由此可以看出,跨平台的困难所在,也不是由硬件平台所导致的,而是由代码所依赖的 API 的不同导致的。同一个平台,如果依赖的 API 不同,代码就不能跨平台,同样地,不同的平台,如果依赖的 API 相同,也可以跨平台。

所以归根结底,是代码所依赖的 API 出现了不同,所以下文中所说的“平台”,实际上对应的是一套 API 。

我们继续说这个模拟 IIC 的驱动,模拟 IIC 驱动是使用 GPIO 的反转来模拟 IIC 协议,所以依赖了平台的 GPIO API,如果把调用 GPIO 的部分写死,那么换一个平台,就肯定不能在多个平台上运行。

下面我们开始讨论在多平台运行的解决方案。

我们先从最朴素简单的解决方案开始,然后逐步迭代到弱函数的方案,这样有两方面好处:

一是从简单的方案开始,循序渐进地介绍,可以降低阅读门槛。
二是可以带读者亲历一遍方案的演进过程,以及演进动因。

和给直接给结果相比,注重过程和动因更能够还原技术决策的真实过程。因为任何技术都是从简单朴素逐步演进而来的,如果直接给出最后的结果,会产生理解的断层,即使记住了几种技术的优劣,在新的场景中,面对更加多样化的实际问题也会难免乏力。

先从最朴素的方案讲起。

方案一、手动控制添加编译的 .c 文件

朴素的方案有很多,比如就是多搞几个版本的 .c 文件,比如SIMU_IIC_STM32_HAL.c ,SIMU_IIC_STM32_LL.c, SIMU_IIC_RTT.c 需要哪个就添加哪个进去编译不就完了嘛!

这种朴素的方案虽然看起来简单,但是,这几个文件中包含有共用的逻辑,例如模拟 IIC 的协议的实现,如何将 8bit 的数据依次发送,等等。

这些共用的逻辑,相当于在每个文件中都复制了一份,一旦修改到共用的逻辑,就要手动同步每个文件,这会导致代码冗余和维护难度的急剧增加,很容易出现人为失误。如果需要添加更多的平台支持,就需要再次复制修改代码。

另一个问题是,使用不同的编译工具链,添加编译文件的方式并不一样,例如,Visual Studio 和 MDK keil 通常是手动添加,而 CMake 通常直接添加目录或者通过文件后缀进行搜索。用户在使用不同的编译工具时,需要针对编译工具来分别处理,这也增加了维护的成本。

因此,我们需要寻找更加优雅的解决方案。

方案一中最核心的问题,是没有分离共用的逻辑,和各个平台的适配接口。
在通常的命名惯例中,共用的逻辑称为 Common,而各个平台的适配接口称为 Port。

在接下来的方案中,我们就会引入 Common 和 Port 分离的设计思想,Common 和 Port 的分离,使得对共用逻辑的修改和增强直接 “分发” 到了各个的 Port 中,而增添新的平台,不需要对 Common 做任何修改。

方案二、条件编译

一种更加优雅的解决方案是使用条件编译。条件编译是一种编译时根据条件选择编译代码的技术,可以通过编译器提供的宏定义和预处理指令来实现。

在我们的模拟 IIC 驱动中,可以直接编写 Common 部分,然后 Common 部分通过条件编译,可以根据平台的不同选择不同的 GPIO Port API。

例如,在 STM32 标准库中,可以使用 GPIO_SetPinMode 和 GPIO_WritePin 接口来模拟 IIC 协议,而在 STM32 HAL 库中,可以使用 HAL_GPIO_WritePin 和 HAL_GPIO_ReadPin 接口来模拟 IIC 协议。因此,在代码中可以使用如下的条件编译方式:

#if defined (USE_STM32_STD_LIB)    /* STM32 Standard Peripheral Library */    GPIO_SetPinMode(SDA_PORT, SDA_PIN, GPIO_MODE_OUTPUT_PP);    GPIO_SetPinMode(SCL_PORT, SCL_PIN, GPIO_MODE_OUTPUT_PP);    ...#elif defined (USE_STM32_HAL_LIB)    /* STM32 HAL Library */    HAL_GPIO_WritePin(SDA_PORT, SDA_PIN, GPIO_PIN_SET);    HAL_GPIO_WritePin(SCL_PORT, SCL_PIN, GPIO_PIN_SET);    ...#elif defined (USE_STM32_LL_LIB)    /* STM32 LL Library */    LL_GPIO_SetOutputPin(SDA_PORT, SDA_PIN);    LL_GPIO_SetOutputPin(SCL_PORT, SCL_PIN);    ...#elif defined (USE_RTT_DRIVER)    /* RT-Thread Driver */    rt_pin_mode(SDA_PIN, PIN_MODE_OUTPUT);    rt_pin_mode(SCL_PIN, PIN_MODE_OUTPUT);    ...#endif

这样,在编译代码时,我们可以通过宏定义来选择编译使用哪个平台的代码,

从而实现跨平台运行。

然而,这种条件编译方式还是有一些问题,如果我们需要添加新的平台支持,就需要添加新的宏定义和条件编译,而且需要修改模块的源码。

方案三 函数指针

我们可以进一步分离 Common 和 Port,将其放在不同的 .c 文件中,Common 通过函数调用的方式来访问 Port 提供的接口,这样可以更加灵活和方便地添加新的平台支持。

具体实现可以通过在 Common 中定义一些函数指针类型来实现。

例如,我们可以定义一个名为 IICOps 的结构体,其中包含了一些指向函数的指针,这些函数实现了具体的 IIC 操作。

在 Port 中,我们实现这些函数,并将其指针传递给 Common 中的 IICOps 结构体。

这样,在 Common 中就可以通过调用这些函数指针来访问 Port 提供的接口了。

这种方案的好处是,添加新的平台支持时,只需要实现相应的 Port 函数,并将其指针传递给 Common 中的结构体即可,不需要修改 Common 的源码。

同时,由于 Common 和 Port 分离,不同平台的适配代码可以相互独立,修改一方不会影响到另一方,从而减少了代码冗余和维护难度。

但是,使用函数指针有两个主要的缺点,一是函数指针本身需要占据内存,增加了内存的开销,二是函数指针需要在初始化时进行加载。

具体来说,函数指针的内存开销相对于代码本身并不大,通常可以忽略不计,但在嵌入式系统中,资源有限,内存开销需要更加注意。

而函数指针的初始化需要在程序启动时进行,这也会对程序的启动时间产生一定的影响。此外,函数指针的使用可能会导致一定的运行时开销,需要在程序性能和资源利用方面做出权衡。

另外,函数指针的使用需要程序员有一定的技术水平和经验,需要合理地进行函数指针的定义、传递和调用等操作,避免出现潜在的错误和安全问题。

总的来说,函数指针是一种比较灵活和方便的方式,可以帮助我们实现代码的跨平台支持,但需要在实际应用中仔细考虑其使用场景和影响,做出合理的决策。

方案四、Common 中声明,Prot 中实现

在这种方案中,我们仍然将 Common 和 Port 分离,但是我们不再使用函数指针来访问 Port 中的接口,而是将其定义为 extern 声明,由 Port 来实现具体的函数。

具体实现可以通过在 Common 中定义一些 extern 声明的函数,这些函数实现了具体的 IIC 操作,但是并不在 Common 中实现具体的代码逻辑,而是在 Port 中实现。

在 Port 中,我们实现这些函数,并将其声明为 extern,然后在编译时链接到 Common 中。

这样,在 Common 中就可以通过调用这些函数来访问 Port 提供的接口了。

这种方案的好处是,添加新的平台支持时,只需要实现相应的 Port 函数,并在编译时链接到 Common 中即可,不需要修改 Common 的源码。

这样 Port 的实现函数的挂载就提前到了编译阶段,避免了运行时挂载函数指针的复杂性和容易出错问题。以及避免了函数指针的内存占用。

但是,和 IIC 的例子不同的是,在一些更实际的项目中,随着软件复杂度的提升, Common 中使用的 Port 函数数量会快速膨胀,这时,每个 Port 函数都必须要实现,即使这个功能非常的冷门,这样 Common 中每增加一个 Port 的依赖,都要求所有的 Port 进行及时的跟进,否则整个项目都无法编译通过。

接下来,就要有请 weak (弱函数)机制出马了

但方案四的缺点在于,在一些更实际的项目中,随着软件复杂度的提升,Common 中使用的 Port 函数数量会快速膨胀,这时,每个 Port 函数都必须要实现,即使这个功能非常的冷门,这样 Common 中每增加一个 Port 的依赖,都要求所有的 Port 进行及时的跟进,否则整个项目都无法编译通过。

方案五 弱函数

为了解决这个问题,可以使用 weak (弱函数)机制,将所有的 Port 函数都定义为 weak 函数。

weak 函数是一种特殊的函数类型,带 weak 的函数和不带 weak 的函数可以同时存在,如果有不带 weak 的函数,就会优先链接不带 weak 的实现,如果没有找到不带 weak 的实现函数,就会使用 weak 函数作为默认的实现。

即,在使用弱函数时,如果找到多个实现,链接器会选择优先级最高的实现。

在 C 语言中,可以使用 attribute((weak)) 来声明一个函数为弱函数。例如:

attribute((weak)) void port_func(){    // 默认实现}attribute((weak)) void port_func()

而在 Port 中,只需要实现需要的函数即可,如果某些函数不需要实现,可以不用管它,因为在链接时会使用 Common 中的默认实现。

这样在编译时如果没有找到相应的实现函数,就会使用默认的实现,而不会导致编译错误。

而在 Port 中,只需要实现需要的函数即可,如果某些函数不需要实现,可以不用管它,因为在编译时会使用 Common 中的默认实现。

这样,在添加新的平台支持时,只需要实现需要的函数,而不用实现所有的函数,大大简化了开发的难度和工作量。同时,也避免了函数指针的内存占用和运行时挂载函数指针的复杂性和容易出错问题。

弱函数的多编译器支持

在不同的平台上, weak 的声明方法也会有所不同,因此需要自己定义一个 weak 声明,例如 MY_WEAK,来支持不同的平台:

/* Compiler */#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 5000000) /* ARM Compiler \                                                              */#define MY_WEAK __attribute__((weak))#elif defined(__IAR_SYSTEMS_ICC__) /* for IAR Compiler */#define MY_WEAK __weak#elif defined(__MINGW32__) /* MINGW32 Compiler */#define MY_WEAK#elif defined(__GNUC__) /* GNU GCC Compiler */#define MY_WEAK __attribute__((weak))#endif/* default MY_WEAK */#ifndef MY_WEAK#define MY_WEAK#endif

可以看到,在不同的编译器下,weak 有不同的写法,上面的这些定义包含了对 armcc5、 armclang、IAR、GCC 的支持。

然而,弱函数的方案在一些平台有一些明显的缺陷,例如,MSVC编译器是微软公司开发的C/C++编译器,在Windows操作系统下被广泛使用。与GCC和Clang等主流编译器相比,MSVC对于弱函数的支持不太完善。

MSVC 中,可以通过使用#pragma weak来声明弱函数,但是这个特性只能在 x86 和 x64 平台下使用,而在 ARM 平台下是不支持的。

此外,在一些版本的MSVC编译器中,#pragma weak 的功能也存在一些限制和bug,所以一般在 MSVC 中直接取消 weak 还会更实际一些。

用弱函数对 Port 进行分类

weak 的引入使得我们的 Port 可以根据实际的需求进行划分,而不是一股脑地必须实现所有的 Port 函数。

引入了 weak 之后,我们就有条件将 Port 划分为以下的几种:

1.核心且无默认实现的 Port

这属于必须实现的 Port,缺乏这个 Port,模块的核心功能就运行不起来。例如模拟 IIC中对 IO 的操作 Port 函数,这种 Port 用不用 weak 的区别不大,属于最硬的骨头,在设计软件时应当注意尽可能地减少这种 Port。

在设计软件时,可以直接取消这类 Port 的弱定义,让编译器在编译时就抛出错误。既然缺少了这类 Port 系统的核心功能就无法工作,那么编译通过了也没有什么意义。

2. 核心且有默认实现的 Port

这类 Port 可以直接定义一个默认实现,在大多数情况下,用户就可以不用管这个 Port 了,而在有定制需求的场合下,又可以灵活地定制。

例如弱定义一个 port_printf 用来支持跨平台软件的打印输出,默认是直接使用平台的 vprintf,对于大多数的用户来说,只需要打印到平台自带的 printf 即可,因此对于大多数用户来说,这个 Port 不用实现,就能正常使用系统了。

attribute((weak)) void port_printf(char* fmt, ...) {  va_list args;  va_start(args, fmt);  vprintf(fmt, args);  va_end(args);}

而有定制需求的用户可以通过自己重写 port_printf() 来打印到其他的地方(比如输出到 log,或者输出到其他串口)。

在 printf 的例子中,我们默认了 printf 是所有的平台都提供了的,对 printf 进行这种假设是合理的,因为它是 libc 的标准函数。

然而,有些 Port 虽然有默认实现,却不能支持所有的平台,例如线程操作的 Port,在常见的平台中,如 linux、RT-Thread、FreeRTOS ,我们知道如何写默认实现,但是这些实现又不通用,这时我们可以在默认实现中结合条件编译,为常见的平台提供默认实现,例如:

attribute((weak)) void port_thread_start(port_thread_t* thread) {#ifdef __linux    pthread_mutex_lock(&(thread->mutex));    pthread_cond_signal(&(thread->cond));    pthread_mutex_unlock(&(thread->mutex));#elif USE_FREERTOS    vTaskResume(thread->thread);#else    #error "port_thread_start() 需要用户实现"#endif}

这个例子中为 linux 和 FreeRTOS 提供了默认的线程启动 Port 的实现,使用 linux 或者 FreeRTOS 的用户可以通过条件编译来直接使用默认实现。

而既不用 linux 也不用 FreeRTOS 的用户,则会在编译时遇到 #error,这提示他们要自己实现 port_thread_start()。

这种写法还有一种好处,就是在不支持 weak 的平台,例如 MSVC,就可以通过 _WIN32 条件编译来进行跨平台支持。

3. 边缘但无默认实现的 Port

还有一类 Port,它们比较冷门,只有部分用户会使用到,但是又难以提供默认的实现。例如用 port_reboot() 来重启硬件,每个硬件平台重启硬件的 API 都是不同的,我们无法提供一个默认的实现。

但是,没有这个 Port,也不影响系统的核心功能,只是在某些时候(例如开启了超时自动重启功能),又有这个 Port才行,这样的 Port 就属于是边缘但无默认实现的 Port。

这时,就可以选择将 Port 缺失的错误延后到运行时,具体在操作时,就可以编写一个 weak 的实现,而这个实现中抛出一个运行时错误,例如:

attribute((weak)) void port_reboot(void){    printf("Error: port_reboot() 需要用户实现\r\n");    while(1);}

这样,只要不用到这个 Port,都可以编译通过且顺利运行,只有实际用到时,才会在运行时报错。

weak 在 GCC 链接静态库时的问题

这里我想特别提示一种常见的 weak 失效的问题,这种问题目前我只发现在 gcc 链接静态库时包含 weak 会出现。

gcc 在链接静态库时,默认的行为是只要找到第一个(不管是不是弱符号),就会将其链接,然后停止继续寻找,这样一来,如果你的 weak 是被第一个找到的,那么强定义的函数就失效了。

这个问题有多种解决方案,我这里只提示一种,有更好的方案可以进qq交流群:577623681 大家一起讨论。

解决方案:使用 "-Wl,--whole-archive" 选项来解决。当使用这个选项时,链接器将整个库文件都包含在链接输出文件中,而不考虑这些库文件是否实际上被使用了。这样就可以保证弱符号在整个库中得到了正确的链接,并且在可执行文件或其他库中保持有效。

需要注意的是,当使用 "-Wl,--whole-archive" 选项时,可能会将一些不必要的库文件链接到最终的可执行文件或库中,这可能会增加最终文件的大小。因此,应该仅在必要时使用这个选项。


定期以通俗易懂的方式分享嵌入式知识,关注公众号,加星标,每天进步一点点。


声明:

本号原创、转载的文章、图片等版权归原作者所有,如有侵权,请联系删除。

关注、点赞、在看、转发,支持优质内容! 

评论 (0)
  •   电磁兼容故障诊断系统平台深度解析   北京华盛恒辉电磁兼容(EMC)故障诊断系统平台是解决电子设备在复杂电磁环境下性能异常的核心工具。随着电子设备集成度提升与电磁环境复杂化,EMC 问题直接影响设备可靠性与安全性。以下从平台架构、核心功能、技术实现、应用场景及发展趋势展开全面剖析。   应用案例   目前,已有多个电磁兼容故障诊断系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁兼容故障诊断系统。这些成功案例为电磁兼容故障诊断系统的推广和应用提供了有力支持。  
    华盛恒辉l58ll334744 2025-04-22 14:29 156浏览
  •   电磁兼容(EMC)故障诊断系统软件解析   北京华盛恒辉电磁兼容故障诊断系统软件是攻克电子设备电磁干扰难题的专业利器。在电子设备复杂度攀升、电磁兼容问题频发的背景下,该软件于研发、测试、生产全流程中占据关键地位。以下为其详细介绍:   应用案例   目前,已有多个电磁兼容故障诊断系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁兼容故障诊断系统。这些成功案例为电磁兼容故障诊断系统的推广和应用提供了有力支持。   一、软件核心功能   干扰与敏感分析:深度剖析电磁干
    华盛恒辉l58ll334744 2025-04-22 14:53 139浏览
  • 据国际精益六西格玛研究所(ILSSI)成员大卫·哈钦斯(David Hutchins)的回忆,在“六西格玛”名称出现前,摩托罗拉组建了约100个质量改进团队,接受朱兰博士制作的16盘录像带培训,名为《朱兰论质量改进》(Juran on Quality Improvement),为了推广这种严谨的分析方法(朱兰博士视频中的核心内容),摩托罗拉前首席执行官鲍勃·加尔文创造了“六西格玛”这一标签,用以表彰这种“最顶尖"的方法。大卫·哈钦斯(David Hutchins)是朱兰博士的好友,也为他的工作做
    优思学院 2025-04-22 12:03 108浏览
  • 文/Leon编辑/cc孙聪颖‍4月18日7时,2025北京亦庄半程马拉松暨人形机器人半程马拉松正式开跑。与普通的半马比赛不同,这次比赛除了有人类选手,还有21支人形机器人队伍参赛,带来了全球首次人类与机器人共同竞技的盛况。参赛队伍中,不乏明星机器人企业及机型,比如北京人形机器人创新中心的天工Ultra、松延动力的N2等。宇树G1、众擎PM01,则是由城市之间科技有限公司购置及调试,并非厂商直接参赛。考虑到机器人的适用场景和续航力各有不同,其赛制也与人类选手做出区别:每支赛队最多可安排3名参赛选手
    华尔街科技眼 2025-04-22 20:10 59浏览
  • 在科技飞速发展的当下,机器人领域的每一次突破都能成为大众瞩目的焦点。这不,全球首届人形机器人半程马拉松比赛刚落下帷幕,赛场上的 “小插曲” 就掀起了一阵网络热潮。4月19日,北京亦庄的赛道上热闹非凡,全球首届人形机器人半程马拉松在这里激情开跑。20支机器人队伍带着各自的“参赛选手”,踏上了这21.0975公里的挑战之路。这场比赛可不简单,它将机器人放置于真实且复杂的动态路况与环境中,对机器人在运动控制、环境感知和能源管理等方面的核心技术能力进行了全方位的检验。不仅要应对长距离带来的续航挑战,还要
    用户1742991715177 2025-04-22 20:42 54浏览
  •   电磁干扰抑制系统平台深度解析   一、系统概述   北京华盛恒辉电磁干扰抑制系统在电子技术快速发展、电磁环境愈发复杂的背景下,电磁干扰(EMI)严重影响电子设备性能、稳定性与安全性。电磁干扰抑制系统平台作为综合性解决方案,通过整合多元技术手段,实现对电磁干扰的高效抑制,确保电子设备稳定运行。   应用案例   目前,已有多个电磁干扰抑制系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁干扰抑制系统。这些成功案例为电磁干扰抑制系统的推广和应用提供了有力支持。   二
    华盛恒辉l58ll334744 2025-04-22 15:27 148浏览
  • 文/Leon编辑/cc孙聪颖‍在特朗普政府发起的关税战中,全球芯片产业受到巨大冲击,美国芯片企业首当其冲。据报道称,英伟达本周二公布的8-K文件显示,美国政府通知该公司向中国(包括中国香港及澳门)销售尖端芯片(H20)时,需要获得美国政府的许可。文件发布后,英伟达预计会在第一季度中额外增加55亿美元的相关费用计提。随后,英伟达股价单日下跌6.9%,市值一夜蒸发约1890亿美元(约合人民币1.37万亿元)。至截稿时,至截稿时,其股价未见止跌,较前日下跌4.51%。北京时间4月17日,英伟达创始人、
    华尔街科技眼 2025-04-22 20:14 64浏览
  • 一、行业背景与市场需求高血压作为全球发病率最高的慢性病之一,其早期监测与管理已成为公共卫生领域的重要课题。世界卫生组织数据显示,全球超13亿人受高血压困扰,且患者群体呈现年轻化趋势。传统血压计因功能单一、数据孤立等缺陷,难以满足现代健康管理的需求。在此背景下,集语音播报、蓝牙传输、电量检测于一体的智能血压计应运而生,通过技术创新实现“测量-分析-管理”全流程智能化,成为慢性病管理的核心终端设备。二、技术架构与核心功能智能血压计以电子血压测量技术为基础,融合物联网、AI算法及语音交互技术,构建起多
    广州唯创电子 2025-04-23 09:06 81浏览
  • 4 月 19 日,“增长无界・智领未来” 第十六届牛商大会暨电子商务十大牛商成果报告会在深圳凤凰大厦盛大举行。河南业之峰科技股份有限公司总经理段利强——誉峰变频器强哥凭借在变频器领域的卓越成就,荣膺第十六届电子商务十大牛商,携誉峰变频器品牌惊艳亮相,以十几年如一日的深耕与创新,书写着行业传奇。图 1:誉峰变频器强哥在牛商大会领奖现场,荣耀时刻定格牛商大会现场,誉峰变频器强哥接受了多家媒体的专访。面对镜头,他从容分享了自己在变频器行业二十年的奋斗历程与心路感悟。谈及全域营销战略的成功,誉峰变频器强
    电子与消费 2025-04-22 13:22 135浏览
  •   陆地边防事件紧急处置系统平台解析   北京华盛恒辉陆地边防事件紧急处置系统平台是整合监测、预警、指挥等功能的智能化综合系统,致力于增强边防安全管控能力,快速响应各类突发事件。以下从系统架构、核心功能、技术支撑、应用场景及发展趋势展开全面解读。   应用案例   目前,已有多个陆地边防事件紧急处置系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润陆地边防事件紧急处置系统。这些成功案例为陆地边防事件紧急处置系统的推广和应用提供了有力支持。   一、系统架构   感知层:部
    华盛恒辉l58ll334744 2025-04-23 11:22 59浏览
  • 近期,金融界消息称,江西万年芯微电子有限公司申请一项名为“基于预真空腔体注塑的芯片塑封方法及芯片”的专利。此项创新工艺的申请,标志着万年芯在高端芯片封装领域取得重要突破,为半导体产业链提升注入了新动能。专利摘要显示,本发明公开了一种基于预真空腔体注塑的芯片塑封方法,方法包括将待塑封的大尺寸芯片平铺于下模盒腔体内的基板并将大尺寸芯片的背向表面直接放置于基板上以进行基板吸附;将上模盒盖合于下模盒形成塑封腔,根据基板将塑封腔分为上型腔以及下型腔;将下型腔内壁与大尺寸芯片间的空隙进行树脂填充;通过设置于
    万年芯 2025-04-22 13:28 95浏览
  •   复杂电磁环境模拟系统平台解析   一、系统概述   北京华盛恒辉复杂电磁环境模拟系统平台是用于还原真实战场或特定场景电磁环境的综合性技术平台。该平台借助软硬件协同运作,能够产生多源、多频段、多体制的电磁信号,并融合空间、时间、频谱等参数,构建高逼真度的电磁环境,为电子对抗、通信、雷达等系统的研发、测试、训练及评估工作提供重要支持。   应用案例   目前,已有多个复杂电磁环境模拟系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润复杂电磁环境模拟系统。这些成功案例为复杂电
    华盛恒辉l58ll334744 2025-04-23 10:29 71浏览
  • 一、技术背景与市场机遇在智能家居高速发展的今天,用户对家电设备的安全性、智能化及能效表现提出更高要求。传统取暖器因缺乏智能感知功能,存在能源浪费、安全隐患等痛点。WTL580-C01微波雷达感应模块的诞生,为取暖设备智能化升级提供了创新解决方案。该模块凭借微波雷达技术优势,在精准测距、环境适应、能耗控制等方面实现突破,成为智能取暖器领域的核心技术组件。二、核心技术原理本模块采用多普勒效应微波雷达技术,通过24GHz高频微波信号的发射-接收机制,实现毫米级动作识别和精准测距。当人体进入4-5米有效
    广州唯创电子 2025-04-23 08:41 76浏览
  •   卫星通信效能评估系统平台全面解析   北京华盛恒辉卫星通信效能评估系统平台是衡量卫星通信系统性能、优化资源配置、保障通信服务质量的关键技术工具。随着卫星通信技术的快速发展,特别是低轨卫星星座、高通量卫星和软件定义卫星的广泛应用,效能评估系统平台的重要性日益凸显。以下从技术架构、评估指标、关键技术、应用场景及发展趋势五个维度进行全面解析。   应用案例   目前,已有多个卫星通信效能评估系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润卫星通信效能评估系统。这些成功案例为卫
    华盛恒辉l58ll334744 2025-04-22 16:34 133浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦