EasyARM i.mx287学习笔记——通过modbus tcp控制GPIO

0 前言

本文使用freemodbus协议栈,在EasyARM i.mx287上实现了modbus tcp从机。

在该从机中定义了线圈寄存器。当中线圈寄存器地址较低的4位和EasyARM的P2.4至P2.5关联,通过modbus指令可控制GPIO的输出。本文改动自freemodbus 演示样例LINUXTCP。经过简单的改动也可用于其它Linux开发板。

【相关博文】

EasyARM i.mx28学习笔记——文件IO方式操作GPIO

EasyARM i.mx28学习笔记——安装和使用tftp

树莓派学习笔记——实现modbus RTU从机

MODBUS协议整理——汇总

freemodbus modbus TCP 学习笔记

MODBUS学习笔记——modbus tk modbus TCP主机实现

Linux学习笔记——例说makefile 索引博文

【代码仓库】

代码仓库位于bitbucket——easyarm-modbus-tcp,请使用Hg克隆或者直接下载zip包。

请不要使用不论什么版本号的IE浏览器訪问链接,除非你已经知道所使用的IE浏览器符合HTML5标准。推荐使用谷歌或者火狐浏览器訪问,若使用国产双核浏览器请切换到极速模式。

 1 部分代码

【gpio-sysfs】

在gpio-sysfs中添加使能GPIO、禁止GPIO和GPIO定期处理函数。

当中gpio_poll传入的參数为modbus线圈寄存器

int gpio_enable(void)
{
    gpio_export(P24);gpio_direction(P24,OUT);gpio_write(P24,0);
    gpio_export(P25);gpio_direction(P25,OUT);gpio_write(P25,0);
    gpio_export(P26);gpio_direction(P26,OUT);gpio_write(P26,0);
    gpio_export(P27);gpio_direction(P27,OUT);gpio_write(P27,0);
    return 0;
}

int gpio_disable(void)
{
    gpio_write(P24,0);gpio_unexport(P24);
    gpio_write(P25,0);gpio_unexport(P25);
    gpio_write(P26,0);gpio_unexport(P26);
    gpio_write(P27,0);gpio_unexport(P27);
    return 0;
}
int gpio_poll(unsigned char status)
{
    status & 0x01 ? gpio_write(P24,1) : gpio_write(P24,0);
    status & 0x02 ? gpio_write(P25,1) : gpio_write(P25,0);
    status & 0x04 ?

gpio_write(P26,1) : gpio_write(P26,0);
    status & 0x08 ? gpio_write(P27,1) : gpio_write(P27,0);
    return 0;
}

【modbus poll】

pvPollingThread线程中获得线圈寄存器结果——ucRegCoilsBuf[0],并传递至gpio_poll函数中。

void* pvPollingThread( void *pvParameter )
{
    eSetPollingThreadState( RUNNING );
    if( eMBEnable( ) == MB_ENOERR )
    {
        do
        {
            gpio_poll(ucRegCoilsBuf[0]); // 改变IO口状态
            if( eMBPoll( ) != MB_ENOERR )
                break;
        }
        while( eGetPollingThreadState( ) != SHUTDOWN );
    }
    ( void )eMBDisable( );
    eSetPollingThreadState( STOPPED );
    return 0;
}

【线圈寄存器读写函数】

eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
    eMBErrorCode eStatus = MB_ENOERR;
    int iNCoils = ( int )usNCoils;
    int usBitOffset;

    if( ( usAddress >= REG_COILS_START ) &&
       ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )
    {

        usBitOffset = ( int )( usAddress - REG_COILS_START );
        switch ( eMode )
        {
        case MB_REG_READ:
            while( iNCoils > 0 )
            {
                *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,
                                                 ( UCHAR )( iNCoils > 8 ? 8 : iNCoils ) );
                iNCoils -= 8;
                usBitOffset += 8;
            }
            break;

        case MB_REG_WRITE:
            while( iNCoils > 0 )
            {
                xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,
                               ( UCHAR )( iNCoils > 8 ? 8 : iNCoils ),
                               *pucRegBuffer++ );
                iNCoils -= 8;
                usBitOffset += 8;
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}

【makefile】

# 指定编译器
CROSS = arm-fsl-linux-gnueabi-
CC = $(CROSS)gcc
STRIP = $(CROSS)strip

# CFLAG包含头文件文件夹
CFLAGS = -g -Wall

# 头文件查找路径
INC = -I. -Iport -I../../modbus/rtu         -I../../modbus/ascii -I../../modbus/include -I../../modbus/tcp

#
LIBS = -lpthread
# 目标
TARGET = modbustcp
# 源文件
SRC = demo.c gpio-sysfs.c port/portother.c     port/portevent.c port/porttcp.c     ../../modbus/mb.c ../../modbus/tcp/mbtcp.c     ../../modbus/functions/mbfunccoils.c     ../../modbus/functions/mbfuncdiag.c     ../../modbus/functions/mbfuncholding.c     ../../modbus/functions/mbfuncinput.c     ../../modbus/functions/mbfuncother.c     ../../modbus/functions/mbfuncdisc.c     ../../modbus/functions/mbutils.c

# 源文件编译为目标文件
OBJS = $(SRC:.c=.o)

.PHONY: clean

# 链接为可运行文件
$(TARGET): $(OBJS)
    $(CC) $^ -o [email protected] $(LIBS)
    $(STRIP) [email protected]

# 可运行文件和目标文件
clean:
    rm -f $(OBJS)
    rm -f $(TARGET)

# 连续动作,先清除再编译链接,拷贝到tftpboot中
install:clean $(TARGET)
    @echo 拷贝到tftpboot文件夹
    cp $(TARGET) ~/tftpboot
    @echo 复制结束

# 编译规则 添加头文件 [email protected]代表目标文件 $< 代表第一个依赖文件
%.o:%.c
    $(CC) $(CFLAGS) $(INC) -o [email protected] -c $<

2 实验

【1】在虚拟机中make获得可运行文件——modbustcp

【2】配置EasyARM IP地址,比如EasyARM的IP地址为192.168.1.211

ifconfig eht0 192.168.1.211

【2】通过tftp传输可运行文件至开发板(如果此时虚拟机的IP地址为192.168.1.106)

tftp -g -r modbustcp 192.168.1.106

【3】改动可运行权限。

并运行

chmod a+x modbustcp

./modbustcp

【4】modbus tcp中有一个简单的控制台。输入h可获得指令帮助。当中e为使能协议栈。q为退出程序。

输入e使能modbus从机协议栈。

图1 运行modbus tcp

【5】在windows中打开modbus调试软件,连接EasyARM。IP地址为192.168.1.211,端口号为默认端口号205。

图2 通过modbus tcp控制GPIO

图3 实验效果

4 总结

【1】操作步骤较多,实现modbus tcp须要不少的基础知识。

时间: 2025-01-31 06:52:08

EasyARM i.mx287学习笔记——通过modbus tcp控制GPIO的相关文章

EasyARM i.mx28学习笔记——通过modbus tcp控制GPIO

0 前言 本文使用freemodbus协议栈,在EasyARM i.mx287上实现了modbus tcp从机.在该从机中定义了线圈寄存器,其中线圈寄存器地址较低的4位和EasyARM的P2.4至P2.5关联,通过modbus指令可控制GPIO的输出.本文修改自freemodbus 示例LINUXTCP,经过简单的修改也可用于其他Linux开发板. [相关博文] [EasyARM i.mx28学习笔记--文件IO方式操作GPIO] [EasyARM i.mx28学习笔记--安装和使用tftp]

EasyARM i.mx28学习笔记——文件IO方式操作GPIO

0 前言 本文描述如果通过文件IO sysfs方式控制EasyARM GPIO端口.通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入. Linux学习可从应用出发,先不纠结Linux驱动编写,先把Linux给玩起来. [相关博文] [EasyARM

EasyARM i.mx287学习笔记——minicom配置和使用

0 前言 在windows中有非常多串口调试软件,比如putty. 而ubuntu中也有非常多串口调试软件,当中最简单有用的便是minicom了. 本文说明虚拟机中怎样使用minicom进行串口调试,详细内容包含虚拟机中加载USB设备,查看USB设备是否存在.minicomport号.波特率等配置. 为了在虚拟机更好的进行嵌入式Linux开发,建议安装Vmware Tool.这样便可方便的在虚拟机和主机中复制粘贴文件. [Linux学习笔记--虚拟机中安装VMware Tools] 1 在虚拟机

EasyARM i.mx28学习笔记——开箱试用总结

0 前言 本月初(2014年8月)购买了周立功的EasyARM开发板,主控为EasyARM i.mx287.出于下面几个理由购买了该开发板. [1]主要原因,有人约我一起学习一起使用该开发板. [2]该开发板性价比較高,到手300元以内,比2440/2410开发板稍廉价些. [3]该开发板的CAN功能是一个特色. [4]通过学习EasyARM i.mx287,比較和树莓派的开发的不同.     [建议] 假设亲爱的读者Linux的基础比較薄弱的话,请优先考虑树莓派.假设从此类ARM开发板入手,可

EasyARM i.mx28学习笔记——根文件系统rootfs修改和烧写

0 前言 本文详细说明如何修改和制作根文件系统,包括修改根文件系统中的配置文件:在根文件系统中加入可执行文件,最后通过uboot tftp方式烧录根文件系统和镜像. [相关博文] [EasyARM i.mx28学习笔记--文件IO方式操作GPIO] [EasyARM i.mx28学习笔记--安装和使用tftp] [EasyARM i.mx28学习笔记--minicom配置和使用] [EasyARM i.mx28学习笔记--通过modbus tcp控制GPIO] 1 准备 若使用uboot tft

树莓派学习笔记——使用文件IO操作GPIO SysFs方式

0 前言 本文描述如果通过文件IO sysfs方式控制树莓派 GPIO端口.通过sysfs方式控制GPIO,先访问/sys/class/gpio目录,向export文件写入GPIO编号,使得该GPIO的操作接口从内核空间暴露到用户空间,GPIO的操作接口包括direction和value等,direction控制GPIO方向,而value可控制GPIO输出或获得GPIO输入. Linux学习可从应用出发,先不纠结Linux驱动编写,先把Linux给玩起来. [相同与不同] 本文和[EasyARM

EasyARM i.mx28学习笔记——安装和使用tftp

0 前言 前段时间购买了周立功的EasyARM i.mx287开发板,加之前3个月工作内容也和linux有关,就借助周立功的EasyARM总结Linux开发过程中的若干注意点. 本文说明在ubuntu中安装tftp服务器的详细步骤,在ubuntu中编写一个让LED闪烁的脚本,使用串口登录EasyARM,在EasyARM中通过busybox的tftp指令获得主机中的脚本文件,增加可执行权之后运行,最终LED灯间隔闪烁. 1 安装tftp [1]新建目录,并修改权限 在用户目录中新建一个名为tftp

EasyARM i.mx28学习笔记——开箱使试用总结

0 前言 本月初(2014年8月)购买了周立功的EasyARM开发板,主控为EasyARM i.mx287.出于以下几个理由购买了该开发板. [1]主要原因,有人约我一起学习一起使用该开发板. [2]该开发板性价比较高,到手300元以内,比2440/2410开发板稍便宜些. [3]该开发板的CAN功能是一个特色. [4]通过学习EasyARM i.mx287,比较和树莓派的开发的不同. [建议] 如果亲爱的读者Linux的基础为0的话,请优先考虑树莓派.如果从此类ARM开发板入手,可能会搞不清楚

EasyARM i.mx28学习笔记——minicom配置和使用

0 前言 在windows中有很多串口调试软件,例如putty.而ubuntu中也有很多串口调试软件,其中最简单实用的便是minicom了. 本文说明虚拟机中如何使用minicom进行串口调试,具体内容包括虚拟机中载入USB设备,查看USB设备是否存在,minicom端口号,波特率等配置. 为了在虚拟机更好的进行嵌入式Linux开发,建议安装Vmware Tool,这样便可方便的在虚拟机和主机中复制粘贴文件. [Linux学习笔记--虚拟机中安装VMware Tools] 1 在虚拟机中载入设备