FreeModbus移植到STM32F107(以太网传输方式)
1.創建工程
?
配置好之后生成工程
?
2.將FreeModbus源碼,拷貝到工程目錄
?
3.將FreeModbus文件添加進工程
打開mbtcp.c文件發現,受MB_TCP_ENABLED宏定義的影響,所有代碼都是灰的
因此跳轉到宏定義的地方。打開TCP模式,并將RTU和ASCII模式關閉
打開mbrtu.c和mbascii.c文件檢查,發現mbrtu.c源碼有問題,不受宏定義影響
因此修改mbrtu.c源碼
修改好之后,編譯出現錯誤
?
4.移植底層接口
先看第一個錯誤,缺少port.h
借鑒demo里面STR71XTCP的程序。將STR71XTCP中的port文件夾,拷貝到工程中。
刪除重復文件mbconfig.h
將文件加入工程
添加好之后,重新編譯,出現錯誤,port.h中包含了STR71X相關代碼
將這些代碼修改
重新編譯,出現錯誤,發現demo中STR71XTCP程序原來是帶操作系統的。portevent.c文件不適用于裸機。
借鑒demo里面AVR的程序。將AVR中的portevent.c文件,拷貝過來并覆蓋源文件。
重新編譯,有部分宏沒有定義。
打開port.h,重新定義。
重新編譯,出現錯誤,NETCONN_COPY沒有定義。這是因為lwip沒有配置LWIP_NETCONN或者LWIP_SOCKET。
?
對于這個我們直接搜尋整個工程,發現NETCONN_COPY的值為1。將NETCONN_COPY的值直接替換掉。
?
重新編譯,報告eMBRegCoilsCB、eMBRegDiscreteCB、eMBRegHoldingCB和eMBRegInputCB沒有定義。
這四個接口是協議棧預留給用戶自己去實現的,分別創建user_mb_app.h和user_mb_app.c兩個文件
#ifndef _USER_MB_APP_H_ #define _USER_MB_APP_H_/* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbconfig.h" #include "mbframe.h" #include "mbutils.h"/* -----------------------Slave Defines -------------------------------------*/ #define S_DISCRETE_INPUT_START 0 #define S_DISCRETE_INPUT_NDISCRETES 16 #define S_COIL_START 0 #define S_COIL_NCOILS 64 #define S_REG_INPUT_START 0 #define S_REG_INPUT_NREGS 100 #define S_REG_HOLDING_START 0 #define S_REG_HOLDING_NREGS 100 /* salve mode: holding register's all address */ #define S_HD_RESERVE 0 #define S_HD_CPU_USAGE_MAJOR 1 #define S_HD_CPU_USAGE_MINOR 2 /* salve mode: input register's all address */ #define S_IN_RESERVE 0 /* salve mode: coil's all address */ #define S_CO_RESERVE 0 /* salve mode: discrete's all address */ #define S_DI_RESERVE 0/* -----------------------Master Defines -------------------------------------*/ #define M_DISCRETE_INPUT_START 0 #define M_DISCRETE_INPUT_NDISCRETES 16 #define M_COIL_START 0 #define M_COIL_NCOILS 64 #define M_REG_INPUT_START 0 #define M_REG_INPUT_NREGS 100 #define M_REG_HOLDING_START 0 #define M_REG_HOLDING_NREGS 100 /* master mode: holding register's all address */ #define M_HD_RESERVE 0 /* master mode: input register's all address */ #define M_IN_RESERVE 0 /* master mode: coil's all address */ #define M_CO_RESERVE 0 /* master mode: discrete's all address */ #define M_DI_RESERVE 0#endif /** FreeModbus Libary: user callback functions and buffer define in slave mode* Copyright (C) 2013 Armink <armink.ztl@gmail.com>** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA** File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $*/ #include "user_mb_app.h"/*------------------------Slave mode use these variables----------------------*/ //Slave mode:DiscreteInputs variables USHORT usSDiscInStart = S_DISCRETE_INPUT_START; #if S_DISCRETE_INPUT_NDISCRETES%8 UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1]; #else UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ; #endif //Slave mode:Coils variables USHORT usSCoilStart = S_COIL_START; #if S_COIL_NCOILS%8 UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ; #else UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ; #endif //Slave mode:InputRegister variables USHORT usSRegInStart = S_REG_INPUT_START; USHORT usSRegInBuf[S_REG_INPUT_NREGS] ; //Slave mode:HoldingRegister variables USHORT usSRegHoldStart = S_REG_HOLDING_START; USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;/*** Modbus slave input register callback function.** @param pucRegBuffer input register buffer* @param usAddress input register address* @param usNRegs input register number** @return result*/ eMBErrorCode eMBRegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex;USHORT * pusRegInputBuf;USHORT REG_INPUT_START;USHORT REG_INPUT_NREGS;USHORT usRegInStart;pusRegInputBuf = usSRegInBuf;REG_INPUT_START = S_REG_INPUT_START;REG_INPUT_NREGS = S_REG_INPUT_NREGS;usRegInStart = usSRegInStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= REG_INPUT_START)&& (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS)){iRegIndex = usAddress - usRegInStart;while (usNRegs > 0){*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);iRegIndex++;usNRegs--;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave holding register callback function.** @param pucRegBuffer holding register buffer* @param usAddress holding register address* @param usNRegs holding register number* @param eMode read or write** @return result*/ eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex;USHORT * pusRegHoldingBuf;USHORT REG_HOLDING_START;USHORT REG_HOLDING_NREGS;USHORT usRegHoldStart;pusRegHoldingBuf = usSRegHoldBuf;REG_HOLDING_START = S_REG_HOLDING_START;REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;usRegHoldStart = usSRegHoldStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= REG_HOLDING_START)&& (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS)){iRegIndex = usAddress - usRegHoldStart;switch (eMode){/* read current register values from the protocol stack. */case MB_REG_READ:while (usNRegs > 0){*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);iRegIndex++;usNRegs--;}break;/* write current register values with new values from the protocol stack. */case MB_REG_WRITE:while (usNRegs > 0){pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;iRegIndex++;usNRegs--;}break;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave coils callback function.** @param pucRegBuffer coils buffer* @param usAddress coils address* @param usNCoils coils number* @param eMode read or write** @return result*/ eMBErrorCode eMBRegCoilsCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex , iRegBitIndex , iNReg;UCHAR * pucCoilBuf;USHORT COIL_START;USHORT COIL_NCOILS;USHORT usCoilStart;iNReg = usNCoils / 8 + 1;pucCoilBuf = ucSCoilBuf;COIL_START = S_COIL_START;COIL_NCOILS = S_COIL_NCOILS;usCoilStart = usSCoilStart;/* it already plus one in modbus function method. */usAddress--;if( ( usAddress >= COIL_START ) &&( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) ){iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;switch ( eMode ){/* read current coil values from the protocol stack. */case MB_REG_READ:while (iNReg > 0){*pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],iRegBitIndex, 8);iNReg--;}pucRegBuffer--;/* last coils */usNCoils = usNCoils % 8;/* filling zero to high bit */*pucRegBuffer = *pucRegBuffer << (8 - usNCoils);*pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);break;/* write current coil values with new values from the protocol stack. */case MB_REG_WRITE:while (iNReg > 1){xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,*pucRegBuffer++);iNReg--;}/* last coils */usNCoils = usNCoils % 8;/* xMBUtilSetBits has bug when ucNBits is zero */if (usNCoils != 0){xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,*pucRegBuffer++);}break;}}else{eStatus = MB_ENOREG;}return eStatus; }/*** Modbus slave discrete callback function.** @param pucRegBuffer discrete buffer* @param usAddress discrete address* @param usNDiscrete discrete number** @return result*/ eMBErrorCode eMBRegDiscreteCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete) {eMBErrorCode eStatus = MB_ENOERR;USHORT iRegIndex , iRegBitIndex , iNReg;UCHAR * pucDiscreteInputBuf;USHORT DISCRETE_INPUT_START;USHORT DISCRETE_INPUT_NDISCRETES;USHORT usDiscreteInputStart;iNReg = usNDiscrete / 8 + 1;pucDiscreteInputBuf = ucSDiscInBuf;DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;usDiscreteInputStart = usSDiscInStart;/* it already plus one in modbus function method. */usAddress--;if ((usAddress >= DISCRETE_INPUT_START)&& (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES)){iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;while (iNReg > 0){*pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],iRegBitIndex, 8);iNReg--;}pucRegBuffer--;/* last discrete */usNDiscrete = usNDiscrete % 8;/* filling zero to high bit */*pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);*pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);}else{eStatus = MB_ENOREG;}return eStatus; }重新編譯,提示vMBPortEventClose未定義。由于我們是裸機程序,并未創建系統對象,也就不需要釋放。直接將vMBPortEventClose注釋即可。
重新編譯,無錯誤
8.協議棧移植工作完成。
燒錄之后,發現程序死在了vMBPortLog函數中。這是由于我們沒有打印口,我們直接將這段代碼注釋即可。
總結
以上是生活随笔為你收集整理的FreeModbus移植到STM32F107(以太网传输方式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32分散加载文件
- 下一篇: 你的“不着急”,最后都是“来不及”