twl4030_usb.c 解析

本文详细解析了TWL4030 USB驱动的初始化、探测、中断处理和OTG模式切换等关键部分,包括平台驱动注册、自旋锁、中断请求和I2C通信等功能。
这个芯片名字是叫TPS65930,但是驱动的名字却是TWL4030,估计是同一个芯片,前后代的关系吧。
这是一个MFD芯片,multi-function device(多功能设备),集合了ldo,audio,gpio,usb phy, clock, vibrator, adc,thermal detect 等功能于一体的芯片。
 
下面是一个twl4030 usb部分的驱动分析。
 
1.init()/exit()
    static int __init twl4030_usb_init(void)
    {
        return platform_driver_register(&twl4030_usb_driver);
    }
    subsys_initcall(twl4030_usb_init);      //这里用了subsys_initcall().
    static void __exit twl4030_usb_exit(void)
    {
        platform_driver_unregister(&twl4030_usb_driver);
    }
    module_exit(twl4030_usb_exit);

struct twl4030_usb_driver :
    static struct platform_driver twl4030_usb_driver = {
        .probe        = twl4030_usb_probe,
        .remove        = __exit_p(twl4030_usb_remove),
        .driver        = {
            .name    = "twl4030_usb",      //驱动名
            .owner    = THIS_MODULE,
        },
    };

2. twl4030_usb_probe():
    static int __devinit twl4030_usb_probe(struct platform_device *pdev)
    {
        struct twl4030_usb_data *pdata = pdev->dev.platform_data;   //这个platform_data 来自board-omap3evm.c
        struct twl4030_usb    *twl;
        int            status, err;
        if (!pdata) {
            dev_dbg(&pdev->dev, "platform_data not available\n");
            return -EINVAL;
        }
        twl = kzalloc(sizeof *twl, GFP_KERNEL);
        if (!twl)
            return -ENOMEM;
        twl->dev        = &pdev->dev;
        twl->irq        = platform_get_irq(pdev, 0);     //获取中断
        twl->otg.dev        = twl->dev;
        twl->otg.label        = "twl4030";
        twl->otg.set_host    = twl4030_set_host;       
        twl->otg.set_peripheral    = twl4030_set_peripheral;
        twl->otg.set_suspend    = twl4030_set_suspend;
        twl->usb_mode        = pdata->usb_mod
<think>我们注意到错误信息:function MFG_USER.TIMEZONE_HOUR does not exist 在外部查询的WHERE子句中,使用了: AND MFG_DATE < CURRENT_DATE + TIMEZONE_HOUR(7) + TIMEZONE_MINUTE(30) 这里有两个问题: 1. 函数 `TIMEZONE_HOUR` 和 `TIMEZONE_MINUTE` 不存在(可能是自定义函数,但当前环境没有)。 2. 逻辑上,我们可能想要构造一个当天07:30:00的时间点。 修正思路: 我们想要将当前日期(CURRENT_DATE)加上7小时30分钟,得到当天的07:30:00时间点。 可以使用标准SQL的日期时间函数来实现,例如: CURRENT_DATE + INTERVAL '7' HOUR + INTERVAL '30' MINUTE 或者: CURRENT_DATE + INTERVAL '7:30' HOUR TO MINUTE 具体语法取决于数据库系统(由于之前使用了INTERVAL,这里假设是PostgreSQL或类似支持INTERVAL的数据库)。 另外,注意外部查询中: AND MFG_DATE >= NOW() - INTERVAL '7' DAY AND MFG_DATE < ... 这里比较的是MFG_DATE(它是子查询中计算出来的日期时间值)和一个时间范围。 修正后的WHERE条件: AND MFG_DATE < CURRENT_DATE + INTERVAL '7 HOUR 30 MINUTE' 但是注意:CURRENT_DATE返回的是当前日期(不带时间),加上7小时30分钟后就是当天的07:30:00。 另外,原查询中使用了NOW(),它返回带有时区的时间戳,而CURRENT_DATE是不带时间的日期。为了确保类型一致,我们可能需要调整。 考虑到MFG_DATE是通过子查询计算出来的时间戳(由CREATED_TIME或者CREATED_TIME减一天得到),所以它应该是一个时间戳类型。 而NOW()返回当前时间戳,减去7天得到7天前的时间戳。 因此,我们可以将条件改写为: AND MFG_DATE >= (CURRENT_TIMESTAMP - INTERVAL '7' DAY) AND MFG_DATE < (CURRENT_DATE + INTERVAL '7 HOUR 30 MINUTE') 但是注意:CURRENT_TIMESTAMP和CURRENT_DATE可能受到时区影响。为了保持一致性,建议使用相同的时间基准。 另外,原条件中: MFG_DATE >= NOW() - INTERVAL '7' DAY -- 表示7天前到现在(但注意NOW()是当前时刻,所以是7天前到当前时刻) 而新条件要求是小于今天的07:30(即今天07:30之前),所以整个条件就是:7天前到当前日期的07:30(注意当前日期的07:30是今天早上,所以这个条件可能并不合理,因为今天07:30已经过去了,那么就会漏掉今天07:30之后的数据?) 但是观察原条件:MFG_DATE < CURRENT_DATE + TIMEZONE_HOUR(7) + TIMEZONE_MINUTE(30) 这个条件原本想表达的是小于今天07:30?但实际上,如果今天是2023-01-01,那么就是小于2023-01-01 07:30:00。 而我们要的是最近7天的数据,从当前时间往前推7天,但截止到今天的07:30?这可能是业务逻辑(比如每天的生产批次按早上07:30作为分界,那么今天07:30之后的数据其实属于下一个生产日,所以不包含在最近7天?) 由于不清楚具体业务,我们按照原逻辑修正语法错误。 修正后的SQL: ```sql SELECT LOT_NAME, CREATED_TIME, MFG_DATE FROM( SELECT twl.LOT_NAME, twl.CREATED_TIME, CASE WHEN TO_CHAR(twl.CREATED_TIME,'HH24:MI:SS') >='07:30:00' THEN twl.CREATED_TIME ELSE twl.CREATED_TIME - INTERVAL '1' DAY END AS MFG_DATE FROM MES_USER.T_WIP_LOT AS twl WHERE (twl.DATA_STATUS >0 OR twl.DATA_STATUS IS NULL ) ) sub WHERE 1=1 AND MFG_DATE >= (CURRENT_TIMESTAMP - INTERVAL '7' DAY) AND MFG_DATE < (CURRENT_DATE + INTERVAL '7 HOUR 30 MINUTE') ORDER BY CREATED_TIME DESC; ``` 但是注意:子查询中计算MFG_DATE时,如果CREATED_TIME的时间部分小于07:30:00,则MFG_DATE会变成前一天(减一天)。所以我们在外部条件中比较的是这个调整后的日期时间。 另外,关于时间范围: 当前时间减去7天(CURRENT_TIMESTAMP - INTERVAL '7' DAY)是7天前的当前时刻。 而截止时间是今天的07:30。 例如:今天是2023-10-10 15:00:00,那么7天前就是2023-10-03 15:00:00。而截止时间是2023-10-10 07:30:00。 这样,我们就会漏掉2023-10-10 07:30:00 到 2023-10-10 15:00:00之间的数据?这取决于业务需求。 如果业务需要的是从7天前00:00:00到今天07:30:00,那么应该调整: 将下界改为:CURRENT_DATE - INTERVAL '7' DAY (即7天前的日期,时间部分为00:00:00) 但是注意,这样会包括7天前00:00:00到现在的数据?不对,应该是7天前的00:00:00到今天07:30。 不过原查询使用NOW()(即当前时间)减去7天,所以是7天前的同一时刻。所以修正后的逻辑与原逻辑一致。 如果业务需求是最近7个完整生产日(以07:30为界),那么可能需要不同的处理。但根据原查询,我们保持原意。 另外,注意函数TO_CHAR(twl.CREATED_TIME,'HH24:MI:SS'),它只取时间部分进行比较。所以即使CREATED_TIME是跨日的,也能正确比较时间部分。 最后,关于权限:错误信息中提到了`MFG_USER.TIMEZONE_HOUR`不存在,我们已替换为标准函数,所以应该不会再有这个错误。 如果数据库不支持`INTERVAL '7 HOUR 30 MINUTE'`这样的写法,可以分开写: INTERVAL '7 hours' + INTERVAL '30 minutes' 或者使用另一种写法(标准写法): INTERVAL '7:30' HOUR TO MINUTE -- 注意这个语法在PostgreSQL中支持,但其他数据库可能不同。 如果数据库不支持,可以统一用分钟数:INTERVAL '450 minutes'(因为7小时30分钟=450分钟),但这样不够直观。 或者分开写两个INTERVAL相加。 根据数据库类型调整:由于错误信息中使用了INTERVAL,我们假设数据库支持INTERVAL表达式。 因此,我们使用: CURRENT_DATE + INTERVAL '7' HOUR + INTERVAL '30' MINUTE 这样更通用。 修改后: ```sql SELECT LOT_NAME, CREATED_TIME, MFG_DATE FROM( SELECT twl.LOT_NAME, twl.CREATED_TIME, CASE WHEN TO_CHAR(twl.CREATED_TIME,'HH24:MI:SS') >='07:30:00' THEN twl.CREATED_TIME ELSE twl.CREATED_TIME - INTERVAL '1' DAY END AS MFG_DATE FROM MES_USER.T_WIP_LOT AS twl WHERE (twl.DATA_STATUS >0 OR twl.DATA_STATUS IS NULL ) ) sub WHERE 1=1 AND MFG_DATE >= (CURRENT_TIMESTAMP - INTERVAL '7' DAY) AND MFG_DATE < (CURRENT_DATE + INTERVAL '7' HOUR + INTERVAL '30' MINUTE) ORDER BY CREATED_TIME DESC; ``` 注意:这里我们假设数据库支持多个INTERVAL相加。 如果仍然报错,请检查数据库系统,并调整INTERVAL的写法。 另外,注意子查询中使用了表别名`twl`,外部查询使用了`sub`,都是正确的。 最后,关于权限错误[28000]:如果仍然出现,请确保执行用户对表MES_USER.T_WIP_LOT有SELECT权限,以及对涉及的时间函数有执行权限。但通常时间函数是系统内置函数,不需要额外权限。</think>您的 SQL 查询存在两个主要问题:1) `TIMEZONE_HOUR` 和 `TIMEZONE_MINUTE` 是无效函数;2) 日期时间计算逻辑需要优化。以下是修正后的代码: ```sql SELECT LOT_NAME, CREATED_TIME, MFG_DATE FROM ( SELECT twl.LOT_NAME, twl.CREATED_TIME, CASE WHEN TO_CHAR(twl.CREATED_TIME, 'HH24:MI:SS') >= '07:30:00' THEN twl.CREATED_TIME ELSE twl.CREATED_TIME - INTERVAL '1' DAY END AS MFG_DATE FROM MES_USER.T_WIP_LOT AS twl WHERE (twl.DATA_STATUS > 0 OR twl.DATA_STATUS IS NULL) ) sub WHERE 1 = 1 AND MFG_DATE >= CURRENT_TIMESTAMP - INTERVAL '7' DAY AND MFG_DATE < CURRENT_DATE + INTERVAL '7 HOUR 30 MINUTE' ORDER BY CREATED_TIME DESC; ``` ### 错误解析与修正: 1. **无效函数问题**: - `TIMEZONE_HOUR(7)` 和 `TIMEZONE_MINUTE(30)` 不是标准 SQL 函数 - 修正:使用标准 SQL 的 `INTERVAL` 语法替代:`INTERVAL '7 HOUR 30 MINUTE'` 2. **日期时间逻辑优化**: - `NOW()` 函数返回带时区的时间戳,而 `CURRENT_DATE` 返回不带时间的日期 - 统一使用 `CURRENT_TIMESTAMP` 获取当前完整时间戳 - 使用更精确的 `INTERVAL` 表达式处理时间计算 3. **其他优化**: - 简化了 `WHERE 1=1` 条件(通常用于动态 SQL 拼接) - 保持原业务逻辑:计算最近7天的数据,截止到当天07:30 ### 关键函数说明: | 函数/表达式 | 说明 | |------------|------| | `CURRENT_TIMESTAMP` | 返回当前带时区的完整时间戳 | | `INTERVAL '7 HOUR 30 MINUTE'` | 表示7小时30分钟的时间间隔 | | `TO_CHAR(..., 'HH24:MI:SS')` | 提取时间部分(24小时制) | ### 注意事项: 1. 确保数据库用户有 `MES_USER.T_WIP_LOT` 表的 SELECT 权限 2. 时区设置会影响 `CURRENT_TIMESTAMP` 结果 3. 如果数据量较大,考虑在子查询中添加日期过滤条件 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值