2017年6月

Gogs和DroneCI 0.7版本配置

Tags: none

之前用Drone 0.4版本,以为直接用就可以了,dock run之后一直提示错误,翻了Drone的文档才知道配置是有区别的。这里以Gogs的地址为192.168.2.12:3000,Drone的地址为192.168.2.12:8000为例。

启动drone容器:

docker run --volume /var/lib/drone:/var/lib/drone -i -t \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --restart=always \
    --publish=8000:8000 \
    --env-file dronerc \
    --detach \
    --name=droneci drone/drone:latest

dronerc文件的内容:

DRONE_OPEN=true
DRONE_HOST=${DRONE_HOST}
DRONE_GOGS=true
DRONE_GOGS_URL=http://192.168.2.12:3000
DRONE_SECRET=${DRONE_SECRET}

使用Gogs和Drone也有一年半了,对于嵌入式开发来说,Drone更多被我用来制做镜像包分发给客户,算是减少了一部分重复的人工工作量,其他同事也可以参与任何一个项目的分发环节。也由于硬件的绑定,不能让Drone参与到硬件上的软件测试工作中。最近有了解一些jenkins应用到硬件的文章,希望以后嵌入式开发也可以享受到更便捷的开发方式和工具。

Freescale i.MX28 AUART应用RS485

0x0

最近有客户使用i.MX28的SOM模块开发产品,其中用到了RS485通讯,发现发送时延时在百毫秒级,由于上层应用协议要求是微秒级,客户要求减少发送的延时。问题看起来很简单,解决起来也是小波折。总归还是自己对kernel知识理解不够深入。

0x1

了解问题背景后,就去看AUART的实现代码,之前开发imx28的同事已经在mxs_auart_tx_chars()的前后加入了gpio的操作,

static inline void mxs_auart_tx_chars(struct mxc_auart_port *s)
{
    if(s->port.line == 1){
        gpio_set_value(MXS_AUART_RS485_EN, 1);
    }

    // ignore more send code

    if (s->port.line == 1) {
        do {
            status = __raw_readl(s->port.membase + HW_UARTAPP_STAT);
        } while (!(status & BM_UARTAPP_STAT_TXFE) || (
            status & BM_UARTAPP_STAT_BUSY));
        gpio_set_value(MXS_AUART_RS485_EN, 0); // Add by JBO, Disable send
    }
}

细看之后觉得do while用法在这里可能是问题的根源。看了下有mxs_auart_stop_tx(),应该放在里面做符合tty规范么,结果一测,发现stop_tx就没有执行。然后翻datasheet和代码,才知道auart没有FIFO Empty的中断,所以TX中断后要polling去查FIFO Empty flag再拉gpio。然后在网上看到有网友的解决相同问题的记录,依样画瓢改成tasklet处理了。其中也是小状况,就这位网友说的那样,"很多事情都是想得简单,做起来的时候各种意外"。

这里把gpio的操作放在了start_tx()和stop_tx()里面了,mxs_auart_tx_chars()里的检查xmit buf为空后,执行tasklet_hi_schedule(&my_task0);启动tasklet任务,然后由rs485_mode_func()来检查FIFO是否为空,再操作gpio。

void rs485_mode_func(unsigned long data)
{
     struct uart_port *u = data;
     struct mxs_auart_port *s = to_auart_port(u);
     int status;
 
     dev_dbg(s->dev, "%s: control RS485 line\n", __FUNCTION__);
     if (s == NULL)
         return;
     if (s->port.line == 1){
         if(!(readl(s->port.membase + HW_UARTAPP_STAT) & BM_UARTAPP_STAT_TXFE)){
             udelay(10);
             tasklet_hi_schedule(&my_task0);
         }else{
             mxs_auart_stop_tx(&s->port);
         }
     }
}

Reference

linux rs485 GPIO 方向控制问题

最新文章

最近回复

  • Blackrose: 感谢拍砖!嗯,那句话...
  • aa: “Raspberry...
  • Blackrose: 外部只是帮你把芯片启...
  • : 内部时钟比外部的频率...
  • Blackrose: 你这评论比正文更有内容么
  • 7hao: CR+LF ...
  • Blackrose: 可以是你更新软件源后...
  • sxk: 博主,我的系统是ub...
  • Blackrose: 你深得精髓么
  • qihao: 这篇文章的简单总结就...

分类

归档

其它