嵌入式软件的设计模式(下篇)

嵌入式ARM 2023-01-19 12:00

接前文 嵌入式软件的设计模式(上篇)

思想有多远,我们就能走多远

4、状态与工作流类设计模式

4.1 状态与事件

行为随条件变化而改变,这里状态切换的模式也称为状态机。有限状态机 (Finite State Machine,FSM) 是由3 个主要元素组成的有向图:状态、转换和动作。

状态是系统或者元素的状态;转换是从一个状态到另一个状态的路径,通常通过感兴趣的事件初始化,当元素处在前驱状态中,并且收到触发事件,它将连接前驱状态与后续状态。如果事件发生,然而状态中的元素没有对这个特定的事件做出响应,事件就“静静丢弃”没有任何效果,也就是状态机仅做肯定的陈述 (“当我在这个状态中并且这件事发生,我才会做” ) 。

状态机本身不关心事件如何到达,但是必须避免竞争条件。同步状态机必须阻塞调用者 (守卫调用模式或者临界区模式) ,异步状态机必须使用排队(队列模式)来存储它们的事件,直到它们得到处理。如果状态机正在执行动作的过程中产生新事件, 状态机会立即停止去处理事件? 答案当然是否定的。状态机在处理一个新事件之前,必须确保前一状态的处理完成。后续几个状态-事件模式都需要遵循这个原则,而且具体模式实现中不再赘述。

4.2 单事件接收器模式

单事件接收器状态机 (以下简称 SERSM) 简单说就是触发状态切换的事件接收入口只有一个,单事件接收器模式依赖于单一事件接收器在客户与状态机间提供接口。在内部,这个单一事件接收器必须接收事件数据类型,不仅识别哪个事件已经发生,并且识别任意伴随事件的数据。

事件接收器模式必然有事件,事件类型event_type和事件携带的数据event_data,前者可以是个枚举值,后者是一个结构体struct,为了识别不同的事件数据属性,可以选择union共用体更贴切。

如果是同步处理,状态执行比较简单,可以直接调用event_receptor,按传入的事件类型和事件数据执行并切状态;异步版本则建议组合使用队列模式,将事件按FIFO的方式入队,事件执行函数被动触发从队列中取出事件,用轮询的机制寻找新的事件和单事件接收器再执行,最终也是调用event_receptor。具体实现有两种方式:

1、分支逻辑法

利用 if-else 或者 switch-case 分支逻辑,按状态转移图,将每一个状态转移原模原样地直译成代码,对于简单的状态机来说,这种实现方式最简单、直接,是首选;缺点所有的状态逻辑封装在单一事件接收器内(一个大型 if-else 或 switch-case 结构),限制了状态变更和扩展性。

//微信公众号:嵌入式系统
//代码只是表意,无法编译
//enum s1 s2 s3  状态枚举值
//state 表示当前状态
void event_receptor(event_type,event_data)
{
    switch(state)
    {
    case s1:
        state_handle1(event_type,event_data);
        break;
    case s2:
        state_handle2(event_type,event_data);
        break;
    case s3:
        state_handle3(event_type,event_data);
    default:
        break;
    }
}

state_handle1/state_handle2/state_handle3执行后,按执行情况切换状态到新的state。下次即使同样的事件,因为state不同,也会产生不同的效果。

2、查表法

对于状态很多、状态转移比较复杂的状态机来说,查表法比较合适,也称表驱动法。通过二维数组来表示状态转移图,能极大地提高代码的可读性和可维护性,扩展状态只需增加表即可。

//微信公众号:嵌入式系统
//代码只是表意,无法编译
typedef struct
{

    int state;   //状态 enum
    pFun state_handle; //对应状态下的函数指针
}state_event_table_struct;

state_event_table_struct table[]={
    {s1,state_handle1},
    {s2,state_handle2},
    {s3,state_handle3}
};

void event_receptor(event_type,event_data)
{
    for(i=0;i<(sizeof(table)/sizeof(state_event_table_struct));i++)
    {
        //根据当前状态state查表选择对应的事件接收器,并进行状态切换
        if(current_state==table[i].state) 
        {
            table[i].state_handle(event_type,event_data);
            //current_state内部更新
        }
    }
}

4.3 多事件接收器模式

多事件接收器有限状态机 (MERSM) 通常仅用于同步状态机,这是因为业务层通常关心状态机的事件集合。在这个模式中,每个事件都有一个单一的事件接收器,每个事件接收器本身仅考虑处理单一事件以及执行相关动作。可以理解为单事件接收器是多个事件进入一个固定的接收器处理,而多事件接收器是多个事件组分配给多个接收器处理。

前者可以比喻为多个领导给一个员工安排任务,后者是多个领导同时给多个员工安排任务。在事件处理上可以复用处理机制,假设员工employee有A/B/C三人,任务task集有t1/t2/t3三种,其处理接口有多种实现方式。

1、拆分为单事件接收器模式内再嵌套一个单事件接收器

//微信公众号:嵌入式系统
//代码只是表意,无法编译
void employee_task_handle(employee, task)
{
    switch(employee)
    {
        case A:
            {
                switch(task)
                {
                    case t1:
      //do something
                        break;
                    case t2:
      //do something
                        break;
                    case t3:
      //do something
                        break;
                    default:
                        break;
                }
            }
            break;

        case B:
   //同上
            break;
        case C:
   //同上
            break;
        default:
            break;
    }
}

对于两层switch-case,也可以先按task分,再嵌套按employee分类执行。

也可以直接将employee_task_handle 函数的参数拆分,例如 employee_A_handle/ employee_B_handle /employee_C_handle 三个函数体,可调用的事件接收入口就有3个,需要调用者自行区分,选择合适的事件接收接口,这也是多事件接收器字面意思的效果。

2、组合事件再按单事件接收器模式

employee三人与task三种,有9种组合方式,直接将有限的9种方式定为枚举值,就是个简单的单事件接收器模式了,只是代码处理上,每个case内重复的代码比较多而已。这只是适合组合类型比较少的情形,将多事件接收器模式降维度,简化为前一节的单事件接收器模式。

3、建立二维表

这种实现方式就是下一节的状态表模式。通过将状态逻辑分组,降为单事件接收器模式处理。例如MTK方案的锂电池脉冲充电管理,因为充电状态有很多状态,每个状态下充电是间歇性脉冲充电,充或者不充再分2个子状态,采用的正是这种方案。

本质上多事件接收器模式,可以采用单事件接收器模式或者状态表模式实现,这样的前提是事件参数类似,结构相同。如果不同事件传入的参数格式差异很大,很难统一;例如事件1需要2个int参数,事件2需要3个char数组为参数,直接按参数类型划分多个接口,不必强行参数封装统一。不同的事件处理分不同的接收器接口,也就是多事件接收器模式的特点。拆分为多个事件接收有利于传参,但要求使用者从多个接口中选择正确的。

4.4 状态表模式

状态表模式是没有嵌套状态机创建的模式,其效果类似表驱动法,状态表模式使用二维数组来存储状态转换信息,通常用状态--事件构建表格。状态表模式的状态间不存在逻辑关系,属于并行的扁平化状态,也就是任意状态在任意时刻的表现一致,状态切换与当前状态无关。

状态表模式的执行,直接通过当前的状态和事件组合来索引,调用前必须先初始化状态表。它也比其他模式更易于扩展,因为扩展只是按规则添加新元素到状态表。毕竟嵌入式设备,状态的类型必然是有限的,状态表可以使用静态方式存储,虽然浪费但实现简单。

//微信公众号:嵌入式系统
//代码只是表意,无法编译
typedef void (* pfun_task_handle)(void);

pfun_task_handle employee_task_table[3][3]={
    {employeeA_task1,employeeA_task2,employeeA_task3},
    {employeeB_task1,employeeB_task2,employeeB_task3},
    {employeeC_task1,employeeC_task2,employeeC_task3},
};

//employee和task定为枚举值
//做好函数指针非空校验
void task_allocation(employee,task)
{
 employee_task_table[employee][task]();
}

这种模式非常适合同步状态机切换,如果是异步场景,最好使用队列模式组合处理。

4.5 分解与状态模式

前面的状态机中,元素始终正好处于某个状态之中,而且是一个确切的状态,这样的状态称为或状态。但实际场景也存在复杂的,例如交通信号灯,它有两个独立的属性:

颜色 :红Red、黄Yellow、绿Green  三种 

显示样式 :熄灭off 、长亮Steady、快闪Flashing quickly 、慢闪Flashing slowly 四种。

这个灯有10种(10=3x3+1)状态,因为off关闭状态,灯的颜色属性已经没必要参考了。这种独立状态乘到一起,形成一个可能巨大的状态集合很常见,解决这类问题的方法一一与状态。这里仅仅作阉割版介绍,状态机的状态,并不一定只是一个属性或枚举值解决,也可以是多个正交属性组合,这种状态需要多个参数来描述,可以在单事件接收器模式上增加状态参数。

理论与实际的差距,一直做GPS卫星定位器,设备含RGB三颗LED,3颗灯除独立工作指示特定状态外,还有组合状态,例三颗共同闪亮多次后恢复先前独立的闪亮状态,代码维护其实很复杂,扩展性并不好。关于状态机,如果状态之间有关联,存在优先级或者组合,不管什么模式代码都会比较难维护;只能说结合产品通用需求做个伪标准化接口。可见理论和实际还是存在较大差距的。

4.6 小结

状态机实现的模式,每一个都有优点和缺点,使用哪一个完全依赖于需求。

单事件接收器模式使用单一事件接收器,并且内部用大的 switch - case 语句实现状态行为。它需要创建并传递给接收器事件相关联的类型,最简单易用。

多事件接收器模式为每个事件使用单独的事件处理程序,以便事件类型不用明确指出,适合不同的参数类型匹配不同的事件接收器。

状态表模式可以扩展到大型的状态空间,并且提供与状态空间大小独立的性能,对较大状态空间支持较好。

分解与状态模式提供简单的实现与状态的方法(难通用待学习)。

5、安全性与可靠性类设计模式

安全性是指不会引起人或者设备危险的系统,即危险的严重性后果,和发生的可能性;可靠性用于衡量系统的“可服务时间”或者“可用性”。没有所谓的“安全软件”,因为嵌入式系统是电子、机械、软件在不同操作下的复合体 ,安全、稳定只是特定场合的运行结果。

嵌入式系统的安全性和可靠性,除去硬件防护方案外,软件上也可以采用一些防御性编程,实现系统的安全可靠以及异常恢复。主要从数据校验、备份两方面来入手。这里的解决方案其实也算是软件开发技巧,不是严格意义上的设计模式。

5.1 二进制反码模式

二进制反码模式在检测由于外界影响或者硬件故障内存损坏时很有用。

可能由 EMI (Electro-magnetic interference ,电磁干扰) 、热量、硬件故障、软件故障或者其他外部原因引发内存位损坏。这个模式将重要存储两份,一份以正常形式,而另一份以二进制反码〈~ 操作符计算位反转,逐位取反) 形式。读取数据时,二进制反码格式再次取反,并且与正常形式值比较。如果值完全相同则返回那个值,否则随之处理错误。

该模式提供可靠的方式识别影响单一内存分配的故障,非常适合数据量小但非常重要的数据存储,但对于非常大的数据结构,复制两份数据浪费硬件资源。在这种情况下使用数据流校验数据的正确性更合适。

一些非常关键的信息,如使用uint8_t变量表示某个状态,一般可设0和非0两种状态,假设原本的非0为1,但因为异常被改为2,软件是无能为力的。但如果使用二进制反码模式,使用0x55和0xAA为两种正常状态,其他为异常状态,这样软件的处理上就更加安全健壮。

5.2 数据流校验模式

数据流校验模式解决各种原因导致的变量损坏的问题,如环境因素 (EMI、热量、辐射) 、硬件因素(电源波动、内存单元故障、地址线短流路) 或者是软件故障 〈其他修改内存的软件错误) ,针对大型数据集合中的数据损坏问题。

简单说就是对数据进行校验,计算其和、CRC、MD5或者SHA哈希值等,如果数据中间出现异常被篡改,校验值可以发现错误,但是不能解决错误。考虑到硬件资源限制,一般用CRC16校验。将原始数据和其CRC16值一并存储。使用前通过校验值确认数据是否被篡改。

5.3 魔数标记模式

如果前面两种方式适合数据存储,如果只是单纯的内存数据块校验,可以简单粗暴的增加魔数标记。例如一个大结构体,首尾增加字段,正常情况下将其赋一个特殊值,如果使用中存在内存覆盖或者操作越界,导致首尾标记的数据出现变化,则表示内存出现严重问题。

//微信公众号:嵌入式系统
typedef struct
{

    uint16_t magic_head;
    int32_t  importance1;
    uint8_t  importance2[5];
    uint16_t magic_tail;
} cutomer_data_struct;

//magic_head或magic_tail发生变化说明内存操作出现问题

对于动态内存申请也可以采用这种方式,期望申请N字节时多申请6个字节(举例而已),

magic_head申请长度有效堆区magic_tail
0x1234N实际可用区域0x1234

如果magic_head和magic_tail不是0x1234,说明动态申请的区域使用越界。可以参考动态内存管理及防御性编程。

有些芯片SDK代码,对flash的写保护,或者看门狗喂狗接口,其写法也类似,将一个特殊的值写给寄存器才算正常,也是基于这类考虑。魔法数在应用开发中尽量使用枚举值来替代,但也因为魔法数的特殊性,在安全方面可以避免误操作。

5.4 智能数据模式

软件为了正确执行功能都有前置条件,但是这些功能并没有明确地检查条件实际上是否满足,在合适的位置使用主动防卫的方式来检查参数,智能数据模式即为标量数据元素编写这种范例。

嵌入式C在函数层面,运行时对参数的范围不会检查,这是其固有的不安全性,需要使用者主动去对传入的参数进行范围检查,对函数的返回值进行结果判断。

智能数据模式简化就是对数据前置条件和规则的自检,属于习惯 (小模式)范围,创建或者启动时对参数自检,对传入的参数值进行范围检查,以及多个参数间的组合合理性检查,对运行的返回值进行错误处理。所有错误码以枚举类型展示,或者直接字符描述以使意图理解更加清晰。

智能数据模式优点是数据能自我保护,缺点是执行操作的性能开销 。一般只在针对核心功能、人机交互等,引入的错误容易产生严重后果的地方处理。

最典型最简单的应用场景就是对传入的指针参数进行非空判断,这里推荐合理的使用const限定参数。

5.5 单通道模式

通道模式使用中等规模或者大型的冗余来帮助识别何时发生运行时故障,并且可能 (依赖于怎样实现) 在故障存在时持续提供服务。

通道是体系结构,包含执行端到端处理的软件(可能有硬件),也就是说通过一系列的数据处理步骤,将关键部分独立化。例如数据流可以定为数据采集-处理-执行一条龙服务,基于事件的驱动。安全性和可靠性通过在通道的关键点增加检查得到增强,可能需要一些额外的硬件。由于仅有单一通道,因此该模式将在出现持续故障时,不能继续完成功能,但是它可检测并可能处理临时故障。

这里不提供代码范例,只是提供一种思路,关键部分单独处理,分步执行,不要耦合其他逻辑,对各步骤中的中间信息增加范围校验,识别异常并尽可能进行自我恢复处理。

5.6 双通道模式

双通道模式是一种通过提供多个通道提高稳定性的主要模式,从而在架构层解决冗余问题。比如体温计检测与显示,单通道到数据采集-处理-显示,双通道就可能是2颗传感器各自独立采集,再合并处理后显示。

如果通道是相同的(叫做同构冗余通道),能够解决随机故障 (偶尔失效) ,但是不能解决系统故障 (错误) 。如果通道使用不同的设计或者实现,称为异构冗余模式(也称为多样设计模式),能够解决随机和系统故障。

双通道模式对单个点 (失效或者是失效与错误,这依赖于选择的具体子模式) 故障提供保护。系统可能通过与另一个通道比较来检测一个通道中的错误,然后转换故障到安全状态,或者它可能使用其他的手段检测一个通道的故障,并且 当故障发生时,转换到另外一个。

这种双备份机制,通过复制通道以解决与安全性和可靠性相关的故障,通常也需要大量的硬件复制,以致非常高硬件成本。如果通道是相同的,则所有的复制品包含相同的错误,因此将在相同的环境下出现错误。一般是实施策略是两个通道的管理实现也不相同。两个通道能够同时运行,并且互相检查,如果在临界值上输出不同,系统则转换到故障安全状态。另外,一个通道可以运行直到检测到错误,并且开启另外一个通道,允许故障出现时持续提供服务。不同模式的变体,有不同的硬件成本和效果。

  1. 同构冗余模式   不同的通道使用相同的设计和实现,可以有效地解决单一点的错误,该模式变体有相对较高的生产成本 ,但是有相对低的设计成本 〈因为两个通道仅需设计一次,复制一次) 。

  2. 异构冗余模式   使用不同设计或者不同实现的双通道来解决随机和系统故障,系统能够在出现故障时持续提供服务。该模式变体不仅有相对较高的生产成本,而且有相对高的设计成本(因为两个个通道需设计两套方案) 。硬件、软件方案都不同,但独立且不同的方案解决随机和系统错误。

  3. 三模块冗余 (TMR ) 模式   使用相同设计的 3 个通道来解决故障,应用的理论是,如果有单一点故障,则通道中的一个将与另外两个解约,并且丢弃异常值。系统可以在出现故障时持续提供服务,提供故障在单一通道内适当的隔离。该模式有很高的生产成本,因为通道必须复制 3 次。如果所有的通道有相同的设计 (很常见) ,则设计成本相对低,如果通道的设计不同,则该模式变体的成本非常高,因为每个通道必须设计 3 次。这种在航空、军工电子学领域很常见的。

  4. 完整性检查模式   使用两个同构通道,一个是主执行通道,另一个使用低精确计算的轻量级通道,如果低精确检查通道检测到主通道有故障,则系统进入故障安全状态。该模式有低生产成本并且中等的设计成本,因为它需要额外的设计工作,但是有较低的精确冗余,当出现单一故障时不能继续提供服务。

  5. 监视器-执行器模式   使用两个额外同构通道,第一个就如在完整性检查模式那样,是一个执行通道,这个通道提供系统服务;第二个通道使用一个或多个独立的传感器监视执行通道的物理结果。如果执行通道有故障,并且执行不正确,则监视器通道识别它,并能够命令系统进入故障安全状态。如果监视器通道有故障,则执行器通道仍然执行正确行为。

多通道模式是个系统工程,不能仅依靠软件就实现,它是嵌入式设备安全和可靠性风险的最佳解决方案,但是成本也相应增加。一般的民用消费电子不会采纳。但是了解这些模式,也可能从软件方面、需求角度进行一定的优化。例如一般车载定位器检查汽车是否有行驶,可以依靠ACC点火,加速度传感器信息,GPS定位信息,虽然没有很明显的交代这是异构三通道,但设备本身支持这些信息的采集,软件层面上就可以组合这三种信息,合并分析得出汽车的状态。

5.7 小结

前面的模式在应用范围上 ,通常称为“设计定式”而不是“设计模式”,但合理的应用可提高设备在操作环境中的安全性和可靠性。

6、总结

天下武功,唯快不破。嵌入式设备因为其特殊性,物料更换、市场先机、订单交期、需求变更,都与软件开发存在关联,一般情况下,凡是软件能勉强解决的就不算增加成本,这种思路下软件开发就处于试验性开发、混乱下迭代的恶性循环,最终导致产品功能看起来都正常,而源码惨不忍睹。

实际上一个产品系列,开发很少奇技淫巧,更多的是修修补补、维护迭代,原创性开发不多;可阅读性和扩展性才是重点。而设计模式,就是在尽可能在局部采用特定的思路,去兼容不同的需求,让代码更好阅读,让下一个接手的人可以很容易的去支持更多奇葩需求。

PS

因为时间问题,嵌入式软件设计模式全文显得虎头蛇尾,下半章未使用源码范例具体说明,但实现的思路有描述清楚,设计模式本身就是重思想而不是套路。

END

来源:嵌入式系统

版权归原作者所有,如有侵权,请联系删除。

推荐阅读
曾经对程序员最好的公司,倒下了…
一款活跃了17年的开发工具,好用到起飞~
单片机只会调库和复制别人的代码是什么水平?

→点关注,不迷路←

嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • 随着智能驾驶时代到来,汽车正转变为移动计算平台。车载AI技术对存储器提出新挑战:既要高性能,又需低功耗和车规级可靠性。贞光科技代理的紫光国芯车规级LPDDR4存储器,以其卓越性能成为国产芯片产业链中的关键一环,为智能汽车提供坚实的"记忆力"支持。作为官方授权代理商,贞光科技通过专业技术团队和完善供应链,让这款国产存储器更好地服务国内汽车厂商。本文将探讨车载AI算力需求现状及贞光科技如何通过紫光国芯LPDDR4产品满足市场需求。 车载AI算力需求激增的背景与挑战智能驾驶推动算力需求爆发式
    贞光科技 2025-05-07 16:54 128浏览
  • 文/郭楚妤编辑/cc孙聪颖‍相较于一众措辞谨慎、毫无掌舵者个人风格的上市公司财报,利亚德的财报显得尤为另类。利亚德光电集团成立于1995年,是一家以LED显示、液晶显示产品设计、生产、销售及服务为主业的高新技术企业。自2016年年报起,无论业绩优劣,董事长李军每年都会在财报末尾附上一首七言打油诗,抒发其对公司当年业绩的感悟。从“三年翻番顺大势”“智能显示我第一”“披荆斩棘幸从容”等词句中,不难窥见李军的雄心壮志。2012年,利亚德(300296.SZ)在深交所创业板上市。成立以来,该公司在细分领
    华尔街科技眼 2025-05-07 19:25 117浏览
  • 某国产固态电解的2次和3次谐波失真相当好,值得一试。(仅供参考)现在国产固态电解的性能跟上来了,值得一试。当然不是随便搞低端的那种。电容器对音质的影响_电子基础-面包板社区  https://mbb.eet-china.com/forum/topic/150182_1_1.html (右键复制链接打开)电容器对音质的影响相当大。电容器在音频系统中的角色不可忽视,它们能够调整系统增益、提供合适的偏置、抑制电源噪声并隔离直流成分。然而,在便携式设备中,由于空间、成本的限
    bruce小肥羊 2025-05-04 18:14 231浏览
  • 2024年初,OpenAI公布的Sora AI视频生成模型,震撼了国产大模型行业。随后国产厂商集体发力视频大模型,快手发布视频生成大模型可灵,字节跳动发布豆包视频生成模型,正式打响了国内AI视频生成领域第一枪。众多企业匆忙入局,只为在这片新兴市场中抢占先机,却往往忽视了技术成熟度与应用规范的打磨。以社交平台上泛滥的 AI 伪造视频为例,全红婵家人被恶意仿冒博流量卖货,明星们也纷纷中招,刘晓庆、张馨予等均曾反馈有人在视频号上通过AI生成视频假冒她。这些伪造视频不仅严重侵犯他人权
    用户1742991715177 2025-05-05 23:08 78浏览
  • 浪潮之上:智能时代的觉醒    近日参加了一场课题的答辩,这是医疗人工智能揭榜挂帅的国家项目的地区考场,参与者众多,围绕着医疗健康的主题,八仙过海各显神通,百花齐放。   中国大地正在发生着激动人心的场景:深圳前海深港人工智能算力中心高速运转的液冷服务器,武汉马路上自动驾驶出租车穿行的智慧道路,机器人参与北京的马拉松竞赛。从中央到地方,人工智能相关政策和消息如雨后春笋般不断出台,数字中国的建设图景正在智能浪潮中徐徐展开,战略布局如同围棋
    广州铁金刚 2025-04-30 15:24 375浏览
  • 多功能电锅长什么样子,主视图如下图所示。侧视图如下图所示。型号JZ-18A,额定功率600W,额定电压220V,产自潮州市潮安区彩塘镇精致电子配件厂,铭牌如下图所示。有两颗螺丝固定底盖,找到合适的工具,拆开底盖如下图所示。可见和大部分市场的加热锅一样的工作原理,手绘原理图,根据原理图进一步理解和分析。F1为保险,250V/10A,185℃,CPGXLD 250V10A TF185℃ RY 是一款温度保险丝,额定电压是250V,额定电流是10A,动作温度是185℃。CPGXLD是温度保险丝电器元件
    liweicheng 2025-05-05 18:36 253浏览
  • 你是不是也有在公共场合被偷看手机或笔电的经验呢?科技时代下,不少现代人的各式机密数据都在手机、平板或是笔电等可携式的3C产品上处理,若是经常性地需要在公共场合使用,不管是工作上的机密文件,或是重要的个人信息等,民众都有防窃防盗意识,为了避免他人窥探内容,都会选择使用「防窥保护贴片」,以防止数据外泄。现今市面上「防窥保护贴」、「防窥片」、「屏幕防窥膜」等产品就是这种目的下产物 (以下简称防窥片)!防窥片功能与常见问题解析首先,防窥片最主要的功能就是用来防止他人窥视屏幕上的隐私信息,它是利用百叶窗的
    百佳泰测试实验室 2025-04-30 13:28 638浏览
  • ‌一、高斯计的正确选择‌1、‌明确测量需求‌‌磁场类型‌:区分直流或交流磁场,选择对应仪器(如交流高斯计需支持交变磁场测量)。‌量程范围‌:根据被测磁场强度选择覆盖范围,例如地球磁场(0.3–0.5 G)或工业磁体(数百至数千高斯)。‌精度与分辨率‌:高精度场景(如科研)需选择误差低于1%的仪器,分辨率需匹配微小磁场变化检测需求。2、‌仪器类型选择‌‌手持式‌:便携性强,适合现场快速检测;‌台式‌:精度更高,适用于实验室或工业环境。‌探头类型‌:‌横向/轴向探头‌:根据磁场方向选择,轴向探头适合
    锦正茂科技 2025-05-06 11:36 376浏览
  • 二位半 5线数码管的驱动方法这个2位半的7段数码管只用5个管脚驱动。如果用常规的7段+共阳/阴则需要用10个管脚。如果把每个段看成独立的灯。5个管脚来点亮,任选其中一个作为COM端时,另外4条线可以单独各控制一个灯。所以实际上最多能驱动5*4 = 20个段。但是这里会有一个小问题。如果想点亮B1,可以让第3条线(P3)置高,P4 置低,其它阳极连P3的灯对应阴极P2 P1都应置高,此时会发现C1也会点亮。实际操作时,可以把COM端线P3设置为PP输出,其它线为OD输出。就可以单独控制了。实际的驱
    southcreek 2025-05-07 15:06 184浏览
  • 想不到短短几年时间,华为就从“技术封锁”的持久战中突围,成功将“被卡脖子”困境扭转为科技主权的主动争夺战。众所周知,前几年技术霸权国家突然对华为发难,导致芯片供应链被强行掐断,海外市场阵地接连失守,恶意舆论如汹涌潮水,让其瞬间陷入了前所未有的困境。而最近财报显示,华为已经渡过危险期,甚至开始反击。2024年财报数据显示,华为实现全球销售收入8621亿元人民币,净利润626亿元人民币;经营活动现金流为884.17亿元,同比增长26.7%。对比来看,2024年营收同比增长22.42%,2023年为7
    用户1742991715177 2025-05-02 18:40 209浏览
  • UNISOC Miracle Gaming奇迹手游引擎亮点:• 高帧稳帧:支持《王者荣耀》等主流手游90帧高画质模式,连续丢帧率最高降低85%;• 丝滑操控:游戏冷启动速度提升50%,《和平精英》开镜开枪操作延迟降低80%;• 极速网络:专属游戏网络引擎,使《王者荣耀》平均延迟降低80%;• 智感语音:与腾讯GVoice联合,弱网环境仍能保持清晰通话;• 超高画质:游戏画质增强、超级HDR画质、游戏超分技术,优化游戏视效。全球手游市场规模日益壮大,游戏玩家对极致体验的追求愈发苛刻。紫光展锐全新U
    紫光展锐 2025-05-07 17:07 170浏览
  • 5小时自学修好BIOS卡住问题  更换硬盘故障现象:f2、f12均失效,只有ESC和开关机键可用。错误页面:经过AI的故障截图询问,确定是机体内灰尘太多,和硬盘损坏造成,开机卡在BIOS。经过亲手拆螺丝和壳体、排线,跟换了新的2.5寸硬盘,故障排除。理论依据:以下是针对“5小时自学修好BIOS卡住问题+更换硬盘”的综合性解决方案,结合硬件操作和BIOS设置调整,分步骤说明:一、判断BIOS卡住的原因1. 初步排查     拔掉多余硬件:断开所有外接设备(如
    丙丁先生 2025-05-04 09:14 118浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦