精华内容
下载资源
问答
  • cppcheck规则编写文档

    2016-12-27 14:02:12
    cppcheck编写自定义规则文档,cppcheck支持自定义规则,通过正则表达式编写检查规则
  • MySQL 8.0 新特性之检查约束(CHECK

    千次阅读 多人点赞 2020-06-05 14:52:42
    介绍 MySQL 8.0 增加的新功能:检查约束(CHECK ),定义列级检查约束和表级检查约束,检查约束的 enforced 选项,检查约束的使用限制。

    大家好,我是只谈技术不剪发的 Tony 老师。这次我们来介绍一个 MySQL 8.0 增加的新功能:检查约束(CHECK )。

    SQL 中的检查约束属于完整性约束的一种,可以用于约束表中的某个字段或者一些字段必须满足某个条件。例如用户名必须大写、余额不能小于零等。

    我们常见的数据库都实现了检查约束,例如 Oracle、SQL Server、PostgreSQL 以及 SQLite;然而 MySQL 一直以来没有真正实现该功能,直到最新的 MySQL 8.0.16。

    MySQL 8.0.15 之前

    在 MySQL 8.0.15 以及之前的版本中,虽然 CREATE TABLE 语句允许CHECK (expr)形式的检查约束语法,但实际上解析之后会忽略该子句。例如

    mysql> select version();
    +-----------+
    | version() |
    +-----------+
    | 8.0.15    |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE t1
        -> (
        ->   c1 INT CHECK (c1 > 10),
        ->   c2 INT ,
        ->   c3 INT CHECK (c3 < 100),
        ->   CONSTRAINT c2_positive CHECK (c2 > 0),
        ->   CHECK (c1 > c3)
        -> );
    Query OK, 0 rows affected (0.33 sec)
    
    mysql> show create table t1\G
    *************************** 1. row ***************************
           Table: t1
    Create Table: CREATE TABLE `t1` (
      `c1` int(11) DEFAULT NULL,
      `c2` int(11) DEFAULT NULL,
      `c3` int(11) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
    1 row in set (0.00 sec)
    

    虽然我们在定义时指定了各种 CHECK 选项,但最终的表结构中不包含任何检查约束。这也意味着我们可以插入非法的数据:

    mysql> insert into t1(c1, c2, c3) values(1, -1, 100);
    Query OK, 1 row affected (0.06 sec)
    

    如果我们想要在 MySQL 8.0.15 之前实现类似的检查约束,可以使用触发器;或者创建一个包含 WITH CHECK OPTION 选项的视图,然后通过视图插入或修改数据。

    MySQL 8.0.16 之后

    MySQL 8.0.16 于 2019 年 4 月 25 日发布,终于带来了我们期待已久的 CHECK 约束功能,而且对于所有的存储引擎都有效。CREATE TABLE 语句允许以下形式的 CHECK 约束语法,可以指定列级约束和表级约束:

    [CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]
    

    其中,可选的 symbol 参数用于给约束指定一个名称。如果省略该选项,MySQL 将会产生一个以表名开头、加上 _chk_ 以及一个数字编号(1、2、3 …)组成的名字(table_name_chk_n)。约束名称最大长度为 64 个字符,而且区分大小写。

    expr 是一个布尔表达式,用于指定约束的条件;表中的每行数据都必须满足 expr 的结果为 TRUE 或者 UNKNOWN(NULL)。如果表达式的结果为 FALSE,将会违反约束。

    可选的 ENFORCED 子句用于指定是否强制该约束:

    • 如果忽略或者指定了 ENFORCED,创建并强制该约束;
    • 如果指定了 NOT ENFORCED,创建但是不强制该约束。这也意味着约束不会生效。

    CHECK 约束可以在列级指定,也可以在表级指定。

    列级检查约束

    列级约束只能出现在字段定义之后,而且只能针对该字段进行约束。例如:

    mysql> select version();
    +-----------+
    | version() |
    +-----------+
    | 8.0.16    |
    +-----------+
    1 row in set (0.00 sec)
    
    mysql> CREATE TABLE t1
        -> (
        ->   c1 INT CHECK (c1 > 10),
        ->   c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
        ->   c3 INT CHECK (c3 < 100)
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> show create table t1\G
    *************************** 1. row ***************************
           Table: t1
    Create Table: CREATE TABLE `t1` (
      `c1` int DEFAULT NULL,
      `c2` int DEFAULT NULL,
      `c3` int DEFAULT NULL,
      CONSTRAINT `c2_positive` CHECK ((`c2` > 0)),
      CONSTRAINT `t1_chk_1` CHECK ((`c1` > 10)),
      CONSTRAINT `t1_chk_2` CHECK ((`c3` < 100))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    其中,字段 c1 和 c3 上的检查约束使用了系统生成的名称;c2 上的检查约束使用了自定义名称。

    📝SQL 标准中所有的约束(主键、唯一约束、外键、检查约束等)都属于相同的命名空间,意味着它们相互不能重名。但在 MySQL 中,每个数据库中的约束类型属于自己的命名空间;因此,主键和检查约束可以重名,但是两个检查约束不能重名。

    我们插入一条测试数据:

    mysql> insert into t1(c1, c2, c3) values(1, -1, 100);
    ERROR 3819 (HY000): Check constraint 'c2_positive' is violated.
    

    插入数据的三个字段都违反了约束,结果显示的是违反了 c2_positive;因为它按照名字排在第一,由此也可以看出 MySQL 按照约束的名字排序依次进行检查。

    我们再插入一条测试数据:

    mysql> insert into t1(c1, c2, c3) values(null, null, null);
    Query OK, 1 row affected (0.00 sec)
    

    数据插入成功,所以 NULL 值并不会违反检查约束。

    表级检查约束

    表级约束独立于字段的定义,而且可以针对多个字段进行约束,甚至可以出现在字段定义之前。例如:

    mysql> drop table t1;
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> CREATE TABLE t1
        -> (
        ->   CHECK (c1 <> c2),
        ->   c1 INT,
        ->   c2 INT,
        ->   c3 INT,
        ->   CONSTRAINT c1_nonzero CHECK (c1 <> 0),
        ->   CHECK (c1 > c3)
        -> );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> show create table t1\G
    *************************** 1. row ***************************
           Table: t1
    Create Table: CREATE TABLE `t1` (
      `c1` int DEFAULT NULL,
      `c2` int DEFAULT NULL,
      `c3` int DEFAULT NULL,
      CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)),
      CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)),
      CONSTRAINT `t1_chk_2` CHECK ((`c1` > `c3`))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    第一个约束 t1_chk_1 出现在字段定义之前,但是仍然可以引用 c1 和 c2;第二个约束 c1_nonzero 使用了自定义的名称;第三个约束 t1_chk_2 在所有字段定义之后。

    我们同样插入一些测试数据:

    mysql> insert into t1(c1, c2, c3) values(1, 2, 3);
    ERROR 3819 (HY000): Check constraint 't1_chk_2' is violated.
    
    mysql> insert into t1(c1, c2, c3) values(null, 2, 3);
    Query OK, 1 row affected (0.01 sec)
    

    第一条记录中的 c1 小于 c3,违反了检查约束 t1_chk_2;第二条记录中的 c1 为 NULL,检查约束 t1_chk_2 的结果为 UNKNOWN,不违法约束。

    强制选项

    使用默认方式或者 ENFORCED 选项创建的约束处于强制检查状态,我们也可以将其修改为 NOT ENFORCED,从而忽略检查:

    ALTER TABLE tbl_name
    ALTER {CHECK | CONSTRAINT} symbol [NOT] ENFORCED
    

    修改之后的检查约束仍然存在,但是不会执行检查。例如:

    mysql> alter table t1 
        -> alter check t1_chk_1 not enforced;
    Query OK, 0 rows affected (0.02 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    mysql> show create table t1\G
    *************************** 1. row ***************************
           Table: t1
    Create Table: CREATE TABLE `t1` (
      `c1` int DEFAULT NULL,
      `c2` int DEFAULT NULL,
      `c3` int DEFAULT NULL,
      CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)),
      CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)) /*!80016 NOT ENFORCED */,
      CONSTRAINT `t1_chk_2` CHECK ((`c1` > `c3`))
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8
    1 row in set (0.00 sec)
    

    从最新的定义可以看出,t1_chk_1 处于 NOT ENFORCED 状态。我们插入一条违反该约束的数据:

    mysql> insert into t1(c1, c2, c3) values(1, 1, 0);
    Query OK, 1 row affected (0.01 sec)
    

    该记录的 c1 和 c2 相等,但是插入成功。

    如果我们需要迁移一些低版本的历史数据时,它们可能会违反新的检查约束;此时可以先将该约束禁用,等数据迁移并处理完成之后,再次启用强制选项。

    检查约束限制

    MySQL 中的 CHECK 条件表达式必须满足以下规则,否则无法创建检查约束:

    • 允许使用非计算列和计算列,但是不允许使用 AUTO_INCREMENT 字段或者其他表中的字段。
    • 允许使用字面值、确定性内置函数(即使不同用户,多次调用该函数,只要输入相同结果就相同)以及运算符。非确定性函数包括:CONNECTION_ID()、CURRENT_USER()、NOW() 等等,它们不能用于检查约束。
    • 不允许使用存储函数或者自定义函数。
    • 不允许使用存储过程和函数参数。
    • 不允许使用变量,包括系统变量、用户定义变量和存储程序的局部变量。
    • 不允许使用子查询。

    另外,禁用在 CHECK 约束字段上定义外键约束的参照操作(ON UPDATE、ON DELETE);同理,存在外键约束参照操作的字段上也不允许创建 CHECK 约束。

    对于 INSERT、UPDATE、REPLACE、LOAD DATA 以及 LOAD XML 语句,如果违反检查约束将会返回错误。此时,对于已经修改的数据处理取决于存储引擎是否支持事务,以及是否使用了严格 SQL 模式

    对于 INSERT IGNORE、UPDATE IGNORE、REPLACE、LOAD DATA … IGNORE 以及 LOAD XML … IGNORE 语句,如果违反检查约束将会返回警告并且跳过存在问题的数据行。

    如果约束表达式的结果类型和字段的数据类型不同,MySQL 将会执行隐式类型转换;如果类型转换失败或者丢失精度,将会返回错误。

    总结

    MySQL 8.0.16 新增的检查约束提高了 MySQL 实现业务完整性约束的能力,也使得 MySQL更加遵循 SQL 标准。😎

    如果觉得文章对你有用,请不要白嫖!欢迎关注❤️、评论📝、点赞👍!

    展开全文
  • mysqlcheck.exe

    2012-11-10 14:50:38
    mysqlcheck.exe放入bin文件夹
  • 适用myeclipse10.1-10.7,亲测10.7有效.其他版本不能用时给我留言,留下邮箱,我给发.
  • Oracle Check约束

    千次阅读 2019-01-08 20:53:53
    最近做一份数据库的任务,发现MySQL中不支持在创建表定义字段时使用check约束,如果要在MySQL中使用类似字段约束取值,有两种方式:1.枚举enum,2.创建触发器 MySQL关于check约束无效的解决办法 下面正式记录一下...

    最近做一份数据库的任务,发现MySQL中不支持在创建表定义字段时使用check约束,如果要在MySQL中使用类似字段约束取值,有两种方式:1.枚举enum,2.创建触发器

    MySQL关于check约束无效的解决办法

    下面正式记录一下,Oracle数据库各种各样的check约束的使用方法

    引用: https://www.cnblogs.com/ChineseIntelligentLanguage/p/6513282.html

    1.检查约束 ( check )
      某列取值范围限制、格式限制等
      
    2.检查只能是男或者女

    create table test29(         
    	id number primary key, 
        sex varchar2(2) check(sex in ('男,女'))  
     );   
    
    create table test30(         
         id number primary key,         
         sex varchar2(2) check(sex ='男' or sex='女')  
    );    
    
    create table test31(         
         id number primary key,         
         sex varchar2(2)  
       );  
    
    alter table test31 add constraint chkk check (sex ='男' or sex='女');  
    alter table test31 add constraint chkk check (sex in('男','女'));  
    

    3.在一个范围中间

    create table test32(       
          id number primary key,       
          age number check(age>0 and age<120)
       );
    create table test33(       
           id number primary key,       
          age number check(age between 12 and 30)
       );
       create table test34(       
            id number primary key ,       
            age number
       );
       alter table test34 add constraint ch_test34 check(age>0 and age<120);
       alter table test34 add constraint ch_test34 check(age between 12 and 30);  
    

    4.长度大于某个值

    create table test35(       
              id number primary key,       
              password varchar2(10) check(length(password)=6)
       );
       
    create table test36(       
              id number primary key ,       
          password varchar2(20)
       );
      alter table test36 add constraint check_test36 check(length(password)=6);
    

    5.数大于某个值

    create table test37(      
         id number(10)primary key ,      
         no number(10) check(no>1) 
       );
       
    create table test38(       
          id number(10) primary key,      
          no number(10)
       );
    alter table test38 add constraint ch_test38 check(no>1);
    

    6.只能是8位字符,前两位是 0 ,3~4位为数字,第 5 位为"_"下划线,6~8位为字母

    create table test39(       
           id number(10) primary key,       
           password varchar2(20) check((password like '00[0-9][0-9]/_[a-z,A-Z][a-z,A-Z][a-z,A-Z]%' escape '/')and(length(password)=8) )
       );
       insert into test39 values (1,'0011_aaa');
       
       create table test40(       
            id number(10) primary key ,       
            password varchar2(10)check((password like '00[0-9][0-9][_][a-z,A-Z][a-z,A-Z][a-z,A-Z]%')and(length(password)=8) ));
       );
       alter table test40 modify password varchar2(10)check((password like '00[0-9][0-9][_][a-z,A-Z][a-z,A-Z][a-z,A-Z]%')and(length(password)>1) 
       insert into test40 values(1,'0012_abc');
    

    7.电子邮箱要含有@符号check(字段 like ‘%@%’)

     create table test41(       
              id number(10) primary key,       
              email varchar2(10) check (email like '%@%') 
        );
        insert into test41 values(1,'12@126.com');
    

    8.SQL中用check约束一列的首字母为’s’check(字段 like ‘s%’)

    create table test42(       
            id number(10) primary key ,       
            name varchar2(10) check(name like 's%')
         );
     insert into test42 values(1,'sname');
    

    9.检查约束前3位和后8位均为数字字符:
    check(字段 like ‘[0-9][0-9][0-9]%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]’)

    create table test43(       
             id number(10) primary key,       
             no varchar2(10)check(no like '[0-9][0-9][0-9]%[0-9][0-9][0-9][0-9][0-9]')
     );
     insert into test43 values(1,'12345678');
    

    10.如何建立检查身份证的约束,身份证是18位,最后一位还有可能是X

     create table test44(       
       id number(10) primary key,       
       no values(18) check( length(no)=18 and right(no,17)like '[0-9]' or right (no,17) like 'x' )
     );
    insert into test44 values (1,'12345678912345678x');
    
    select 身份证号 from 表名where len(身份证号) = 18 and (right(身份证号,17) like  '[0-9]'or right(身份证号,17) like 'x')
    

    11.如何设置区号由0-9之间的数字组成CONSTRAINT

    quhao CHECK (quhao  LIKE '[0-9][0-9][0-9]' 
    or quhao LIKE '[0-9][0-9][0-9][0-9]'
    or quhao LIKE '[0-9][0-9][0-9][0-9][0-9]'));
    

    解释:quhao LIKE '[0-9]…[0-9]'的号码由表示n位从0到9中的数组成。
    quhao LIKE ‘[0-9][0-9][0-9]’ 表示3位的区号,如北京010;
    quhao LIKE '[0-9][0-9][0-9][0-9]'表示4位的区号,如三门峡0398;
    quhao LIKE '[0-9][0-9][0-9][0-9][0-9]'表示5位的区号,如香港00852

    12.最后回复时间 TLastClickT 发贴时间 TTime最后回复时间 必须晚于 发贴时间 并且小于等于当前时间

    使用GetDate()函数获取当前时间
    设计表在TLastClickT上右击选择约束,新建,
    填入([TLastClickT] > [TTime] and [TLastClickT] < GetDate())
    或者TiastReply(回帖时间)大于Ttime(发帖时间)
    在创表的同时创建表的时候应该还没有回帖吧,为什么要用默认值?
    可以添加一个约束 
    alter table topic alter column add check(TlastReply is null or TlastReply > Ttime)
    

    13.定义前八位为数字或者 -一共是15位,为CHAR型

    alter table 表名add constraint chk check(字段 like'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'),    
     constraint chklen check(len(字段)=15)    
    

    14.如何限制varchar字段不允许出现单引号的检查约束 !!!
    设表为TALBENAME,不能有引号的字段为FIELDNAME 则:

    ALTER TABLE tablename ADD CONSTRAINT CK_fieldname CHECK (not fieldname like '%''%')
    

    15.在表中的某列中通过检查约束,让其有某些固定的值

     check(sid like 'bd[0-9][0-9][0-9][0-9][0-9][0-9]')
         add const ck_num check(num like '[1][2] [4][_] [0-9][0-9] [0-9][a-z]')
    

    16.如何限制varchar字段不允许出现字符串的检查约束 !!!

    设表名为TABLENAME,VARCHAR类型的字段为VAR_FIELD.则有:
     ALTER TABLE [dbo].[TABLENAME] 
     ADD CONSTRAINT [CK_TABLENAME] 
     CHECK (isnumeric([VAR_FIELD]) = 1)
     这样,在VAR_FIELD只要出现字段一旦出现非数字内容就会报告错误。
    

    17.电话号码的格式必须为xxxx-xxxxxxxx或手机号11位

     alter 表名 add constraint ck_字段名 check (字段 like '[0-9][0-9][0-9][0-9]_[0-9]......' 
     or length(字段)=11)
    

    18.身份证号是18位且唯一的

     alter 表名 add constraint ck_字段名 check (len(字段名)=18 ),
     constraint uk_字段名 unique(字段名)
    
    展开全文
  • MTK平台关于lcm esd check机制的介绍

    千次阅读 2018-12-15 11:42:01
    一、esd check的作用 esd意思是静电释放,在手机领域中,都是有静电标准的。静电的危害也是很明显的,在手机使用过程中可能会因为静电原因造成手机屏幕显示异常,触摸屏失灵,严重点还可能造成死机等现象。因此消除...

    原创文章,转载请注明出处

    一、esd check的作用

    esd意思是静电释放,在手机领域中,都是有静电标准的。静电的危害也是很明显的,在手机使用过程中可能会因为静电原因造成手机屏幕显示异常,触摸屏失灵,严重点还可能造成死机等现象。因此消除静电是一项很重要的工作,有硬件和软件两种措施,这里我们只介绍软件上的处理,即esd check。其实这种方法无法避免esd,只是一种遇到esd时软件上做的一些处理而已。

    二、esd check的两种方式

    mtk平台对于lcm的esd check有两种处理方式,分别是读寄存器方式和外部TE方式

    1、读寄存器方式

    通过读寄存器方式做ESD,只需要在lcm driver里面的lcm_get_params函数中按照如下的方式进行客制化配置就能够正常的run了

    PS:MT6737在ESD读取寄存器时候,只能够识别屏端返回的短包,并且只能够判断一个返回值。如果有LCM IC返回的是长包,或者需要判断多个返回值。

    2、外部TE方式

    该方式是通过CPU irq中断的方式实现的,具体按如下配置既可

    1)lcm driver中的lcm_get_params函数

    2)lcm driver中的lcm_init函数

    关于LCM IC中0x35的说明:

    H-Blanking:在将光信号转换为电信号的扫描过程中,扫描总是从图像的左上角开始,水平向前行进,同时扫描点也以较慢的速率向下移动。当扫描点到达图像右侧边缘时,扫描点快速返回左侧,重新开始在第1行的起点下面进行第2行扫描,行与行之间的返回过程称为H-Blanking。

    V-Blanking:一幅完整的图像扫描信号,由H-Blanking间隔分开的行信号序列构成,称为一帧。扫描点扫描完一帧后,要从图像的右下角返回到图像的左上角,开始新一帧的扫描,这一时间间隔,叫做V-Blanking

    3)项目工程中dct的配置

    三、软件流程

    kernel-3.18\drivers\misc\mediatek\video\mt6735\primary_display.c

    unsigned int _need_do_esd_check(void)	//esd总开关	返回1有效
    {
    	int ret = 0;
    #ifdef CONFIG_OF
    	if ((pgc->plcm->params->dsi.esd_check_enable == 1) && (islcmconnected == 1))
    		ret = 1;
    #else
    	if (pgc->plcm->params->dsi.esd_check_enable == 1)
    		ret = 1;
    #endif
    	return ret;
    }
    
    unsigned int _need_register_eint(void)		//TE模式开关
    {
    	int ret = 1;
    
    	/* 1.need do esd check */
    	/* 2.dsi vdo mode */
    	/* 3.customization_esd_check_enable = 0 */
    	if (_need_do_esd_check() == 0)
    		ret = 0;
    	else if (primary_display_is_video_mode() == 0)
    		ret = 0;
    	else if (pgc->plcm->params->dsi.customization_esd_check_enable == 1)
    		ret = 0;
    
    	return ret;
    }
    
    int primary_display_init(char *lcm_name, unsigned int lcm_fps, int is_lcm_inited)
    {
    ……
    #ifdef MTK_FB_ESD_ENABLE
    	primary_display_esd_check_task = kthread_create(primary_display_esd_check_worker_kthread,
    							NULL, "display_esd_check");    //esd check线程
    	init_waitqueue_head(&esd_ext_te_wq);	//等待队列 用于TE模式
    	init_waitqueue_head(&esd_check_task_wq);	//用于整个esd流程
    	if (_need_do_esd_check())
    		wake_up_process(primary_display_esd_check_task);
    
    	if (_need_register_eint()) {
    		struct device_node *node = NULL;
    		int irq;
    		u32 ints[2] = { 0, 0 };
    	 	node = of_find_compatible_node(NULL, NULL, "mediatek, DSI_TE_1-eint");//获取TE中断信息
    		if (node) {
    			of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints));
    			/* FIXME: find definatition of  mt_gpio_set_debounce */
    			/* mt_gpio_set_debounce(ints[0], ints[1]); */
    			mt_eint_set_hw_debounce(ints[0], ints[1]);
    			irq = irq_of_parse_and_map(node, 0);
    			if (request_irq(irq, _esd_check_ext_te_irq_handler, IRQF_TRIGGER_RISING, 
    "DSI_TE_1-eint", NULL))    //注册TE中断函数
    				DISPMSG("[ESD]EINT IRQ LINE NOT AVAILABLE!!\n");
    			else
    				eint_flag++;
    
    		} else {
    			DISPMSG("[ESD][%s] can't find DSI_TE_1 eint compatible node\n", __func__);
    		}
    	}
    
    
    	if (_need_do_esd_check())
    		primary_display_esd_check_enable(1);    //使能esd check
    
    #endif
    ……
    }
    
    void primary_display_esd_check_enable(int enable)
    {
    	/* check if enable ESD check mechanism first */
    	if (_is_enable_esd_check() != true) {
    		DISPMSG("[ESD]Checking if ESD enable but ESD check mechanism is not enabled.\n");
    		return;
    	}
    
    	if (_need_do_esd_check()) {
    		if (_need_register_eint() && eint_flag != 2) {
    			DISPMSG("[ESD]Please check DCT setting about GPIO107/EINT107\n");
    			return;
    		}
    
    		if (enable) {
    			pr_warn("[DISP][ESD]esd check thread wakeup\n");
    			atomic_set(&esd_check_task_wakeup, 1);    
    			wake_up_interruptible(&esd_check_task_wq);    //唤醒esd check的等待队列
    		} else {
    			DISPMSG("[ESD]esd check thread stop\n");
    			atomic_set(&esd_check_task_wakeup, 0);
    		}
    	}
    }
    
    static int primary_display_esd_check_worker_kthread(void *data)
    {
    	int ret = 0;
    	int i = 0;
    	int esd_try_cnt = 5;	/* 20; */
    	int count = 0;
    	struct sched_param param = {.sched_priority = 87 }; /* RTPM_PRIO_FB_THREAD */
    
    	sched_setscheduler(current, SCHED_RR, &param);
    	dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE);
    	dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_START);
    
    	while (1) {
    		if (count == 0) {
    			count++;
    			msleep(3000);
    		}
    		msleep(2000);	/* esd check every 2s */
    		ret = wait_event_interruptible(esd_check_task_wq, atomic_read(&esd_check_task_wakeup));
    		if (ret < 0) {
    			DISPMSG("[ESD]esd check thread waked up accidently\n");
    			continue;
    		}
    #ifdef DISP_SWITCH_DST_MODE
    		_primary_path_switch_dst_lock();
    #endif
    		_primary_path_cmd_lock();
    		ret = primary_display_esd_check();//esd check核心函数,成功返回0,失败返回1
    		if (ret == 1) {
    			DISPMSG("[ESD]esd check fail, will do esd recovery %d\n", ret);
    			i = esd_try_cnt;
    			while (i--) {
    				DISPMSG("[ESD]esd recovery try:%d\n", i);
    				primary_display_esd_recovery();//esd check失败后会这行recovery操作
    				ret = primary_display_esd_check();//recovery之后再次做esd check
    				if (ret == 0) {//返回0说明recovery成功,退出循环
    					DISPMSG("[ESD]esd recovery success\n");
    					break;
    				}
    				DISPMSG("[ESD]after esd recovery, esd check still fail\n");
    				if (i == 0) {//如果五次recovery都失败则会disable esd check操作,关闭对应线程
    					DISPMSG("[ESD]after esd recovery %d times, esd check still fail,\n",
    						  esd_try_cnt);
    					DISPMSG("disable esd check\n");
    					primary_display_esd_check_enable(0);//
    					primary_display_esd_recovery();
    				}
    			}
    		}
    		_primary_path_cmd_unlock();
    #ifdef DISP_SWITCH_DST_MODE
    		_primary_path_switch_dst_unlock();
    #endif
    		if (kthread_should_stop())
    			break;
    	}
    	return 0;
    }
    
    int primary_display_esd_check(void)
    {
    ……
    	/* Esd Check : EXT TE */
    		if (pgc->plcm->params->dsi.customization_esd_check_enable == 0) {//外部TE方式
    		MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagStart, 0, 0);
    		if (primary_display_is_video_mode()) {
    			……
    				if (_need_register_eint()) {
    				MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagPulse, 1, 1);
    
    				if (wait_event_interruptible_timeout
    				    (esd_ext_te_wq, atomic_read(&esd_ext_te_event), HZ / 2) > 0) {//检查TE中断脚是否有触发中断,如果HZ/2之内没有触发中断,则说明发生了esd
    					ret = 0; /* esd check pass */
    				} else {
    					ret = 1; /* esd check fail */
    					DISPMSG("esd check fail release fence fake\n");
    					primary_display_release_fence_fake();
    				}
    				atomic_set(&esd_ext_te_event, 0);
    			}
    			primary_display_switch_esd_mode(0);
    		} else {
    			……
    		}
    		MMProfileLogEx(ddp_mmp_get_events()->esd_extte, MMProfileFlagEnd, 0, ret);
    		goto done;
    	}
    	/* Esd Check : Read from lcm */
    	……
    		ret = dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_config_esd, 
    CMDQ_ESD_CHECK_CMP);//读寄存器方式
    		if (ret) {
    			ret = 1;	/* esd check fail */
    			DISPMSG("esd check fail release fence fake\n");
    			primary_display_release_fence_fake();
    		} 
    	……
    }
    
    static irqreturn_t _esd_check_ext_te_irq_handler(int irq, void *data)//TE中断函数
    {
    	MMProfileLogEx(ddp_mmp_get_events()->esd_vdo_eint, MMProfileFlagPulse, 0, 0);
    	atomic_set(&esd_ext_te_event, 1);
    	wake_up_interruptible(&esd_ext_te_wq);
    	return IRQ_HANDLED;
    }
    
    int dpmgr_path_build_cmdq(disp_path_handle dp_handle, void *trigger_loop_handle, CMDQ_STATE state)
    {
    ……
    	for ( i=0; i< module_num; i++) {
    		module_name = modules[i];
    		if (ddp_modules_driver[module_name] != 0) {
    			if (ddp_modules_driver[module_name]->build_cmdq!= 0) {
    				DISP_LOG_D("%s build cmdq, state=%d\n",ddp_get_module_name(module_name), state);
    				ddp_modules_driver[module_name]->build_cmdq(module_name, trigger_loop_handle, state); //读寄存器方式,最终会调用build_cmdq成员函数
    			}
    		}
    	}
    	return 0;
    }
    
    H	int ddp_dsi_build_cmdq(DISP_MODULE_ENUM module, void *cmdq_trigger_handle, CMDQ_STATE state)
    {
    ……
    	else if (state == CMDQ_ESD_CHECK_CMP) {
    
    		DISPMSG("[DSI]enter cmp\n");
    		/* cmp just once and only 1 return value */
    		for (i = 0; i < 3; i++) {
    			if (dsi_params->lcm_esd_check_table[i].cmd == 0)
    				break;
    			/* read data */
    			if (hSlot) {
    				/* read from slot */
    				cmdqBackupReadSlot(hSlot, i, ((uint32_t *) &read_data0));
    			} else {
    				/* read from dsi , support only one cmd read */
    				if (i == 0) {
    					DSI_OUTREG32(NULL, &read_data0,
    						     AS_UINT32(&DSI_REG[dsi_i]->DSI_RX_DATA0));
    				}
    			}
    				if (read_data0.byte1 ==
    			    dsi_params->lcm_esd_check_table[i].para_list[0]) {//如果读取原先设置好的寄存器的值与预想的不一样,则判定发生esd
    				/* clear rx data */
    				/* DSI_OUTREG32(NULL, &DSI_REG[dsi_i]->DSI_RX_DATA0,0); */
    				ret = 0;	/* esd pass */
    			} else {
    				ret = 1;	/* esd fail */
    				break;
    			}
    		}
    ……
    }
    
    int primary_display_esd_recovery(void)//recovery操作实际是对lcm进行init操作
    {
    ……
    disp_lcm_suspend(pgc->plcm);
    disp_lcm_init(pgc->plcm, 1);
    ……
    }
    

    以上就是整个esd check的流程

    四、相关案例分析

    1、开启esd之后不生效,故意改错返回值也不生效

    lcm driver中的lcm_get_params函数中没有将customization_esd_check_enable设置为1

    2、设置多个返回值,除了第一个,其余无效

    MT6737在ESD读取寄存器时候,只能够识别屏端返回的短包,并且只能够判断一个返回值

    3、开启esd之后打静电出现黑屏恢复不了

    lcm的特殊性,需在primary_display_esd_check_worker_kthread线程中primary_display_esd_recovery与primary_display_esd_check之间添加延时,让lcm有充足时间recovery成功

    展开全文
  • JVM系列之:从汇编角度分析NullCheck

    千次阅读 2020-08-06 07:42:39
    文章目录简介一个普通的virtual call普通方法中的null check反优化的例子总结 简介 之前我们在讲Virtual call的时候有提到,virtual call方法会根据传递的参数实例的不同而进行优化,从而优化成为classic call,从而...

    简介

    之前我们在讲Virtual call的时候有提到,virtual call方法会根据传递的参数实例的不同而进行优化,从而优化成为classic call,从而提升执行效率。

    今天我们考虑一下,在virtual call中执行nullcheck的时候,如果已经知道传递的参数是非空的。JIT会对代码进行优化吗?

    一起来看看吧。

    一个普通的virtual call

    我们来分析一下在方法中调用list.add方法的例子:

    public class TestNull {
    
        public static void main(String[] args) throws InterruptedException {
            List<String> list= new ArrayList();
    	    list.add("www.flydean.com");
            for (int i = 0; i < 10000; i++)
            {
                testMethod(list);
            }
            Thread.sleep(1000);
        }
        private static void testMethod(List<String> list)
        {
            list.get(0);
        }
    }
    

    代码很简单,我们在循环中调用testMethod方法,而这个方法里面又调用了list.get(0)方法,来获取list的第一个参数。

    单纯的看testMethod,这个方法是有可能抛出NullPointerException的,但是从整体运行的角度来看,因为我们的list是有值的, 所以不会抛出异常。

    使用JIT Watcher看看运行结果:

    先看第二个和第三个红框,我们可以看到代码先做了参数类型的比较,然后对testMethod进行了优化,这里还可以看到get方法是内联到testMethod中的。

    代码优化的部分我们找到了,那么异常处理呢?如果list为空,应该怎么处理异常呢?

    第一个红框,大家可以看到是一个隐式的异常处理,它重定向到1152b4f01这个地址。

    第四个红框就是这地址,表示的是异常处理的代码。

    普通方法中的null check

    我们在上面的普通方法里面加上一个null check:

    public class TestNull1 {
    
        public static void main(String[] args) throws InterruptedException {
            List<String> list= new ArrayList();
            list.add("www.flydean.com");
            for (int i = 0; i < 10000; i++)
            {
                testMethod(list);
            }
            Thread.sleep(1000);
        }
    
        private static void testMethod(List<String> list)
        {
            if(list !=null ){
                list.get(0);
            }
        }
    }
    

    上面我们添加了一个list !=null的判断。

    运行看下结果:

    相比较而言,我们可以看到,代码其实没有太多的变化,说明JIT在代码优化的过程中,将null check优化掉了。

    那么null check到底在什么地方呢? 看我标红的第二个框,这里是之前的异常处理区域,我们可以看到里面有一个ifnull,表明这里做了null check。

    反优化的例子

    上面的两个例子,我们可以看出在virtual method中,JIT对null check进行了优化。接下来我们再看一个例子,在这个例子中,我们显示的传递一个null给testMethod,然后再次循环testMethod,如下所示。

    for (int i = 0; i < 10000; i++)
            {
                testMethod(list);
            }
            Thread.sleep(1000);
            testMethod(null);
    for (int i = 0; i < 10000; i++)
            {
                testMethod(list);
            }
    

    我们看下JIT的结果:

    看下结果有什么不同呢?

    第一,ifnull现在是显示调用的,并不包含在隐式异常中。
    第二,隐式异常也不见了,因为使用显示的ifnull。

    总结

    JIT会根据不同的情况,对代码进行不同程度的优化,希望大家能够喜欢。

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/jvm-assembly-nullcheck/

    本文来源:flydean的博客

    欢迎关注我的公众号:程序那些事,更多精彩等着您!

    展开全文
  • 正确配置了Health Check,只有通过了Readiness探测的新副本才能添加到Service,如果没有通过探测,现有副本就不会呗替换,业务依然正常运行。 接下来,我们分别创建yaml文件app.v1.yaml和app.v2.yaml: api...
  • cmake:pkg_check_modules

    千次阅读 2020-12-27 21:50:05
    pkg_check_modules是 CMake 自己的 pkg-config模块的一个用来简化的封装:你不用再检查 CMake 的版本,加载合适的模块,检查是否被加载,等等,参数和传给 find_package 的一样:先是待返回变量的前缀,然后是包名...
  • Cppcheck 用法(上篇)

    万次阅读 多人点赞 2016-10-11 13:51:24
    简述Cppcheck 是一种 C/C++ 代码缺陷静态检查工具。不同于 C/C++ 编译器及很多其它分析工具,它不检查代码中的语法错误。Cppcheck 只检查编译器检查不出来的 bug 类型,其目的是检查代码中真正的错误(即:零误报)...
  • DataSource health check failed

    万次阅读 2020-06-05 11:26:54
    2020-06-05 10:48:56 WARN [-RMI TCP Connection(3)-192.168.0.152] [87] [org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator] : DataSource health check failed org.springframework.dao....
  • CHECK约束

    千次阅读 2018-10-21 01:35:00
    CHECK约束会检查输入到记录中的值是否满足一个条件,如果不满足这个条件则对数据库做的修改不会成功。比如,一个人的年龄是不可能为负数的,一个人的入学日期不可能早于出生日期,出厂月份不可能大于12。可以在CHECK...
  • nginx安装第三访模块nginx_upstream_check_module一:nginx后端健康检查二:nginx被动检查三:nginx主动检查3.1 安装nginx_upstream_check_module3.2 模块配置四:docker中安装 一:nginx后端健康检查 nginx自带健康...
  • 最近在学习 Spring Cloud Stream 的时候用到 RabbitMQ,连接本地的 RabbitMQ 一切正常,连接远程的 RabbitMQ 始终会报 Rabbit health check failed,博主因为这个问题折腾了很长时间,终于找到了问题所在,希望我的...
  • 如何理解negative timing check

    千次阅读 2020-04-12 21:52:03
    最近也是遇到了这个问题,通过周末的研究,感觉自己搞明白了,现在总结一下吧!...positive setuphold timing check $setuphold函数 在工艺厂商提供的工艺库模型中定义了工艺库中用到的所有cell的v...
  • AudioServer的TimeCheck机制

    千次阅读 2019-11-13 17:22:16
    android audioserver里面用于binder调用超时检测有个TimeCheck机制,对于audioserver binder调用不能超过5s,如果超过5s就会产生一个abort的log 实现路径在frameworks\av\media\libmedia\TimeCheck.cpp 代码量很少...
  • dependency check工具的使用

    千次阅读 2021-11-09 17:03:50
    前置条件:先下载dependency check文件包 Dependency-Check工具下载地址https://owasp.org/www-project-dependency-check/,在右侧选择command line,如下图: 方式一:用命令行来运行 windows下的命令 ...
  • | `-- xx.xx.xx.xx.cmd 存放相关主机需要执行的命令 1 2 3 4 5 6 `--daily_check.py此文件是python的主程序 `--日期-xunjian.txt生成的巡检信息文件 `--check.log日志文件 |--hosts存放着要执行那些命令和检查那些...
  • cppcheck命令行参数说明

    千次阅读 2017-02-07 12:20:55
    汉字均为翻译 以下翻译均采用谷歌... cppcheck [OPTIONS] [files or paths] If a directory is given instead of a filename, *.cpp, *.cxx, *.cc, *.c++, *.c, *.tpp, and *.txx files are checked recursiv
  • 在下载NLP backend spaCy的时候,pip install spacy这一步是正常的 但是下一步:python -m spacy download en_...即ValueError: check_hostname requires server_hostname 请问该怎么解决呢?</p>
  • import requests wb = requests.get("...) print(wb.text) ...报错 python3 ValueError: check_hostname requires server_hostname 请问各位大佬 这是代码问题还是编辑器差什么信息啊</p>
  • 文章目录 遇到的问题 解决方法 参考 遇到的问题 ValueError: check_hostname requires server_hostname 具体报错内容如下: Traceback (most recent call last): File "pythonrepos.py", line 6, in <module> r = ...
  • C语言单元测试工具check

    千次阅读 2019-05-22 11:28:39
    C语言单元测试工具check实例 关于check的概念性描述,我在这里就不多少了,主要就是分享一下我在学习使用了check后的一些问题。 安装完check(我是在github上下载的源码安装的),在你的 /usr/local/ 目录下会有...
  • CheckiO上熟悉编程

    千次阅读 2019-01-08 23:39:55
    偶然间发现了一个网站CheckiO,这里提供了很多很多的编程练习,并且你可以在自己尝试解决后,通过点击通关表单里的Best Solutions查看到别人的解答方法. 一个自己动手解决了问题,二个看到别人pythonic的代...
  • 暂时k8s不支持docker的healthcheck功能,k8s由其之前就提供的liveness和readiness功能来实现healthcheck,docker引入healthcheck功能,估计也是向k8s学习的。   docker 的healthcheck 设置选项 : --...
  • sign check fail: check Sign and Data Fail

    千次阅读 2019-01-17 12:02:31
    支付宝开发报错:com.alipay.api.AlipayApiException: sign check fail: check Sign and Data Fail 解决方法: 确认使用的支付宝公钥是否正确,不同的环境使用的支付宝公钥不同, 如沙箱环境、线上openapi网关和...
  • Linux cppcheck使用

    千次阅读 2019-06-25 09:23:02
    cppcheckTool for static C/C++ code analysis ... Cppcheck is a command-line tool that tries to detect bugs that your C/C++ compiler doesn't see. It is versatile, and can check non-standard c...
  • jquery.checktree.js的资源

    热门讨论 2010-10-13 18:04:05
    jquery.checktree.js的资源jquery.checktree.js的资源jquery.checktree.js的资源
  • MACHINE-CHECK-EXCEPTION蓝屏

    千次阅读 2021-08-25 20:14:47
    Machine Check Exception (MCE) 是CPU发现硬件错误时触发的异常(exception),中断号是18,异常的类型是abort: 导致MCE的原因主要有:主板总线故障、内存ECC校验错、cache错误、TLB错误、内部时钟错误,等等。...
  • Rabbit health check failed

    千次阅读 2020-09-23 11:06:03
    748) 09-23 10:52:47.893 WARN [o.s.boot.actuate.amqp.RabbitHealthIndicator] - Rabbit health check failed org.springframework.amqp.AmqpTimeoutException: java.util.concurrent.TimeoutException 2:找了好久...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,586,115
精华内容 634,446
关键字:

check