太坑了,C标准库缓冲区溢出的问题,该搞清楚了

小麦大叔 2021-12-13 21:30


大家好,我是小麦,今天给大家分享一篇文章。在开发的过程中,如果遇到C标准库缓冲区溢出的问题,那么内心肯定是奔溃的。

下面我们来看看有哪些办法来避免这种情况吧。

C中大多数缓冲区溢出问题可以直接追溯到标准 C 库。最有害的罪魁祸首是不进行自变量检查的、有问题的字符串操作strcpystrcatsprintf 和 gets

大部分程序员仍然会使用这些函数,因为从来没有人教开发人员避免使用它们。某些人从各处获得某个提示,但即使是优秀的开发人员也会被这弄糟,下面就来分析一下。

第一位公共的“敌人”是 gets()。建议不要使用 gets()。该函数从标准输入读入用户输入的一行文本,它在遇到 EOF字符或换行字符之前,不会停止读入文本。也就是:gets() 根本不执行边界检查。因此,使用 gets()总是有可能使任何缓冲区溢出。作为一个替代方法,可以使用 fgets()。它可以做与 gets()所做的同样的事情,但它接受用来限制读入字符数目的大小参数,因此,提供了一种防止缓冲区溢出的方法。例如,不要使用以下代码:

void main()
{
char buf[1024];
gets(buf);
}

而使用以下代码:

#define BUFSIZE 1024
void main()
{
char buf[BUFSIZE];
fgets(buf, BUFSIZE, stdin);
}


1C 编程中的主要陷阱

C语言中一些标准函数很有可能使你陷入困境。但不是所有函数使用都不好。通常,利用这些函数之一需要任意输入传递给该函数。这个列表包括:

  • strcpy()
  • strcat()
  • sprintf()
  • scanf()
  • sscanf()
  • fscanf()
  • vfscanf()
  • vsprintf
  • vscanf()
  • vsscanf()
  • streadd()
  • strecpy()
  • strtrns()

我们推荐使用,如果有可能,应尽量避免使用这些函数。这些函数在大多数情况下,都有合理的替代方法。我们将仔细检查它们中的每一个,所以可以看到什么构成了它们的误用,以及如何避免它。

strcpy()函数将源字符串复制到缓冲区。没有指定要复制字符的具体数目。复制字符的数目直接取决于源字符串中的数目。如果源字符串碰巧来自用户输入,且没有专门限制其大小,则有可能会陷入大的麻烦中!

如果知道目的地缓冲区的大小,则可以添加明确的检查:

if(strlen(src) >= dst_size)
{
/* Do something appropriate, such as throw an error. */
}
else
{
strcpy(dst, src);
}

完成同样目的的更容易方式是使用 strncpy() 库例程:

strncpy(dst, src, dst_size-1);
dst[dst_size-1] = '\0'; /* Always do this to be safe! */

如果 src 比 dst 大,则该函数不会抛出一个错误;当达到最大尺寸时,它只是停止复制字符。注意上面调用 strncpy()中的 -1。如果 src 比 dst 长,则那给我们留有空间,将一个空字符放在 dst 数组的末尾。

当然,可能使用strcpy()不会带来任何潜在的安全性问题,正如在以下示例中所见:

strcpy(buf, "Hello!");

即使这个操作造成 buf 的溢出,但它只是对几个字符这样而已。由于我们静态地知道那些字符是什么,并且很明显,由于没有危害,所以这里无须担心 ― 当然,除非可以用其它方式覆盖字符串Hello所在的静态存储器。

确保strcpy()不会溢出的另一种方式是,在需要它时就分配空间,确保通过在源字符串上调用 strlen() 来分配足够的空间。例如:

dst = (char *)malloc(strlen(src));
strcpy(dst, src);

strcat()函数非常类似于strcpy(),除了它可以将一个字符串合并到缓冲区末尾。它也有一个类似的、更安全的替代方法strncat()。如果可能,使用strncat()而不要使用strcat()

函数sprintf()vsprintf()是用来格式化文本和将其存入缓冲区的通用函数。它们可以用直接的方式模仿strcpy()行为。换句话说,使用sprintf()vsprintf()与使用strcpy()一样,都很容易对程序造成缓冲区溢出。例如,考虑以下代码:

void main(int argc, char **argv)
{
char usage[1024];
sprintf(usage, "USAGE: %s -f flag [arg1]\n", argv[0]);
}

我们经常会看到类似上面的代码。它看起来没有什么危害。它创建一个知道如何调用该程序字符串。那样,可以更改二进制的名称,该程序的输出将自动反映这个更改。虽然如此, 该代码有严重的问题。文件系统倾向于将任何文件的名称限制于特定数目的字符。那么,您应该认为如果您的缓冲区足够大,可以处理可能的最长名称,您的程序会安全,对吗?只要将1024改为对我们的操作系统适合的任何数目,就好了吗?但是,不是这样的。通过编写我们自己的小程序来推翻上面所说的,可能容易地推翻这个限制:

void main()
{
execl("/path/to/above/program",
<<insert really long string here>>,
NULL);
}

函数execl()启动第一个参数中命名的程序。第二个参数作为argv[0]传递给被调用的程序。我们可以使那个字符串要多长有多长!

那么如何解决sprintf()带来得问题呢?遗憾的是,没有完全可移植的方法。某些体系结构提供了snprintf()方法,即允许程序员指定将多少字符从每个源复制到缓冲区中。例如,如果我们的系统上有snprintf,则可以修正一个示例成为:

void main(int argc, char **argv)
{
char usage[1024];
char format_string = "USAGE: %s -f flag [arg1]\n";
snprintf(usage, format_string, argv[0],1024-strlen(format_string) + 1);
}

注意,在第四个变量之前,snprintf()sprintf()是一样的。第四个变量指定了从第三个变量中应被复制到缓冲区的字符最大数目。注意,1024 是错误的数目!我们必须确保要复制到缓冲区使用的字符串总长不超过缓冲区的大小。所以,必须考虑一个空字符,加上所有格式字符串中的这些字符,再减去格式说明符 %s。该数字结果为1000,但上面的代码是更具有可维护性,因为如果格式字符串偶然发生变化,它不会出错。

sprintf()的许多(但不是全部)版本带有使用这两个函数的更安全的方法。可以指定格式字符串本身每个自变量的精度。例如,另一种修正上面有问题的sprintf()的方法是:

void main(int argc, char **argv)
{
char usage[1024];
sprintf(usage, "USAGE: %.1000s -f flag [arg1]\n", argv[0]);
}

注意,百分号后与 s 前的 .1000。该语法表明,从相关变量(本例中是 argv[0])复制的字符不超过 1000 个。

如果任一解决方案在您的程序必须运行的系统上行不通,则最佳的解决方案是将snprintf()的工作版本与您的代码放置在一个包中。可以找到以sh归档格式的、自由使用的版本;请参阅 参考资料。

继续,scanf系列的函数也设计得很差。在这种情况下,目的地缓冲区会发生溢出。考虑以下代码:

void main(int argc, char **argv)
{
char buf[256];
sscanf(argv[0], "%s", &buf);
}

如果输入的字大于 buf 的大小,则有溢出的情况。幸运的是,有一种简便的方法可以解决这个问题。考虑以下代码,它没有安全性方面的薄弱环节:

void main(int argc, char **argv)
{
char buf[256];
sscanf(argv[0], "%255s", &buf);
}

百分号和 s 之间的 255 指定了实际存储在变量 buf 中来自 argv[0] 的字符不会超过 255 个。其余匹配的字符将不会被复制。

接下来,我们讨论streadd()strecpy()。由于,不是每台机器开始就有这些调用,那些有这些函数的程序员,在使用它们时,应该小心。这些函数可以将那些含有不可读字符的字符串转换成可打印的表示。例如,考虑以下程序:

#include <libgen.h>

void main(int argc, char **argv)
{
char buf[20];
streadd(buf, "\t\n", "");
printf(%s\n", buf);
}

该程序打印:

\t\n

而不是打印所有空白。如果程序员没有预料到需要多大的输出缓冲区来处理输入缓冲区(不发生缓冲区溢出),则streadd() 和 strecpy()函数可能有问题。如果输入缓冲区包含单一字符 ― 假设是 ASCII 001(control-A)―则它将打印成四个字符\001。这是字符串增长的最坏情况。如果没有分配足够的空间,以至于输出缓冲区的大小总是输入缓冲区大小的四倍,则可能发生缓冲区溢出。

另一个较少使用的函数是strtrns(),因为许多机器上没有该函数。函数strtrns()取三个字符串和结果字符串应该放在其内的一个缓冲区,作为其自变量。第一个字符串必须复制到该缓冲区。一个字符被从第一个字符串中复制到缓冲区,除非那个字符出现在第二个字符串中。如果出现的话,那么会替换掉第三个字符串中同一索引中的字符。这听上去有点令人迷惑。让我们看一下,将所有小写字符转换成大写字符的示例:

#include <libgen.h>
void main(int argc, char **argv)
{
char lower[] = "abcdefghijklmnopqrstuvwxyz";
char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *buf;
if(argc < 2) {
printf("USAGE: %s arg\n", argv[0]);
exit(0);
}
buf = (char *)malloc(strlen(argv[1]));
strtrns(argv[1], lower, upper, buf);
printf("%s\n", buf);
}

以上代码实际上不包含缓冲区溢出。但如果我们使用了固定大小的静态缓冲区,而不是用malloc()分配足够空间来复制argv[1],则可能会引起缓冲区溢出情况。

2避免内部缓冲区溢出

realpath()函数接受可能包含相对路径的字符串,并将它转换成指同一文件的字符串,但是通过绝对路径。在做这件事时,它展开了所有符号链接。

该函数取两个自变量,第一个作为要规范化的字符串,第二个作为将存储结果的缓冲区。当然,需要确保结果缓冲区足够大,以处理任何大小的路径。分配的MAXPATHLEN缓冲区应该足够大。然而,使用realpath()有另一个问题。如果传递给它的、要规范化的路径大小大于MAXPATHLEN,则realpath()实现内部的静态缓冲区会溢出!虽然实际上没有访问溢出的缓冲区,但无论如何它会伤害您的。结果是,应该明确不使用realpath(),除非确保检查您试图规范化的路径长度不超过MAXPATHLEN

其它广泛可用的调用也有类似的问题。经常使用的syslog()调用也有类似的问题,直到不久前,才注意到这个问题并修正了它。大多数机器上已经纠正了这个问题,但您不应该依赖正确的行为。最好总是假定代码正运行在可能最不友好的环境中,只是万一在哪天它真的这样。getopt()系列调用的各种实现,以及getpass()函数,都可能产生内部静态缓冲区溢出问题。如果您不得不使用这些函数,最佳解决方案是设置传递给这些函数的输入长度的阈值。

自己模拟gets()的安全性问题以及所有问题是非常容易的。例如,下面这段代码:

char buf[1024];
int i = 0;
char ch;
while((ch = getchar()) != '\n')
{
if(ch == -1) break;
buf[i++] = ch;
}

哎呀!可以用来读入字符的任何函数都存在这个问题,包括getchar()fgetc()getc() 和 read()

缓冲区溢出问题的准则是:总是确保做边界检查。

C 和 C++ 不能够自动地做边界检查,这实在不好,但确实有很好的原因,来解释不这样做的理由。边界检查的代价是效率。一般来讲,C 在大多数情况下注重效率。然而,获得效率的代价是,C 程序员必须十分警觉,并且有极强的安全意识,才能防止他们的程序出现问题,而且即使这些,使代码不出问题也不容易。

在现在,变量检查不会严重影响程序的效率。大多数应用程序不会注意到这点差异。所以,应该总是进行边界检查。在将数据复制到您自己的缓冲区之前,检查数据长度。同样,检查以确保不要将过大的数据传递给另一个库,因为您也不能相信其他人的代码!(回忆一下前面所讨论的内部缓冲区溢出。)

3其它危险是什么?

遗憾的是,即使是系统调用的“安全”版本 ― 譬如,相对于strcpy()strncpy()也不完全安全。也有可能把事情搞糟。即使安全的调用有时会留下未终止的字符串,或者会发生微妙的相差一位错误。当然,如果您偶然使用比源缓冲区小的结果缓冲区,则您可能发现自己处于非常困难的境地。

与我们目前所讨论的相比,往往很难犯这些错误,但您应该仍然意识到它们。当使用这类调用时,要仔细考虑。如果不仔细留意缓冲区大小,包括bcopy()fgets()memcpy()snprintf()strccpy()strcadd()strncpy() 和 vsnprintf(),许多函数会行为失常。

另一个要避免的系统调用是 getenv()。使用getenv() 的最大问题是您从来不能假定特殊环境变量是任何特定长度的。我们将在后续的专栏文章中讨论环境变量带来的种种问题。

到目前为止,我们已经给出了一大堆常见 C 函数,这些函数容易引起缓冲区溢出问题。当然,还有许多函数有相同的问题。特别是,注意第三方 COTS 软件。不要设想关于其他人软件行为的任何事情。还要意识到我们没有仔细检查每个平台上的每个常见库(我们不想做那一工作),并且还可能存在其它有问题的调用。

即使我们检查了每个常见库的各个地方,如果我们试图声称已经列出了将在任何时候遇到的所有问题,则您应该持非常非常怀疑的态度。我们只是想给您起一个头。其余全靠您了。

4静态和动态测试工具

我们将在以后的专栏文章中更加详细地介绍一些脆弱性检测的工具,但现在值得一提的是两种已被证明能有效帮助找到和去除缓冲区溢出问题的扫描工具。这两个主要类别的分析工具是静态工具(考虑代码但永不运行)和动态工具(执行代码以确定行为)。

可以使用一些静态工具来查找潜在的缓冲区溢出问题。很糟糕的是,没有一个工具对一般公众是可用的!许多工具做得一点也不比自动化 grep 命令多,可以运行它以找到源代码中每个有问题函数的实例。由于存在更好的技术,这仍然是高效的方式将几万行或几十万行的大程序缩减到只有数百个“潜在的问题”。(在以后的专栏文章中,将演示一个基于这种方法的、草草了事的扫描工具,并告诉您有关如何构建它的想法。)

较好的静态工具利用以某些方式表示的数据流信息来断定哪个变量会影响到其它哪个变量。用这种方法,可以丢弃来自基于 grep 的分析的某些“假肯定”。David Wagner 在他的工作中已经实现了这样的方法(在“Learning the basics of buffer overflows”中描述;请参阅 参考资料),在 Reliable Software Technologies 的研究人员也已实现。当前,数据流相关方法的问题是它当前引入了假否定(即,它没有标志可能是真正问题的某些调用)。

第二类方法涉及动态分析的使用。动态工具通常把注意力放在代码运行时的情况,查找潜在的问题。一种已在实验室使用的方法是故障注入。这个想法是以这样一种方式来检测程序:对它进行实验,运行“假设”游戏,看它会发生什么。有一种故障注入工具 ― FIST(请参阅 参考资料)已被用来查找可能的缓冲区溢出脆弱性。

最终,动态和静态方法的某些组合将会给您的投资带来回报。但在确定最佳组合方面,仍然有许多工作要做。

5最后

下面表格总结了一些编程构造,我们建议你小心使用或避免使用它们。如果要想代码健壮,最好有一定容错处理最好,比如之前给大家分享过的Assert断言机制》。
函数严重性解决方案
gets最危险使用 fgets(buf, size, stdin)。这几乎总是一个大问题!
strcpy很危险改为使用 strncpy。
strcat很危险改为使用 strncat。
sprintf很危险改为使用 snprintf,或者使用精度说明符。
scanf很危险使用精度说明符,或自己进行解析。
sscanf很危险使用精度说明符,或自己进行解析。
fscanf很危险使用精度说明符,或自己进行解析。
vfscanf很危险使用精度说明符,或自己进行解析。
vsprintf很危险改为使用 vsnprintf,或者使用精度说明符。
vscanf很危险使用精度说明符,或自己进行解析。
vsscanf很危险使用精度说明符,或自己进行解析。
streadd很危险确保分配的目的地参数大小是源参数大小的四倍。
strecpy很危险确保分配的目的地参数大小是源参数大小的四倍。
strtrns危险手工检查来查看目的地大小是否至少与源字符串相等。
realpath很危险(或稍小,取决于实现)分配缓冲区大小为 MAXPATHLEN。同样,手工检查参数以确保输入参数不超过 MAXPATHLEN。
syslog很危险(或稍小,取决于实现)在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。
getopt很危险(或稍小,取决于实现)在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。
getopt_long很危险(或稍小,取决于实现)在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。
getpass很危险(或稍小,取决于实现)在将字符串输入传递给该函数之前,将所有字符串输入截成合理的大小。
getchar中等危险如果在循环中使用该函数,确保检查缓冲区边界。
fgetc中等危险如果在循环中使用该函数,确保检查缓冲区边界。
read中等危险如果在循环中使用该函数,确保检查缓冲区边界。
bcopy中等危险如果在循环中使用该函数,确保检查缓冲区边界。
fgets低危险确保缓冲区大小与它所说的一样大。
memcpy低危险确保缓冲区大小与它所说的一样大。
snprintf低危险确保缓冲区大小与它所说的一样大。
strccpy低危险确保缓冲区大小与它所说的一样大。
strcadd低危险确保缓冲区大小与它所说的一样大。
strncpy低危险确保缓冲区大小与它所说的一样大。
getchar低危险确保缓冲区大小与它所说的一样大。
vsnprintf低危险确保缓冲区大小与它所说的一样大。

转自:嵌入式专栏
免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

欢迎关注我的公众号回复“加群”按规则加入技术交流群


—— The End —


往期推荐



物联网居然有这么多通信协议...

10大动图:秒懂各种常用通信协议原理

CAN总线简易入门教程

嵌入式学习真的这么烧钱吗?

一键调整PCB丝印,超级好用


长按识别二维码关注我


你点的每个好看,我都认真当成了喜欢
小麦大叔 一位热衷技术的攻城狮,懂点技术,会讲故事,交个朋友?
评论
  • 真空容器的材料选择取决于其应用场景(如科研、工业、医疗)、真空等级(低真空、高真空、超高真空)以及环境条件(温度、压力、化学腐蚀等)。以下是常见材料及其优缺点分析:1. 不锈钢(如304、316L)优点:耐腐蚀性强:316L含钼,耐酸碱和高温氧化,适合高真空和腐蚀性环境。高强度:机械性能稳定,可承受高压差和外部冲击。低放气率:经电解抛光或镀镍处理后,表面放气率极低,适合超高真空系统(如粒子加速器、半导体镀膜设备)。易加工:可焊接、铸造,适合复杂结构设计。缺点:重量大:大型容器运输和安装成本高。磁
    锦正茂科技 2025-03-29 10:52 40浏览
  • 文/杜杰编辑/cc孙聪颖‍3月11日,美国总统特朗普,将自费8万美元购买的特斯拉Model S,开进了白宫。特朗普此举,绝非偶然随性,而是有着鲜明的主观意图,处处彰显出一种刻意托举的姿态 。特朗普也毫不讳言,希望他的购买能推动特斯拉的发展。作为全球电动车鼻祖,特斯拉曾凭借创新理念与先进技术,开辟电动汽车新时代,引领行业发展潮流。然而当下,这家行业先驱正深陷困境,面临着前所未有的挑战。就连“钢铁侠”马斯克自己都在采访时表示“非常困难”,的确是需要美国总统伸手拉一把了。马斯克踏入白宫的那一刻,特斯拉
    华尔街科技眼 2025-03-28 20:44 140浏览
  • 真空容器内部并非wan全没有压强,而是压强极低,接近于零。真空状态下的压强与容器内外气体的分子数量、温度以及容器本身的性质有关。一、真空与压强的基本概念真空指的是一个空间内不存在物质或物质极少的状态,通常用于描述容器或系统中气体的稀薄程度。压强则是单位面积上所受正压力的大小,常用于描述气体、液体等流体对容器壁的作用力。二、真空状态下的压强特点在真空状态下,容器内部的气体分子数量极少,因此它们对容器壁的作用力也相应减小。这导致真空容器内部的压强远低于大气压强,甚至接近于零。然而,由于技术限制和物理
    锦正茂科技 2025-03-29 10:16 101浏览
  •        随着智能驾驶向L3级及以上迈进,系统对实时性的要求已逼近极限。例如,自动紧急制动(AEB)需在50毫秒内完成感知、决策到执行的全链路响应,多传感器数据同步误差需小于10微秒。然而,传统基于Linux-RT的方案在混合任务处理中存在天然缺陷——其最大中断延迟高达200微秒,且多任务并发时易引发优先级反转问题。据《2024年智能汽车电子架构白皮书》统计,超60%的车企因实时性不足被迫推迟舱驾一体化项目落地。为旌电子给出的破局之道,是采用R5F(实
    中科领创 2025-03-29 11:55 146浏览
  • 本文介绍OpenHarmony5.0 DevEco Studio开发工具安装与配置,鸿蒙北向开发入门必备!鸿蒙北向开发主要侧重于应用层的开发,如APP开发、用户界面设计等,更多地关注用户体验、应用性能优化、上层业务逻辑的实现,需要开发者具备基本的编程知识、对操作系统原理的简单理解,以及一定的UI设计感。由触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,支持开源鸿蒙OpenHarmony3.2至5.0系统,适合鸿蒙开发入门学习。下载与安装开发工具点下面链接下载:
    Industio_触觉智能 2025-03-28 18:16 125浏览
  • 一、真空容器的定义与工作原理真空容器是一种能够创造并保持一定真空度的密闭容器。其工作原理通常涉及抽气系统,该系统能够逐渐抽出容器内部的气体分子,从而降低容器内的气压,形成真空环境。在这个过程中,容器的体积并不会因抽气而改变,但容器内的压力会随着气体的抽出而逐渐降低。二、真空容器并非恒压系统真空容器并非一个恒压系统。恒压系统指的是在外部环境变化时,系统内部压力能够保持相对稳定。然而,在真空容器中,随着气体的不断抽出,内部压力会持续降低,直至达到所需的真空度。因此,真空容器内部的压力是变化的,而非恒
    锦正茂科技 2025-03-29 10:23 95浏览
  • 在智能语音设备开发中,高音量输出是许多场景的核心需求,例如安防警报、工业设备提示、户外广播等。 WT588F02BP-14S 和 WTN6040FP-14S 两款语音芯片,凭借其内置的 D类功放 和 3W大功率输出 能力,成为高音量场景的理想选择。本文将从 性能参数、应用场景、设计要点 三大维度,全面解析这两款芯片的选型策略。一、核心参数对比与选型决策参数WT588F02BP-14SWTN6040FP-14S输出功率3W@4Ω(THD<1%)3W@4Ω(THD<0.8%)功
    广州唯创电子 2025-03-28 09:15 63浏览
  • 3月27日,长虹中玖闪光超高剂量率电子射线放射治疗系统(e-Flash)临床试验项目在四川大学华西医院正式启动,标志着该项目正式进入临床试验阶段。这不仅是我国医学技术领域的一项重大突破,更是我国在高端医疗设备研发和应用方面的重要里程碑。e-Flash放射治疗系统适用于哪些病症,治疗周期为多久?会不会产生副作用?治疗费用高不高……随着超高剂量率电子射线放射治疗系统(e-Flash)正式进入临床试验阶段,社会各界对该项目的实施情况尤为关注。对此,中国工程院院士范国滨,以及四川大学华西医院、四川省肿瘤
    华尔街科技眼 2025-03-28 20:26 153浏览
  • 本文介绍瑞芯微RK356X系列复用接口配置的方法,基于触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。复用接口介绍由下图可知,红圈内容当前引脚可配置为SPI0或者PWM0功能。由标准系统固件以及相关系统手册可得,当前接口默认配置为SPI0功能:console:/ # ls dev/spidev0.0dev/spidev0.0再由原理图可知当前GPIO为GPIO0_C3
    Industio_触觉智能 2025-03-28 18:14 81浏览
  • 在智能家居领域,无线门铃正朝着高集成度、低功耗、强抗干扰的方向发展。 WTN6040F 和 WT588F02B 两款语音芯片,凭借其 内置EV1527编解码协议 和 免MCU设计 的独特优势,为无线门铃开发提供了革命性解决方案。本文将深入解析这两款芯片的技术特性、应用场景及落地价值。一、无线门铃市场痛点与芯片方案优势1.1 行业核心痛点系统复杂:传统方案需MCU+射频模块+语音芯片组合,BOM成本高功耗瓶颈:待机电流
    广州唯创电子 2025-03-31 09:06 56浏览
  • 语音芯片在播放音频时出现电流声是嵌入式音频系统开发中的常见问题,直接影响用户体验。唯创电子WT系列语音芯片在智能家居、工业控制等领域广泛应用,本文将从PWM直推输出与DAC+功放输出两类典型电路架构出发,系统化分析电流声成因并提供工程级解决方案。一、PWM直推输出电路电流声诊断1.1 现象特征高频"滋滋"声(8kHz-20kHz)声音随系统负载变化波动静音状态下仍存在底噪1.2 核心成因分析(1) 电源干扰开关电源纹波超标:实测案例显示,当12V转3.3V的DC-DC电源纹波>80mVpp时,P
    广州唯创电子 2025-03-28 08:47 71浏览
  • Shinco音响拆解 一年一次的面包板社区的拆解活动拉开帷幕了。板友们开始大显身手了,拆解各种闲置的宝贝。把各自的设计原理和拆解的感悟一一向电子爱好者展示。产品使用了什么方案,用了什么芯片,能否有更优的方案等等。不仅让拆解的人员了解和深入探索在其中。还可以让网友们学习电子方面的相关知识。今天我也向各位拆解一个产品--- Shinco音响(如下图)。 当产品连接上电脑的耳机孔和USB孔时,它会发出“开机,音频输入模式”的语音播报,。告诉用户它已经进入音响外放模式。3.5mm耳机扣接收电脑音频信号。
    zhusx123 2025-03-30 15:42 65浏览
  • 你还记得,那些年疯狂追捧的淘宝网红店吗?它们曾是时尚的风向标,是很多人购物车里的常客,承载着无数年轻人的创业梦想。然而,最近这股网红店闭店潮,却如同一记重锤,敲醒了所有人。 从初代网红张大奕关闭“吾欢喜的衣橱”,到周扬青告别“GRACE CHOW”,再到拥有 190 万社交平台粉丝的“李大米 Lidami”宣布关闭淘宝店铺,以及“Ff5 official”“MAKI STUDIO”等大批网红店纷纷发出闭店通告,曾经风光无限的淘宝网红店,正在以惊人的速度消失。这一波闭店潮,涉及的店铺数量
    用户1742991715177 2025-03-27 23:22 43浏览
  • 在工业控制与数据采集领域,高精度的AD采集和实时显示至关重要。今天,我们就来基于瑞芯微RK3568J + FPGA国产平台深入探讨以下,它是如何实现该功能的。适用开发环境如下:Windows开发环境:Windows 7 64bit、Windows 10 64bitLinux开发环境:Ubuntu18.04.4 64bit、VMware15.5.5U-Boot:U-Boot-2017.09Kernel:Linux-4.19.232、Linux-RT-4.19.232LinuxSDK:LinuxSD
    Tronlong 2025-03-28 10:14 103浏览
  • 在智能语音交互设备开发中,系统响应速度直接影响用户体验。WT588F系列语音芯片凭借其灵活的架构设计,在响应效率方面表现出色。本文将深入解析该芯片从接收指令到音频输出的全过程,并揭示不同工作模式下的时间性能差异。一、核心处理流程与时序分解1.1 典型指令执行路径指令接收 → 协议解析 → 存储寻址 → 数据读取 → 数模转换 → 音频输出1.2 关键阶段时间分布(典型值)处理阶段PWM模式耗时DAC模式耗时外挂Flash模式耗时指令解析2-3ms2-3ms3-5ms存储寻址1ms1ms5-10m
    广州唯创电子 2025-03-31 09:26 82浏览
我要评论
3
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦