免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2383 | 回复: 6
打印 上一主题 下一主题

[求助!!!非标准单总线设备,写数据时使用spin_lock_irqsave不起作用] [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-09-09 13:46 |只看该作者 |倒序浏览
各位高手:
本人目前在写一个操作led灯的IC驱动,但是在使用GPIO模拟时序时,会被打断,使用spin_lock_irqsave也不起作用,代码如下:
#define DELAY_TDS   udelay(10)
#define DELAY_THLB  udelay(2)
#define DELAY_TLLB  udelay(4)
#define DELAY_THHB  udelay(4)
#define DELAY_TLHB  udelay(2)
#define DELAY_TEODL udelay(2)
#define DELAY_TEODH udelay(400)
#define DELAY_TSD   mdelay(2)

void ktd202x_send_bit(struct ktd202x_data *data,int bit_data)
{
        if (bit_data == 0) {
                gpio_set_value(data->ctrl_gpio, 0);
                DELAY_TLLB;
                gpio_set_value(data->ctrl_gpio, 1);
                DELAY_THLB;
        } else {
                gpio_set_value(data->ctrl_gpio, 0);
                DELAY_TLHB;
                gpio_set_value(data->ctrl_gpio, 1);
                DELAY_THHB;
        }
}

/* Write a complete command including address, data and EOD         */

void ktd202x_send_data(struct ktd202x_data *data,unsigned char byte_address, unsigned char byte_data)
{
        int n;
        unsigned long flags;
        printk(KERN_ERR"address = %d,data = %d\n" ,byte_address,byte_data);
       
        spin_lock_irqsave(&data->led_lock, flags);
        /* Set Ctrl High */
        gpio_set_value(data->ctrl_gpio, 1);
        DELAY_TDS;

        /* Write Byte Address (only 4 bits)         */
        /* MSB first, start at xxxx 1xxx         */
        for (n = 0; n < 4; n++) {
                ktd2024_send_bit(data,(byte_address & 0x0 ? 1 : 0);
                byte_address = byte_address << 1;
        }

        /* Write Byte Data (8 bits)                 */
        /* MSB first, start at 1xxx xxxx         */
        for (n = 0; n < 8; n++) {
                ktd2024_send_bit(data,(byte_data & 0x80) ? 1 : 0);
                byte_data = byte_data << 1;
        }

        /* Write EOD                */
        gpio_set_value(data->ctrl_gpio, 0);
        DELAY_TEODL;
        gpio_set_value(data->ctrl_gpio, 1);
        spin_unlock_irqrestore(&data->led_lock, flags);
        DELAY_TEODH;
}
这个应该如何解决,是否还有其他方式去写这个IC的寄存器?请高手指点.

论坛徽章:
0
2 [报告]
发表于 2014-09-09 16:35 |只看该作者
本帖最后由 xuexizhe_computer 于 2014-09-09 16:37 编辑


这是用示波器测得波形,明显时序不对,好像被中断了

论坛徽章:
0
3 [报告]
发表于 2014-09-10 07:11 |只看该作者
spin_lock_irqsave  只是防止竞争情况的出现,不能防止一个进程换出CPU。arm Linux内核一般是10ms进行一次进程调度的判断。如果要达到你的要求可以,可以尝试下如下几种方式:
            1、增加该进程的优先级。
            2、在该段代码中禁止进程间的抢占。

论坛徽章:
0
4 [报告]
发表于 2014-09-10 11:10 |只看该作者
本帖最后由 xuexizhe_computer 于 2014-09-10 15:38 编辑

回复 3# 蜗牛_1215
你好

根据你的两个方案:
1 第一个提高进程优先级,这个该如何提高?

2 第二个是使用disable_preempt()/enable_preempt().
  这个我用了,但是不起作用,会出现下图所示现象:


  而且这里还有一个问题,整个写数据的过程最短也需要84us,这个是否有些危险?
  
3 这样一个设备驱动,是否还有其他方式去进行寄存器的操作?例如timer等


   

论坛徽章:
0
5 [报告]
发表于 2014-09-11 09:59 |只看该作者
回复 4# xuexizhe_comput
修改进程优先级可以参考如下代码:

static int touch_event_handler(void *unused)
{
        struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
        sched_setscheduler(current, SCHED_RR, &param);
        do
        {
                mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
                set_current_state(TASK_INTERRUPTIBLE);
                wait_event_interruptible(waiter, tpd_flag != 0);
                mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
                tpd_flag = 0;
                TPD_DEBUG_SET_TIME;
                set_current_state(TASK_RUNNING);
                gsl_report_work();
        } while (!kthread_should_stop());       
        return 0;
}

论坛徽章:
0
6 [报告]
发表于 2014-09-11 10:16 |只看该作者
回复 5# 蜗牛_1215
我看了一下你的代码,发现传输1与0的数据是通过高低电平的延续时间长短不一来确定1与0。这种传输对于时间的精准度要求比较高,如果你用gpio来模拟时序很容易出现数据出错。

   

论坛徽章:
0
7 [报告]
发表于 2014-09-15 17:17 |只看该作者
你好
我尝试了一下,但是机子容易挂掉。我又看了一下高精度定时器,这部分,看起来可以实现,
http://blog.csdn.net/droidphone/article/details/8074892
这个具体实现方案该如何做?
回复 6# 蜗牛_1215


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP