AT32的freertos下modbus TCP移植

1.準備模板

打開雅特力官網,也就是帶有LwIP的示例。

下載官方源碼:modbus

2.移植

我這里是在這里新建兩個文件夾,分別是modbus與port,這個任意,只需要將必要的文件加入項目即可。

將源碼中的modbus這些都移植過來,分別是實現,頭文件、以及tcp相關的文件。其余的就不需要了

port文件夾里為:源碼->demo->MCF5235TCP->port。

接下來將這些文件加入工程。加入頭文件

編譯后,發現有12個錯誤

3.依次解決:

1.打開mbconfig.h

確保,我是本來就這樣,所以可能就只有12個錯誤,如果不是這樣可能之前編譯的錯誤更多。

2.打開port.h

這里我就關閉tcp_debug了。

3.打開portevent.c

沒有定義,自己定義一下,然后這里的sys_mbox_ne()這個函數定義已經發生了改變。按照途中修改,后續報警的xMailBox加上&符號,

4.打開portother.c

刪掉多余的這個三個

編譯,發現還有五個錯誤

1.打開porttcp.c

報錯說沒有memcpy,那么我們加入頭文件

還有這個錯誤,我們ctrl+h尋找,發現定義在portother.c文件里

復制并放在port.h中:

2.突然又發現少個宏定義,很離譜,我之前移植的時候沒有少過

是這個宏

拷貝,并放到mbconfig.h文件中:

#ifndef MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS
#define MB_ASCII_TIMEOUT_WAIT_BEFORE_SEND_MS    ( 0 )
#endif

不過我記得我之前沒有這個問題。

再次編譯:

我出現了以下五個錯誤

我的main.c為:

/***************************************************************************** @file     main.c* @version  v2.0.6* @date     2022-03-11* @brief    main program***************************************************************************                       Copyright notice & Disclaimer** The software Board Support Package (BSP) that is made available to * download from Artery official website is the copyrighted work of Artery. * Artery authorizes customers to use, copy, and distribute the BSP * software and its related documentation for the purpose of design and * development in conjunction with Artery microcontrollers. Use of the * software is governed by this copyright notice and the following disclaimer.** THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.****************************************************************************/#include "at32f435_437_board.h"
#include "at32f435_437_clock.h"
#include "at32_emac.h"
#include "stdio.h"
#include "FreeRTOS.h"
#include "task.h"#include "lwip/api.h"
#include "lwip/sys.h"
/*FreeModBus*/
#include "mb.h"
#include "mbutils.h"/* ----------------------- Defines ------------------------------------------*/
#define PROG                    "FreeModbus"//輸入寄存器起始地址
#define REG_INPUT_START       0x0000
//輸入寄存器數量
#define REG_INPUT_NREGS       8
//保持寄存器起始地址
#define REG_HOLDING_START     0x0000
//保持寄存器數量
#define REG_HOLDING_NREGS     8//線圈起始地址
#define REG_COILS_START       0x0000
//線圈數量
#define REG_COILS_SIZE        16//開關寄存器起始地址
#define REG_DISCRETE_START    0x0000
//開關寄存器數量
#define REG_DISCRETE_SIZE     16/* Private variables ---------------------------------------------------------*/
//輸入寄存器內容
uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};
//輸入寄存器起始地址
uint16_t usRegInputStart = REG_INPUT_START;//保持寄存器內容
uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x147b,0x3f8e,0x147b,0x400e,0x1eb8,0x4055,0x147b,0x408e};
//保持寄存器起始地址
uint16_t usRegHoldingStart = REG_HOLDING_START;//線圈狀態
uint8_t ucRegCoilsBuf[REG_COILS_SIZE / 8] = {0x0f,0x02};
//開關輸入狀態
uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE / 8] = {0x0f,0x02};
/** @addtogroup UTILITIES_examples* @{*//*開始任務*/
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
/** @addtogroup FreeRTOS_demo* @{*/
extern void tcpip_stack_init(void);
extern void udpecho_init(void);
extern void tcpecho_init(void);TaskHandle_t network_handler;/* led3 task */
void network_task_function(void *pvParameters);/*** @brief  main function.* @param  none* @retval none*/
int main(void)
{nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);system_clock_config();/* init led2*/at32_led_init(LED2);/* init led3*/at32_led_init(LED3);/* init led4*/at32_led_init(LED4);/* init usart1 */uart_print_init(115200);/* enter critical */taskENTER_CRITICAL(); if(xTaskCreate((TaskFunction_t )network_task_function,     (const char*    )"Network_task",   (uint16_t       )512, (void*          )NULL,(UBaseType_t    )2,(TaskHandle_t*  )&network_handler) != pdPASS){printf("Network task could not be created as there was insufficient heap memory remaining.\r\n");}        else{printf("Network task was created successfully.\r\n");}/* exit critical */            taskEXIT_CRITICAL();      /* start scheduler */            vTaskStartScheduler(); }static void modbustcp_thread(void *arg)
{	LWIP_UNUSED_ARG(arg);eMBErrorCode    xStatus;eMBTCPInit( MB_TCP_PORT_USE_DEFAULT );eMBEnable();while(1){eMBPoll();vTaskDelay(5);}/* An error occured. Maybe we can restart. */
//		( void )eMBDisable(  );
//		( void )eMBClose(  );//}
}void modbustcp_init(void)
{sys_thread_new("modbustcp_thread", modbustcp_thread, NULL, 512, 4);
}/* led3 task function */
void network_task_function(void *pvParameters)
{while(emac_system_init() == ERROR);tcpip_stack_init();modbustcp_init();taskENTER_CRITICAL();           //進入臨界區vTaskDelete(StartTask_Handler); //刪除開始任務taskEXIT_CRITICAL();            //退出臨界區
}/*** @}*/ /****************************************************************************
* 名	  稱:eMBRegInputCB 
* 功    能:讀取輸入寄存器,對應功能碼是 04 eMBFuncReadInputRegister
* 入口參數:pucRegBuffer: 數據緩存區,用于響應主機   
*						usAddress: 寄存器地址
*						usNRegs: 要讀取的寄存器個數
* 出口參數:
* 注	  意:上位機發來的 幀格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
*								+StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
*								+LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
*								+CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
*							3 區
****************************************************************************/
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{eMBErrorCode    eStatus = MB_ENOERR;int             iRegIndex;/* it already plus one in modbus function method. */usAddress--;if( ( usAddress >= REG_INPUT_START )&& ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ){iRegIndex = ( int )( usAddress - usRegInputStart );while( usNRegs > 0 ){*pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );*pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );iRegIndex++;usNRegs--;}}else{eStatus = MB_ENOREG;}return eStatus;
}/****************************************************************************
* 名	  稱:eMBRegHoldingCB 
* 功    能:對應功能碼有:06 寫保持寄存器 eMBFuncWriteHoldingRegister 
*													16 寫多個保持寄存器 eMBFuncWriteMultipleHoldingRegister
*													03 讀保持寄存器 eMBFuncReadHoldingRegister
*													23 讀寫多個保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
* 入口參數:pucRegBuffer: 數據緩存區,用于響應主機   
*						usAddress: 寄存器地址
*						usNRegs: 要讀寫的寄存器個數
*						eMode: 功能碼
* 出口參數:
* 注	  意:4 區
****************************************************************************/
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{eMBErrorCode    eStatus = MB_ENOERR;int             iRegIndex;/* it already plus one in modbus function method. */usAddress--;if((usAddress >= REG_HOLDING_START)&&\((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS))){iRegIndex = (int)(usAddress - usRegHoldingStart);switch(eMode){                                       case MB_REG_READ://讀 MB_REG_READ = 0while(usNRegs > 0){*pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            *pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); iRegIndex++;usNRegs--;					}                            break;case MB_REG_WRITE://寫 MB_REG_WRITE = 0while(usNRegs > 0){         usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;iRegIndex++;usNRegs--;}				}}else//錯誤{eStatus = MB_ENOREG;}	return eStatus;
}extern void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,UCHAR ucValue );
extern UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits );
/****************************************************************************
* 名	  稱:eMBRegCoilsCB 
* 功    能:對應功能碼有:01 讀線圈 eMBFuncReadCoils
*													05 寫線圈 eMBFuncWriteCoil
*													15 寫多個線圈 eMBFuncWriteMultipleCoils
* 入口參數:pucRegBuffer: 數據緩存區,用于響應主機   
*						usAddress: 線圈地址
*						usNCoils: 要讀寫的線圈個數
*						eMode: 功能碼
* 出口參數:
* 注	  意:如繼電器 
*						0 區
****************************************************************************/
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,eMBRegisterMode eMode )
{//錯誤狀態eMBErrorCode eStatus = MB_ENOERR;//寄存器個數int16_t iNCoils = ( int16_t )usNCoils;//寄存器偏移量int16_t usBitOffset;/* it already plus one in modbus function method. */usAddress--;//檢查寄存器是否在指定范圍內if( ( (int16_t)usAddress >= REG_COILS_START ) &&( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) ){//計算寄存器偏移量usBitOffset = ( int16_t )( usAddress - REG_COILS_START );switch ( eMode ){//讀操作case MB_REG_READ:while( iNCoils > 0 ){*pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,( uint8_t )( iNCoils > 8 ? 8 : iNCoils ) );iNCoils -= 8;usBitOffset += 8;}break;//寫操作case MB_REG_WRITE:while( iNCoils > 0 ){xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,( uint8_t )( iNCoils > 8 ? 8 : iNCoils ),*pucRegBuffer++ );iNCoils -= 8;}break;}}else{eStatus = MB_ENOREG;}return eStatus;
}/****************************************************************************
* 名	  稱:eMBRegDiscreteCB 
* 功    能:讀取離散寄存器,對應功能碼有:02 讀離散寄存器 eMBFuncReadDiscreteInputs
* 入口參數:pucRegBuffer: 數據緩存區,用于響應主機   
*						usAddress: 寄存器地址
*						usNDiscrete: 要讀取的寄存器個數
* 出口參數:
* 注	  意:1 區
****************************************************************************/
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{//錯誤狀態eMBErrorCode eStatus = MB_ENOERR;//操作寄存器個數int16_t iNDiscrete = ( int16_t )usNDiscrete;//偏移量uint16_t usBitOffset;/* it already plus one in modbus function method. */usAddress--; //判斷寄存器時候再制定范圍內if( ( (int16_t)usAddress >= REG_DISCRETE_START ) &&( usAddress + usNDiscrete <= REG_DISCRETE_START + REG_DISCRETE_SIZE ) ){//獲得偏移量usBitOffset = ( uint16_t )( usAddress - REG_DISCRETE_START );while( iNDiscrete > 0 ){*pucRegBuffer++ = xMBUtilGetBits( ucRegDiscreteBuf, usBitOffset,( uint8_t)( iNDiscrete > 8 ? 8 : iNDiscrete ) );iNDiscrete -= 8;usBitOffset += 8;}}else{eStatus = MB_ENOREG;}return eStatus;
}
/*** @}*/ 

? ? usAddress--;每一個都有這個是因為在modbus內部處理的時候,會將地址+1,從1開始。所以讀數組的時候,會出現問題。

現在再次編譯:

我們按照指示,打開mbutils.c

void __aeabi_assert(const char *expr, const char *file, int line) {// 打印斷言失敗信息(根據需要修改,如輸出到串口、LCD等)// 斷言失敗后的處理(如停機、復位等)while (1);  // 死循環,防止程序繼續運行// 或調用復位函數(根據芯片型號,如 NVIC_SystemReset())
}

加入后,編譯通過,下載:

打開tcpip_stack_init();函數,發現綁定ip為172.31.96.101.我的eMBTCPInit( MB_TCP_PORT_USE_DEFAULT );為默認502.

發送數據:讀取8個數據:收到回應。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92468.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis面試精講 Day 16:Redis性能監控與分析工具

【Redis面試精講 Day 16】Redis性能監控與分析工具 開篇 歡迎來到"Redis面試精講"系列第16天&#xff0c;今天我們將深入探討Redis性能監控與分析工具。在大型分布式系統中&#xff0c;Redis作為關鍵的數據存儲和緩存組件&#xff0c;其性能指標直接影響整個系統的…

vue3+vue-flow制作簡單可拖拽可增刪改流程圖

實現效果實現代碼 準備工作 安裝依賴 npm install vue-flow/core npm install vue-flow/minimap //小地圖 npm install vue-flow/controls //自帶的縮放、居中、加鎖功能我這里只用到上述三個&#xff0c;還有其余的可根據實際情況配合官方文檔使用。 npm install vue-flow/bac…

itextPdf獲取pdf文件寬高不準確

正常情況下我們通過下面方式獲取寬高PdfReader reader new PdfReader(file.getPath()); float width reader.getPageSize(1).getWidth(); float height reader.getPageSize(1).getHeight();但是這樣獲取的寬高是不準確的&#xff0c;永遠都是 寬 > 高&#xff0c;也就是橫…

NodeJs學習日志(2):windows安裝使用node.js 安裝express,suquelize,mysql,nodemon

windows安裝使用node.js 安裝express&#xff0c;suquelize&#xff0c;mysql&#xff0c;nodemon 系統是win10&#xff0c;默認已經安裝好nodejs與npm包名作用expressWeb應用框架suquelize數據庫ORMmysql數據庫nodemon代碼熱重載安裝express 添加express生成器 npm add expres…

VueCropper 圖片裁剪組件在Vue項目中的實踐應用

VueCropper 圖片裁剪組件在Vue項目中的實踐應用 1. 組件介紹 VueCropper 是一個基于 Vue.js 的圖片裁剪組件&#xff0c;它提供了豐富的圖片裁剪功能&#xff0c;包括&#xff1a; 圖片縮放、旋轉、移動固定比例裁剪高質量圖片輸出多種裁剪模式選擇 2. 安裝與引入 首先需要安裝…

給同一個wordpress網站綁定多個域名的實現方法

在WordPress網站上綁定多個域名&#xff0c;可以通過以下幾種方法實現&#xff1a; 1. 修改wp-config.php文件 在wp-config.php文件中&#xff0c;找到define(‘WP_DEBUG’, false);&#xff0c;在其下方添加以下代碼&#xff1a; define(WP_SITEURL, http:// . $_SERVER[HT…

HarmonyOS分布式開發實戰:打造跨設備協同應用

&#x1f4d6; 文章目錄 第一章&#xff1a;HarmonyOS分布式架構揭秘第二章&#xff1a;跨設備協同的核心技術第三章&#xff1a;開發環境搭建與配置第四章&#xff1a;實戰項目&#xff1a;智能家居控制系統第五章&#xff1a;數據同步與狀態管理第六章&#xff1a;性能優化與…

用 Enigma Virtual Box 把 Qt 程序壓成單文件 EXE——從編譯、收集依賴到一鍵封包

關鍵詞&#xff1a;Qt、windeployqt、Enigma Virtual Box、單文件、綠色軟件 為什么要打成單文件&#xff1f; 傳統做法&#xff1a;用 windeployqt 把依賴拷進 release 目錄&#xff0c;發給用戶一個文件夾&#xff0c;文件又多又亂。理想做法&#xff1a;把整個目錄壓成一個…

unity中實現選中人物腳下顯示圓形標識且完美貼合復雜地形(如彈坑) 的效果

要實現人物腳下圓形 完美貼合復雜地形&#xff08;如彈坑&#xff09; 的效果&#xff0c;核心思路是 「動態生成貼合地面的 Mesh」 —— 即根據地面的高度場實時計算環形頂點的 Y 坐標&#xff0c;讓每個頂點都 “貼” 在地面上。核心邏輯&#xff1a;確定環形范圍&#xff1a…

引領GameFi 2.0新范式:D.Plan攜手頂級財經媒體啟動“龍珠創意秀”

在GameFi賽道尋求新突破的今天&#xff0c;一個名為Dragonverse Plan&#xff08;D.Plan&#xff09;的項目正以其獨特的經濟模型和宏大愿景&#xff0c;吸引著整個Web3社區的目光。據悉&#xff0c;D.Plan即將聯合中文區頂級加密媒體金色財經與非小號&#xff08;Feixiaohao&a…

通信算法之307:fpga之時序圖繪制

時序圖繪制軟件 一. 序言 在FPGA設計過程中&#xff0c;經常需要編寫設計文檔&#xff0c;其中&#xff0c;不可缺少的就是波形圖的繪制&#xff0c;可以直接截取Vivado或者Modelsim平臺實際仿真波形&#xff0c;但是往往由于信號雜亂無法凸顯重點。因此&#xff0c;通過相應軟…

計網學習筆記第3章 數據鏈路層(灰灰題庫)

題目 11 單選題 下列說法正確的是______。 A. 路由器具有路由選擇功能&#xff0c;交換機沒有路由選擇功能 B. 三層交換機具有路由選擇功能&#xff0c;二層交換機沒有路由選擇功能 C. 三層交換機適合異構網絡&#xff0c;二層交換機不適合異構網絡 D. 路由器適合異構網絡&…

SQL的LEFT JOIN優化

原sql&#xff0c;一個base表a,LEFT JOIN三個表抽數 SELECT ccu.*, ctr.*, om.*, of.* FROM ods.a ccu LEFT JOIN ods.b ctr ON ccu.coupon_code ctr.coupon_code AND ctr.is_deleted 0 LEFT JOIN ods.c om ON ctr.bill_code om.order_id AND om.deleted 0 LEFT JOIN ods.…

Redis 核心概念、命令詳解與應用實踐:從基礎到分布式集成

目錄 1. 認識 Redis 2. Redis 特性 2.1 操作內存 2.2 速度快 2.3 豐富的功能 2.4 簡單穩定 2.5 客戶端語言多 2.6 持久化 2.7 主從復制 2.8 高可用 和 分布式 2.9 單線程架構 2.9.1 引出單線程模型 2.9.2 單線程快的原因 2.10 Redis 和 MySQL 的特性對比 2.11 R…

【Day 18】Linux-DNS解析

目錄 一、DNS概念 1、概念和作用 2、域名解析類型 3、 軟件與服務 4、DNS核心概念 區域 記錄 5、查詢類型 6、分層結構 二、DNS操作 配置本機為DNS內網解析服務器 &#xff08;1&#xff09;修改主配置文件 &#xff08;2&#xff09;添加區域 正向解析區域&#xff1a; …

Python 中 OpenCV (cv2) 安裝與使用介紹

Python 中 OpenCV (cv2) 安裝與使用詳細指南 OpenCV (Open Source Computer Vision Library) 是計算機視覺領域最流行的庫之一。Python 通過 cv2 模塊提供 OpenCV 的接口。 一、安裝 OpenCV 方法 1&#xff1a;基礎安裝&#xff08;推薦&#xff09; # 安裝核心包&#xff0…

微軟WSUS替代方案

微軟WSUS事件回顧2025年7月10日&#xff0c;微軟最新確認Windows Server Update Services&#xff08;WSUS&#xff09;出現了問題&#xff0c;導致IT管理員無法正常同步和部署Windows更新。WSUS是允許管理員根據策略配置&#xff0c;將更新推送到特定計算機&#xff0c;并優化…

Minio 分布式集群安裝配置

目錄創建 mkdir -p /opt/minio/run && mkdir -p /etc/minio && mkdir -p /indata/disk_0/minio/datarun&#xff1a;啟動腳本及二進制文件目錄/etc/minio&#xff1a;配置文件目錄data&#xff1a;數據存儲目錄下載 minio wget https://dl.min.io/server/minio…

Spring Boot + ShardingSphere 實現分庫分表 + 讀寫分離實戰

&#x1f680; Spring Boot ShardingSphere 實現分庫分表 讀寫分離&#xff08;涵蓋99%真實場景&#xff09; &#x1f3f7;? 標簽&#xff1a;ShardingSphere、分庫分表、讀寫分離、MySQL 主從、Spring Boot 實戰 分庫分表 vs 讀寫分離 vs 主從配置與數據庫高可用架構區別 …

將普通用戶添加到 Docker 用戶組

這樣可以避免每次使用 Docker 命令時都需要 sudo。以下是具體步驟&#xff1a;1. 創建 Docker 用戶組&#xff08;如果尚未存在&#xff09; 默認情況下&#xff0c;安裝 Docker 時會自動創建 docker 用戶組。可以通過以下命令檢查&#xff1a; groupadd docker&#xff08;如果…