Coder Social home page Coder Social logo

alejoseb / modbus-stm32-hal-freertos Goto Github PK

View Code? Open in Web Editor NEW
506.0 34.0 174.0 19.48 MB

Modbus TCP and RTU, Master and Slave for STM32 using Cube HAL and FreeRTOS

License: GNU Lesser General Public License v2.1

C 83.12% Jupyter Notebook 16.88%
stm32 plc bluepill modbus modbus-library cube-hal freertos usart usb tcp

modbus-stm32-hal-freertos's Introduction

Modbus library for STM32 Microcontrollers

TCP, USART and USB-CDC Modbus RTU Master and Slave library for STM32 microcontrollers based on Cube HAL and FreeRTOS.

Includes multiple examples for popular development boards including BluePill, NUCLEO-64, NUCLEO-144 and Discovery Boards (Cortex-M3/M4/M7).

This is a port of the Modbus library for Arduino: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino

Video demo for STM32F4-discovery board and TouchGFX: https://youtu.be/XDCQvu0LirY

NEW Script examples to test the library based on Pymodbus

NEW TCP slave (server) multi-client with configurable auto-aging algorithm for management of TCP connections

Translations supported by the community:

Traditional Chinese: 繁體中文

Characteristics:

  • Portable to any STM32 MCU supported by ST Cube HAL.
  • Portable to other Microcontrollers, like the Raspberry PI Pico, requiring little engineering effort.
  • Multithread-safe implementation based on FreeRTOS.
  • Multiple instances of Modbus (Master and/or Slave) can run concurrently in the same MCU, only limited by the number of available UART/USART of the MCU.
  • RS232 and RS485 compatible.
  • USART DMA support for high baudrates with idle-line detection.
  • USB-CDC RTU master and Slave support for F103 Bluepill board.
  • TCP master and slave support with examples for F429 and H743 MCUs

File structure

├── LICENSE
├── README.md
├── Examples
    ├── ModbusBluepill --> STM32F103C8 USART Slave
    ├── ModbusBluepillUSB --> STM32F103C8 USART + USB-CDC Master and Slave 
    ├── ModbusF103 --> NUCLEO-F103RB Modbus Master and Slave
    ├── ModbusF429 --> NUCLEO-F429ZI Modbus Slave 
    ├── ModbusF429TCP --> NUCLEO-F429ZI Modbus TCP
    ├── ModbusF429DMA --> NUCLEO-F429ZI Modbus RTU DMA master and slave 
    ├── ModbusL152DMA --> NUCLEO-L152RE Modbus RTU DMA slave
    ├── ModbusH743 --> NUCLEO-H743ZI Modbus Slave
    ├── ModbusH743TCP --> NUCLEO-H743ZI Modbus TCP
    ├── ModbusF303 --> NUCLEO-F303RE Modbus Slave
    ├── ModbusSTM32F4-discovery --> STM32F4-discovery TouchGFX + Modbus Master
    ├── ModbusWB55DMA --> P-NUCLEO-WB55 Modbus RTU DMA slave with RS485 
    ├── ModbusG070 --> NUCLEO-G070RB Modbus Slave
    ├── ModbusF030 --> STM32F030RCT6 USART Slave
├── Script
    ├── *.ipynb --> various master and slave Jupyter notebooks for testing
├── MODBUS-LIB --> Library Folder
    ├── Inc
    │   └── Modbus.h 
    ├── Config
    │   └── ModbusConfigTemplate.h --> Configuration Template
    └── Src
        ├── Modbus.c 
        └── UARTCallback.c
 

How to use the examples

Examples provided for STM32CubeIDE Version: 1.8.0 https://www.st.com/en/development-tools/stm32cubeide.html.

  • Import the examples in the STM32Cube IDE from the system folder
  • Connect your NUCLEO board
  • Compile and start your debugging session!
  • If you need to adjust the Baud rate or any other parameter use the Cube-MX assistant (recommended). If you change the USART port you need to enable the interrupts for the selected USART. Check UARTCallback.c for more details.

Notes and Known issues :

  • The standard interrupt mode for Modbus RTU USART is suitable for 115200 bps or lower baud rates. For Higher baud rates---tested up to 2 Mbps---it is recommended to use the DMA mode. Check the corresponding examples. It will require extra configurations for the DMA channels in the Cube HAL.

  • The USB-CDC example supports only the Bluepill development board. It has not been validated with other development boards. To use this example, you need to activate USB-CDC in your ModbusConfig.h file.

  • The TCP examples have been validated with NUCLEO F429ZI and H743ZI. To use these examples, you need to activate TCP in your ModbusConfig.h file.

  • The HAL implementation for LWIP TCP of the CubeMX generates code that might not work if the cable is not connected from the very beginning. This is a known issue that can be solved manually changing the generated code as detailed here: https://community.st.com/s/question/0D50X0000CDolzDSQR/ethernet-does-not-work-if-uc-starts-with-the-cable-disconnected

Check the TCP example for the NUCLEO F429, which includes the manual modifications.

How to port to your own MCU

  • Create a new project in STM32Cube IDE for your MCU
  • Enable FreeRTOS CMSIS_V2 in the middleware section of Cube-MX
  • Configure a USART and activate the global interrupt
  • If you are using the DMA mode for USART, configure the DMA requests for RX and TX
  • Configure the Preemption priority of USART interrupt to a lower priority (5 or a higher number for a standard configuration) than your FreeRTOS scheduler. This parameter is changed in the NVIC configuration pane.
  • Import the Modbus library folder (MODBUS-LIB) using drag-and-drop from your host operating system to your STM32Cube IDE project
  • When asked, choose link folders and files
  • Update the include paths in the project's properties to include the Inc folder of MODBUS-LIB folder
  • Create a ModbusConfig.h using the ModbusConfigTemplate.h and add it to your project in your include path
  • Instantiate a new global modbusHandler_t and follow the examples provided in the repository
  • Note: If your project uses the USART interrupt service for other purposes you have to modify the UARTCallback.c file accordingly

Recommended Modbus Master and Slave testing tools for Linux and Windows

Master and slave Python library

Linux/Windows: https://github.com/riptideio/pymodbus

Master client Qmodbus

Linux: https://launchpad.net/~js-reynaud/+archive/ubuntu/qmodbus

Windows: https://sourceforge.net/projects/qmodbus/

Slave simulator

Linux: https://sourceforge.net/projects/pymodslave/

Windows: https://sourceforge.net/projects/modrssim2/

TODOs:

  • Implement isolated memory spaces for coils, inputs and holding registers.
  • Implement wrapper functions for Master function codes. Currently, telegrams are defined manually.
  • Improve function documentation
  • MODBUS TCP implementation improvement to support multiple clients and TCP session management (10/24/2021)
  • Improve the queue for data reception; the current method is too heavy it should be replaced with a simple buffer, a stream, or another FreeRTOS primitive. Solved Queue replaced by a Ring Buffer (03/19/2021)
  • Test with Rs485 transceivers (implemented but not tested) Verified with MAX485 transceivers (01/03/2021)
  • MODBUS TCP implementation (28/04/2021)

modbus-stm32-hal-freertos's People

Contributors

alejoseb avatar bigjiongeagle avatar butaforsky avatar godchadigo avatar heme2 avatar nguyenlam185 avatar r0tary avatar samo4 avatar zateeman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modbus-stm32-hal-freertos's Issues

install in keil

Dear Alejoseb

Thanks for your stm32 modbus Library.

Please tell how to install this library in keil.

Best Regards

Portability with other ics

Dear concern

As you have mentioned that the project is portable for all stm32, please specify how to open or use for my IC stm32f103c8tx. Im a bit new with cubemx so your helo would be grateful.

CRC check of received frame error

I have received CRC failed error and while debugging the crc value for received frame is taken as transmitted frame crc value. because the last values in the au8Buffer were transmission frame. So the value of crc is miss interupted.

TCP session terminated

    Hi alejoseb,

Thank you for the codes you posted.
I used example ModbusF429TCP for my board. My board is STM32F429IGT6. My board with IP 192.168.1.190 is the client(master). I have used Modbus Slave software as a server(slave) in the system with IP 192.168.1.101. Currently,The problem is that after a short time of starting the connection, no more data is sent from the board side. At this moment, if ACK is not sent from the board side for the current slave packet, it will lead to retransmission from the slave side. The question is why the board as the master no longer sends data.. I am attaching the photos of Wireshark software and tools.
Wireshark:
w1
w2
w3
w4
Modbus Slave:
MB_slave
STM32CubeIDE- main.c:
MB_MasterType
STM32CubeIDE- freertos.c:
Code

Originally posted by @Aimhighn in #62 (comment)

H743 master issue

I can't set my device as master. I used slave example.

    ModbusH.uModbusType = MB_MASTER;
    ModbusH.port =  &huart3; // This is the UART port connected to STLINK in the NUCLEO F429
    ModbusH.u8id = 0; //slave ID
    ModbusH.u16timeOut = 1000;
    ModbusH.EN_Port = NULL; // No RS485

NOT COMMUNICATING WITH THE PC ! Can you provide detailed information for Master device settings ?

Corrupted answer from slave

Hi, first of all, thanks for your work to porting that arduino library what i'm using in a couple of devices. I have started to learn programming STM32 devices and FREE_RTOS and exactly this library is that what i need. So i will try to explain what issue i faced.
The master device is an STM32F103RB MCU with an a SP485E transceiver attached to USART3 (Interrupt enabled, priority 5, 9600bps 8N1). The slave is an a Arduino ProMini (M328) with MAX485 transceiver on Serial. I have tried with modified example of ModbusF103 (Just master task) and i faced many dropped incoming package due to CRC ERROR (Average ~40% error rate). If i use more tasks (2 extra task to blink LEDs with different interval using osDelay functions in it) then the error rate jumps up to >90%. I found that when the error occurs then the first byte from the answer stream is lost somewhere (Slave ID) and this causes CRC problem (the whole message is came to MCU i have checked with Logic analyzer).

void StartTaskMaster(void *argument)
{
  /* USER CODE BEGIN StartTaskMaster */
  /* Infinite loop */
	 // telegram 0: read registers

  uint32_t u32NotificationValue;

  // telegram 0: read registers
  telegram[0].u8id = 0x01; // slave address
  telegram[0].u8fct = 0x03; // function code (this one is registers read)
  telegram[0].u16RegAdd = 0x01; // start address in slave
  telegram[0].u16CoilsNo = 0x03; // number of elements (coils or registers) to read
  telegram[0].au16reg = ModbusDATA+1; // pointer to a memory array in the Arduino


  // telegram 1: write registers
  telegram[1].u8id = 0x01; // slave address
  telegram[1].u8fct = 0x06; // function code (this one is registers write)
  telegram[1].u16RegAdd = 0x00;
  telegram[1].u16CoilsNo = 0x01; // number of elements (coils or registers) to read
  telegram[1].au16reg = ModbusDATA; // pointer to a memory array in the Arduino


  for(;;)
  {
	  /*
	  ModbusQuery(&ModbusH, telegram[0]); // make a query
	  u32NotificationValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // block until query finishes
	  if(u32NotificationValue)
	  {
		//handle error
		//  while(1);
	  }
	 // osDelay(1000);
*/


	  ModbusDATA[0] ^= 0xFFFF;
	  ModbusQuery(&ModbusH, telegram[1]); // make a query
	  u32NotificationValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // block until query finishes
	  if(u32NotificationValue)
	  {
	  	//handle error
		//  while(1);
	  }

	 osDelay(1000);
  }
  /* USER CODE END StartTaskMaster */
}

Screenshot_20210103_131212
Screenshot_20210103_131448

Extra zero byte "received" from RTU corrupts checksum

I'm sending a modbus message through this library in master mode at 9600 8N1. The modbus is set up with the following parameters:

m_handler.uModbusType = MB_MASTER;
 m_handler.xTypeHW = USART_HW;
 m_handler.port = &huart4;
 // Master ID must be 0.
 m_handler.u8id = 0;
 m_handler.u16timeOut = 1000;
 // RS485 enable pin (UART_DE/UART_RTS).
 m_handler.EN_Port = EE_485_RDis_TEn_GPIO_Port;
 m_handler.EN_Pin = EE_485_RDis_TEn_Pin;
 m_handler.u32timeOut = 0;
 m_handler.u16regs = m_data;
 m_handler.u16regsize = sizeof(m_data) / sizeof(m_data[0]);

The device on the other end acknowledges the message as shown in the attached image. Unfortunately, the RX data buffer shows the data with an extra zero (0) byte at the beginning of the message so it is 9 bytes long instead of 8. It appears to be reading the one character delay between transmit and receive as another byte of transmission.

Unfortunately, this causes the validateAnswer function called from StartTaskModbusMaster to fail on the checksum calculation. Is there a modbus setup parameter that might cause this extra initial zero byte? What am I missing?

Modbus oscope

Behavior of library when there is spurious noise on modbus at powerup

My code uses this library by sending a command and immediately waiting for a response, so each transaction is one-to-one. However, I am seeing responses getting out of sync with requests by 5, i.e., a modbus request doesn't see the corresponding response for 5 subsequent transactions. I assume data in the RX buffer is due to some initial noise on the UART receive inputs as the modbus device on the other end of the wires is powering up.

Regardless of the cause, is there a recommended way to purge the receive ring buffer? Calling RingClear on the receive buffer (xRingBuffer) won't work reliably because it doesn't have the locks around it to block simultaneous interrupts.

Any getting started documentation?

Is there any documentation on how to get started? I need to configure a modbus device that will be a slave and return things like GPIO states and Analogue read values in coils and registers. It would be great if there were a simple guide to providing coils, holding registers and input registers for example. Also a simple guide on how to configure the UART port that is used including the pin for driving TXEN on the RS485 driver.
Did I miss something obvious. I am not a trained programmer and I have no idea where to look to get this info if is not in a readme or similar. I am trying to use this with the Blue Pill and have not found any details on what to do when looking at the Blue Pill example. If I compile the example, what does it provide? How would I extend it to return GPIO status etc.?

Receiving UART data from a UART port different than the Modbus port causes Modbus to stop working

Hi there,

Thanks for this great library! I'm seeing the following problem:

  • If I only use the Modbus library on UART port 1, everything works well.

  • If I enable UART port 2 to output messages via HAL_UART_Transmit(&huart2, data, size, timeout), Modbus on UART port 1 still works fine.

  • However, once I try to receive input on UART port 2 (e.g. via HAL_UART_Receive(&huart2, data, size, timeout), Modbus on UART port 1 no longer works.

Do you know what I'm missing here?

Note: I added conditional checks in UARTCallback.c to only run the code logic in the callbacks for the &huart1 instance. If the &huart2 instance is detected, the callbacks do nothing.

Coil, holding/input register and discrete input mapping/callback in slave mode

I am trying to use this library for a modbus slave. I couldn’t find any mechanism to map u16_registers to coils/ holding reg/ input reg/ discrete input.
Is there any callback mechanism?

I can see a semaphore to aceess modbus data. Should I use semaphore to access in other task?

Let's say I would like to toggle a LED(coil) in a freeRTOS task depending on modbus command, how do I do that?

Also from my current understanding, I don’t see any way to prevent write in an input register/ discrete input.

Did I miss that in example, or is my understanding is wrong?

Add function that blocks until au16regs is updated

Currently ModbusQuery returns immediately, and the user must check periodically to determine whether au16regs has been updated. It would be nice to have a new function (ModbusQueryBlock) that blocks until xSemaphoreGive(modH->ModBusSphrHandle); //Release the semaphore is run.

Ethernet Communication with Lwip TCP /IP

Hello,

I've added the Modbus TCP library with the ModbusH743TCP example for my own project. My board is stm32h747-disc0. I am trying to see the firstly ethernet communication between board to pc over Ethernet peripheral. Software gets stuck into prvCheckTasksWaitingTermination() but I think it is not related to your Modbus library. When I ping the IP over the cmd window I couldn't be able to communicate with the board yet. To do that, which parts of code do I need to check especially?

Thanks in advance.

error in modbus poll "insufficient bytes received"

Hello, I am a beginner to freertos, and I need help with some questions that I don’t understand.
I ran the code on the B-L475EIOTA2 development board and used this board as a modbus slave station,and send a response using modbus poll, but an error was reported on the modbus poll:insufficient bytes received.
It seems that the board has received the data from the master station, but failed to send the response packet. Why? Where does the source code need to be modified?

License clarification

Hi,

I'm considering using your library in a closed-source project. I've read the LGPL, and I'm not sure how to use it in a project such as this. It seems like it's hard to use LGPL libraries on microcontrollers, because we don't have dynamic linking. Would you consider providing your interpretation of how this library can be used on a statically-linked microcontroller project? Alternatively, would you consider a similar library that doesn't encumber in the case of static linking?

Thanks!

Modbus RTU By using USART DMA

Hello I am using the Modbus-STM32-HAL-FreeRTOS library that you made. I am testing the part using DMA. I am using stm32 L462VETx board as MCU and RS485_Click module. But I have a problem with the frame that I send.
When I decode the frame on the oscilloscope the function code is found at the ID (so it creates a frame shift) as you can see in this Screenshot
image
Please can you help me. Thanks

Fail to access a register address above 255

Hi,
I have 2600 registers (40000-42600)
I fail to read above 4256
I see that in the code you put the 16bit address into an 8bit variable, is this OK?

int8_t process_FC3(modbusHandler_t *modH)
{

    uint8_t u8StartAdd = word( modH->u8Buffer[ ADD_HI ], modH->u8Buffer[ ADD_LO ] );

Modbus TCP, ERR_BAD_SIZE reading coils.

Hi,

While using the MCU as a Modbus TCP master, trying to read 8 or less coils from a slave throws ERR_BAD_SIZE. I'm using pyModSlave as a slave.

I checked that request and response ADUs are correct with Wireshark, and also that the buffer in 'TCPgetRxBuffer' (Modbus.c) matches with the response ADU.

Debugging 'TCPgetRxBuffer' function, I noticed that in line 997 there is this condition:
if (buflen>11) { // minimum frame size for modbus TCP

In the case I described above, buffer length is exactly 10 bytes:
Transaction ID (2 bytes) + Protocol ID (2 bytes) + N.º following bytes (2 bytes) + Slave ID (1 byte) + Function Code (1 byte) + Data length (1 byte) + Data (1 byte in this case)

Is this a case the code currently doesn't take into account or am I missing something else?

Using Modbus with lwip

I have successfully implemented Modbus library and it is working properly in RTU_Slave mode. But when I try to add ethernet(TCP/IP), it fails. I can't even ping my device. I think the problem is task management. Ethernet manager task priority is Normal. what do you suggest to me?

MB-TCP (Using ETH-TO-SERIAL module)

Hi Alejandro,
Thank you for sharing the Library.
I am working on Modbus TCP and I have come across some problems.
The MCU is STM32L151RE and I want to use wiz105SR (ETH-TO-SERIAL) module for making connections between MCU and network. So I used the MODBSUF429TCP example and am trying to modify it for my system.
Considering the system as the slave, how can I modify the library?

modbus TCP Slave tool test is showing errors

Hi,

Thank you @alejoseb for the work you did under this library and I found it very useful.
I'm using modbus tcp slave and master for my stm32h7, when I tested the slave mode the Modbus Poll tool is showing : Read Error and Write Error after every poll ,so I tested the master and slave at the same time in order to store the incrementing value at the same register ModbusDATA but the errors are blocking the incrementation in modbus poll tool, Do you think that is related to the fact that in the slave mode, the slave is disconnecting after every poll?

Looking for your help

1 Master and Multiple Slave Error

Hi! First of all, thank you for this library! It is working very well as Modbus Master.

1 Master and 1 Slave is working as expected.

However when I try to query from multiple slave devices, randomly one of the slaves is crashing.

After some time, one of these devices is not responding.

When I try to communicate with the Modbus Slave Desktop app, it is working as expected.
I also tried different Modbus Slave Library(eziya/STM32_HAL_FREEMODBUS_RTU) and your Master library, it is working as expected too.

I have changed the variable names for easy to understand. And added some code pieces for my application.
But when I try to use your original library, the problem is still occurring.

Here is the Master Init

  ModbusMaster.Mb_Type = MASTER_RTU;
  ModbusMaster.port =  &huart2;
  ModbusMaster.Mb_ID = 0;
  ModbusMaster.EN_Port = GPIOA;
  ModbusMaster.EN_Pin = GPIO_PIN_1;
  ModbusMaster.LED_Port = GPIOA;
  ModbusMaster.LED_Pin = GPIO_PIN_15;
  ModbusMaster.MB_Regs = slave1_r;
  ModbusMaster.Mb_Reg_Size = sizeof(slave1_r)/sizeof(slave1_r[0]);
  ModbusMaster.Mb_Timer_Period = 500;
	
  ModbusInit(&ModbusMaster);
  ModbusStart(&ModbusMaster);

Telegram assignments

mb_master_function[0].Mb_M_Slave_ID = 10;								
mb_master_function[0].Mb_M_Function = MB_FC_READ_REGISTERS;								
mb_master_function[0].Mb_M_Start_Address = 0x00;				
mb_master_function[0].Mb_M_Reg_Size = 10;								
mb_master_function[0].Mb_M_Regs = slave1_r;	
  
mb_master_function[1].Mb_M_Slave_ID = 10;								
mb_master_function[1].Mb_M_Function = MB_FC_WRITE_MULTIPLE_REGISTERS;								
mb_master_function[1].Mb_M_Start_Address = 0x0A;				
mb_master_function[1].Mb_M_Reg_Size = 10;								
mb_master_function[1].Mb_M_Regs = slave1_w;
/*********************************************************************************************************************************/
mb_master_function[2].Mb_M_Slave_ID = 11;									
mb_master_function[2].Mb_M_Function = MB_FC_READ_REGISTERS;									
mb_master_function[2].Mb_M_Start_Address = 0x00;					
mb_master_function[2].Mb_M_Reg_Size = 10;									
mb_master_function[2].Mb_M_Regs = slave2_r;	
  
mb_master_function[3].Mb_M_Slave_ID = 11;									
mb_master_function[3].Mb_M_Function = MB_FC_WRITE_MULTIPLE_REGISTERS;									
mb_master_function[3].Mb_M_Start_Address = 0x0A;					
mb_master_function[3].Mb_M_Reg_Size = 10;									
mb_master_function[3].Mb_M_Regs = slave2_w;	
/*********************************************************************************************************************************/
mb_master_function[4].Mb_M_Slave_ID = 12;									
mb_master_function[4].Mb_M_Function = MB_FC_READ_REGISTERS;									
mb_master_function[4].Mb_M_Start_Address = 0x00;					
mb_master_function[4].Mb_M_Reg_Size = 10;									
mb_master_function[4].Mb_M_Regs = slave3_r;	
  
mb_master_function[5].Mb_M_Slave_ID = 12;									
mb_master_function[5].Mb_M_Function = MB_FC_WRITE_MULTIPLE_REGISTERS;									
mb_master_function[5].Mb_M_Start_Address = 0x0A;					
mb_master_function[5].Mb_M_Reg_Size = 10;									
mb_master_function[5].Mb_M_Regs = slave3_w;

Master Task

error_codes[0] = Modbus_Master_Query(&ModbusMaster, mb_master_function[0], &error_counter[0]);
		
 osDelay(50);
		
 Modbus_Master_Query(&ModbusMaster, mb_master_function[1], 0);
		
 osDelay(250);
		
 /***********************************************************************************************************************/
    
 error_codes[1] = Modbus_Master_Query(&ModbusMaster, mb_master_function[2], &error_counter[1]);
		
 osDelay(50);
		
 Modbus_Master_Query(&ModbusMaster, mb_master_function[3], 0);
		
 osDelay(250);
		
 /***********************************************************************************************************************/
    
 error_codes[2] = Modbus_Master_Query(&ModbusMaster, mb_master_function[4], &error_counter[2]);
		
 osDelay(50);
		
 Modbus_Master_Query(&ModbusMaster, mb_master_function[5], 0);
		
 osDelay(250);

Thank you!

unknown type errors when trying to use library

Hello. I have downloaded your modbus library and I am trying to use it. I use STM32F407. I have followed the steps that you have suggested:

  1. In CUBEMX, configured UART4 which I want to use for MODBUS
  2. Activated global interrupt
  3. Enabled DMA RX TX
    image
  4. Imported the MODBUS-LIB to my project, updated include path in project properties
  5. I have renamed ModbusConfigTemplate.h to ModbusConfig.h

When I try to build the project, I get 30 errors ( most of them are due to unknown types)

Project build log:

In file included from ../MODBUS-LIB/Src/Modbus.c:14:
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:195:2: error: unknown type name 'osMessageQueueId_t'
  195 |  osMessageQueueId_t QueueTelegramHandle;
      |  ^~~~~~~~~~~~~~~~~~
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:198:2: error: unknown type name 'osThreadId_t'
  198 |  osThreadId_t myTaskModbusAHandle;
      |  ^~~~~~~~~~~~
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:204:2: error: unknown type name 'osSemaphoreId_t'
  204 |  osSemaphoreId_t ModBusSphrHandle;
      |  ^~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:44:7: error: unknown type name 'osMessageQueueAttr_t'
   44 | const osMessageQueueAttr_t QueueTelegram_attributes = {
      |       ^~~~~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:45:8: error: field name not in record or union initializer
   45 |        .name = "QueueModbusTelegram"
      |        ^
../MODBUS-LIB/Src/Modbus.c:45:8: note: (near initialization for 'QueueTelegram_attributes')
../MODBUS-LIB/Src/Modbus.c:45:16: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   45 |        .name = "QueueModbusTelegram"
      |                ^~~~~~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:45:16: note: (near initialization for 'QueueTelegram_attributes')
../MODBUS-LIB/Src/Modbus.c:49:7: error: unknown type name 'osThreadAttr_t'
   49 | const osThreadAttr_t myTaskModbusA_attributes = {
      |       ^~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:50:5: error: field name not in record or union initializer
   50 |     .name = "TaskModbusSlave",
      |     ^
../MODBUS-LIB/Src/Modbus.c:50:5: note: (near initialization for 'myTaskModbusA_attributes')
../MODBUS-LIB/Src/Modbus.c:50:13: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   50 |     .name = "TaskModbusSlave",
      |             ^~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:50:13: note: (near initialization for 'myTaskModbusA_attributes')
../MODBUS-LIB/Src/Modbus.c:51:5: error: field name not in record or union initializer
   51 |     .priority = (osPriority_t) osPriorityNormal,
      |     ^
../MODBUS-LIB/Src/Modbus.c:51:5: note: (near initialization for 'myTaskModbusA_attributes')
../MODBUS-LIB/Src/Modbus.c:51:18: error: 'osPriority_t' undeclared here (not in a function); did you mean 'osPriority'?
   51 |     .priority = (osPriority_t) osPriorityNormal,
      |                  ^~~~~~~~~~~~
      |                  osPriority
../MODBUS-LIB/Src/Modbus.c:51:17: warning: excess elements in scalar initializer
   51 |     .priority = (osPriority_t) osPriorityNormal,
      |                 ^
../MODBUS-LIB/Src/Modbus.c:51:17: note: (near initialization for 'myTaskModbusA_attributes')
../MODBUS-LIB/Src/Modbus.c:51:32: error: expected '}' before 'osPriorityNormal'
   51 |     .priority = (osPriority_t) osPriorityNormal,
      |                                ^~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:49:49: note: to match this '{'
   49 | const osThreadAttr_t myTaskModbusA_attributes = {
      |                                                 ^
../MODBUS-LIB/Src/Modbus.c:55:7: error: unknown type name 'osThreadAttr_t'
   55 | const osThreadAttr_t myTaskModbusA_attributesTCP = {
      |       ^~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:56:5: error: field name not in record or union initializer
   56 |     .name = "TaskModbusSlave",
      |     ^
../MODBUS-LIB/Src/Modbus.c:56:5: note: (near initialization for 'myTaskModbusA_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:56:13: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   56 |     .name = "TaskModbusSlave",
      |             ^~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:56:13: note: (near initialization for 'myTaskModbusA_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:57:5: error: field name not in record or union initializer
   57 |     .priority = (osPriority_t) osPriorityNormal,
      |     ^
../MODBUS-LIB/Src/Modbus.c:57:5: note: (near initialization for 'myTaskModbusA_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:57:17: warning: excess elements in scalar initializer
   57 |     .priority = (osPriority_t) osPriorityNormal,
      |                 ^
../MODBUS-LIB/Src/Modbus.c:57:17: note: (near initialization for 'myTaskModbusA_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:57:32: error: expected '}' before 'osPriorityNormal'
   57 |     .priority = (osPriority_t) osPriorityNormal,
      |                                ^~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:55:52: note: to match this '{'
   55 | const osThreadAttr_t myTaskModbusA_attributesTCP = {
      |                                                    ^
../MODBUS-LIB/Src/Modbus.c:65:7: error: unknown type name 'osThreadAttr_t'
   65 | const osThreadAttr_t myTaskModbusB_attributes = {
      |       ^~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:66:5: error: field name not in record or union initializer
   66 |     .name = "TaskModbusMaster",
      |     ^
../MODBUS-LIB/Src/Modbus.c:66:5: note: (near initialization for 'myTaskModbusB_attributes')
../MODBUS-LIB/Src/Modbus.c:66:13: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   66 |     .name = "TaskModbusMaster",
      |             ^~~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:66:13: note: (near initialization for 'myTaskModbusB_attributes')
../MODBUS-LIB/Src/Modbus.c:67:5: error: field name not in record or union initializer
   67 |     .priority = (osPriority_t) osPriorityNormal,
      |     ^
../MODBUS-LIB/Src/Modbus.c:67:5: note: (near initialization for 'myTaskModbusB_attributes')
../MODBUS-LIB/Src/Modbus.c:67:17: warning: excess elements in scalar initializer
   67 |     .priority = (osPriority_t) osPriorityNormal,
      |                 ^
../MODBUS-LIB/Src/Modbus.c:67:17: note: (near initialization for 'myTaskModbusB_attributes')
../MODBUS-LIB/Src/Modbus.c:67:32: error: expected '}' before 'osPriorityNormal'
   67 |     .priority = (osPriority_t) osPriorityNormal,
      |                                ^~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:65:49: note: to match this '{'
   65 | const osThreadAttr_t myTaskModbusB_attributes = {
      |                                                 ^
../MODBUS-LIB/Src/Modbus.c:72:7: error: unknown type name 'osThreadAttr_t'
   72 | const osThreadAttr_t myTaskModbusB_attributesTCP = {
      |       ^~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:73:5: error: field name not in record or union initializer
   73 |     .name = "TaskModbusMaster",
      |     ^
../MODBUS-LIB/Src/Modbus.c:73:5: note: (near initialization for 'myTaskModbusB_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:73:13: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   73 |     .name = "TaskModbusMaster",
      |             ^~~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:73:13: note: (near initialization for 'myTaskModbusB_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:74:5: error: field name not in record or union initializer
   74 |     .priority = (osPriority_t) osPriorityNormal,
      |     ^
../MODBUS-LIB/Src/Modbus.c:74:5: note: (near initialization for 'myTaskModbusB_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:74:17: warning: excess elements in scalar initializer
   74 |     .priority = (osPriority_t) osPriorityNormal,
      |                 ^
../MODBUS-LIB/Src/Modbus.c:74:17: note: (near initialization for 'myTaskModbusB_attributesTCP')
../MODBUS-LIB/Src/Modbus.c:74:32: error: expected '}' before 'osPriorityNormal'
   74 |     .priority = (osPriority_t) osPriorityNormal,
      |                                ^~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:72:52: note: to match this '{'
   72 | const osThreadAttr_t myTaskModbusB_attributesTCP = {
      |                                                    ^
../MODBUS-LIB/Src/Modbus.c:82:7: error: unknown type name 'osSemaphoreAttr_t'
   82 | const osSemaphoreAttr_t ModBusSphr_attributes = {
      |       ^~~~~~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:83:5: error: field name not in record or union initializer
   83 |     .name = "ModBusSphr"
      |     ^
../MODBUS-LIB/Src/Modbus.c:83:5: note: (near initialization for 'ModBusSphr_attributes')
../MODBUS-LIB/Src/Modbus.c:83:13: warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
   83 |     .name = "ModBusSphr"
      |             ^~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c:83:13: note: (near initialization for 'ModBusSphr_attributes')
../MODBUS-LIB/Src/Modbus.c: In function 'ModbusInit':
../MODBUS-LIB/Src/Modbus.c:226:33: warning: implicit declaration of function 'osThreadNew'; did you mean 'osThreadDef'? [-Wimplicit-function-declaration]
  226 |     modH->myTaskModbusAHandle = osThreadNew(StartTaskModbusSlave, modH, &myTaskModbusA_attributes);
      |                                 ^~~~~~~~~~~
      |                                 osThreadDef
../MODBUS-LIB/Src/Modbus.c:263:33: warning: implicit declaration of function 'osMessageQueueNew'; did you mean 'osMessageDelete'? [-Wimplicit-function-declaration]
  263 |     modH->QueueTelegramHandle = osMessageQueueNew (MAX_TELEGRAMS, sizeof(modbus_t), &QueueTelegram_attributes);
      |                                 ^~~~~~~~~~~~~~~~~
      |                                 osMessageDelete
../MODBUS-LIB/Src/Modbus.c:265:34: warning: comparison between pointer and integer
  265 |     if(modH->QueueTelegramHandle == NULL)
      |                                  ^~
../MODBUS-LIB/Src/Modbus.c:276:35: warning: comparison between pointer and integer
  276 |    if  (modH->myTaskModbusAHandle == NULL)
      |                                   ^~
arm-none-eabi-gcc "../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c" -mcpu=cortex-m4 -std=gnu11 -DUSE_HAL_DRIVER -DSTM32F407xx -c -I../Core/Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc -I../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy -I../Middlewares/Third_Party/FreeRTOS/Source/include -I../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS -I../Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -I../Drivers/CMSIS/Device/ST/STM32F4xx/Include -I../Drivers/CMSIS/Include -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/ADS7828/Inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/Custom_IO/Inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/MCP41/Inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/PCA9539/Inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/TB_specific/inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/UART3/inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc" -I"C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Config" -Os -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.d" -MT"Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.o"
In file included from ../MODBUS-LIB/Src/UARTCallback.c:12:
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:195:2: error: unknown type name 'osMessageQueueId_t'
  195 |  osMessageQueueId_t QueueTelegramHandle;
      |  ^~~~~~~~~~~~~~~~~~
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:198:2: error: unknown type name 'osThreadId_t'
  198 |  osThreadId_t myTaskModbusAHandle;
      |  ^~~~~~~~~~~~
C:/Users/petrikas.lu/Desktop/WORK/UTB/MODBUS-LIB/Inc/Modbus.h:204:2: error: unknown type name 'osSemaphoreId_t'
  204 |  osSemaphoreId_t ModBusSphrHandle;
      |  ^~~~~~~~~~~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:57,
                 from ../MODBUS-LIB/Src/UARTCallback.c:9:
../MODBUS-LIB/Src/UARTCallback.c: In function 'HAL_UART_TxCpltCallback':
../MODBUS-LIB/Src/Modbus.c:294:29: warning: implicit declaration of function 'osSemaphoreNew'; did you mean 'osSemaphoreDef'? [-Wimplicit-function-declaration]
  294 |    modH->ModBusSphrHandle = osSemaphoreNew(1, 1, &ModBusSphr_attributes);
      |                             ^~~~~~~~~~~~~~
      |                             osSemaphoreDef
../MODBUS-LIB/Src/Modbus.c:296:30: warning: comparison between pointer and integer
  296 |    if(modH->ModBusSphrHandle == NULL)
      |                              ^~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:57,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../MODBUS-LIB/Src/Modbus.c: In function 'vTimerCallbackT35':
../MODBUS-LIB/Src/Modbus.c:461:28: warning: passing argument 1 of 'xTaskGenericNotify' makes pointer from integer without a cast [-Wint-conversion]
  461 |    xTaskNotify(mHandlers[i]->myTaskModbusAHandle, 0, eSetValueWithOverwrite);
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1854:78: note: in definition of macro 'xTaskNotify'
 1854 | #define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
      |                                                                              ^~~~~~~~~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1853:45: note: expected 'TaskHandle_t' {aka 'struct tskTaskControlBlock *'} but argument is of type 'int'
 1853 | BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;
      |                                ~~~~~~~~~~~~~^~~~~~~~~~~~~
../MODBUS-LIB/Src/Modbus.c: In function 'vTimerCallbackTimeout':
../MODBUS-LIB/Src/Modbus.c:476:29: warning: passing argument 1 of 'xTaskGenericNotify' makes pointer from integer without a cast [-Wint-conversion]
  476 |     xTaskNotify(mHandlers[i]->myTaskModbusAHandle, ERR_TIME_OUT, eSetValueWithOverwrite);
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1854:78: note: in definition of macro 'xTaskNotify'
 1854 | #define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL )
      |                                                                              ^~~~~~~~~~~~~
../MODBUS-LIB/Src/UARTCallback.c:34:38: warning: passing argument 1 of 'xTaskGenericNotifyFromISR' makes pointer from integer without a cast [-Wint-conversion]
   34 |       xTaskNotifyFromISR(mHandlers[i]->myTaskModbusAHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1945:119: note: in definition of macro 'xTaskNotifyFromISR'
 1945 | #define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )
      |                                                                                                                       ^~~~~~~~~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1853:45: note: expected 'TaskHandle_t' {aka 'struct tskTaskControlBlock *'} but argument is of type 'int'
 1853 | BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION;
      |                                ~~~~~~~~~~~~~^~~~~~~~~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1944:52: note: expected 'TaskHandle_t' {aka 'struct tskTaskControlBlock *'} but argument is of type 'int'
 1944 | BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
      |                                       ~~~~~~~~~~~~~^~~~~~~~~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:60,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../MODBUS-LIB/Src/Modbus.c: In function 'StartTaskModbusSlave':
../MODBUS-LIB/Src/Modbus.c:731:21: warning: passing argument 1 of 'xQueueSemaphoreTake' makes pointer from integer without a cast [-Wint-conversion]
  731 |  xSemaphoreTake(modH->ModBusSphrHandle , portMAX_DELAY); //before processing the message get the semaphore
../Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h:289:74: note: in definition of macro 'xSemaphoreTake'
  289 | #define xSemaphoreTake( xSemaphore, xBlockTime )  xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
      |                                                                          ^~~~~~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:59,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:1418:47: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
 1418 | BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
      |                                 ~~~~~~~~~~~~~~^~~~~~
../MODBUS-LIB/Src/Modbus.c: In function 'ModbusQuery':
../MODBUS-LIB/Src/Modbus.c:777:23: warning: passing argument 1 of 'xQueueGenericSend' makes pointer from integer without a cast [-Wint-conversion]
  777 |  xQueueSendToBack(modH->QueueTelegramHandle, &telegram, 0);
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:395:86: note: in definition of macro 'xQueueSendToBack'
  395 | #define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK )
      |                                                                                      ^~~~~~
../MODBUS-LIB/Src/UARTCallback.c: In function 'HAL_UARTEx_RxEventCallback':
../MODBUS-LIB/Src/UARTCallback.c:152:42: warning: passing argument 1 of 'xTaskGenericNotifyFromISR' makes pointer from integer without a cast [-Wint-conversion]
  152 |           xTaskNotifyFromISR(mHandlers[i]->myTaskModbusAHandle, 0 , eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1945:119: note: in definition of macro 'xTaskNotifyFromISR'
 1945 | #define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) )
      |                                                                                                                       ^~~~~~~~~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/task.h:1944:52: note: expected 'TaskHandle_t' {aka 'struct tskTaskControlBlock *'} but argument is of type 'int'
 1944 | BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
      |                                       ~~~~~~~~~~~~~^~~~~~~~~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:650:45: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
  650 | BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
      |                               ~~~~~~~~~~~~~~^~~~~~
../MODBUS-LIB/Src/Modbus.c: In function 'ModbusQueryInject':
../MODBUS-LIB/Src/Modbus.c:789:18: warning: passing argument 1 of 'xQueueGenericReset' makes pointer from integer without a cast [-Wint-conversion]
  789 |  xQueueReset(modH->QueueTelegramHandle);
      |              ~~~~^~~~~~~~~~~~~~~~~~~~~
      |                  |
      |                  int
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:1433:51: note: in definition of macro 'xQueueReset'
 1433 | #define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )
      |                                                   ^~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:1644:46: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
 1644 | BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
      |                                ~~~~~~~~~~~~~~^~~~~~
../MODBUS-LIB/Src/Modbus.c:791:24: warning: passing argument 1 of 'xQueueGenericSend' makes pointer from integer without a cast [-Wint-conversion]
  791 |  xQueueSendToFront(modH->QueueTelegramHandle, &telegram, 0);
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:313:87: note: in definition of macro 'xQueueSendToFront'
  313 | #define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT )
      |                                                                                       ^~~~~~
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:650:45: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
  650 | BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
      |                               ~~~~~~~~~~~~~~^~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:60,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../MODBUS-LIB/Src/Modbus.c: In function 'SendQuery':
../MODBUS-LIB/Src/Modbus.c:841:21: warning: passing argument 1 of 'xQueueSemaphoreTake' makes pointer from integer without a cast [-Wint-conversion]
  841 |  xSemaphoreTake(modH->ModBusSphrHandle , portMAX_DELAY); //before processing the message get the semaphore
../Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h:289:74: note: in definition of macro 'xSemaphoreTake'
  289 | #define xSemaphoreTake( xSemaphore, xBlockTime )  xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
      |                                                                          ^~~~~~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:59,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:1418:47: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
 1418 | BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
      |                                 ~~~~~~~~~~~~~~^~~~~~
../MODBUS-LIB/Src/Modbus.c: In function 'StartTaskModbusMaster':
../MODBUS-LIB/Src/Modbus.c:1057:22: warning: passing argument 1 of 'xQueueReceive' makes pointer from integer without a cast [-Wint-conversion]
 1057 |    xQueueReceive(modH->QueueTelegramHandle, &telegram, portMAX_DELAY);
      |                  ~~~~^~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      int
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:59,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:868:41: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
  868 | BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
      |                           ~~~~~~~~~~~~~~^~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:60,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../MODBUS-LIB/Src/Modbus.c:1150:23: warning: passing argument 1 of 'xQueueSemaphoreTake' makes pointer from integer without a cast [-Wint-conversion]
 1150 |    xSemaphoreTake(modH->ModBusSphrHandle , portMAX_DELAY); //before processing the message get the semaphore
../Middlewares/Third_Party/FreeRTOS/Source/include/semphr.h:289:74: note: in definition of macro 'xSemaphoreTake'
  289 | #define xSemaphoreTake( xSemaphore, xBlockTime )  xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
      |                                                                          ^~~~~~~~~~
In file included from ../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h:59,
                 from ../MODBUS-LIB/Src/Modbus.c:10:
../Middlewares/Third_Party/FreeRTOS/Source/include/queue.h:1418:47: note: expected 'QueueHandle_t' {aka 'struct QueueDefinition *'} but argument is of type 'int'
 1418 | BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
      |                                 ~~~~~~~~~~~~~~^~~~~~
make: *** [MODBUS-LIB/Src/subdir.mk:22: MODBUS-LIB/Src/UARTCallback.o] Error 1
make: *** Waiting for unfinished jobs....
make: *** [MODBUS-LIB/Src/subdir.mk:22: MODBUS-LIB/Src/Modbus.o] Error 1
"make -j16 all" terminated with exit code 2. Build might be incomplete.

For example, in Modbus.c, multiple types are not recognised:
image

Communication lost with Honeywell Comfortpoint DDC panel

First of all I would like to thanks for your great work. Really appreciate. I have tried some experiment with Honeywell PLC (Comfortpoint DDC panel) as well as with Modscan32 Application.

When I connected Slave ID 1 And Slave ID2 in Daisy chain topology it works great with Modscan32. Everything run flawlessly.

But When same thing I have tried with Honeywell PLC, there is communication loss after 2 hrs and again reconnected in 30mins. Main problem is only one device os responding at a time.

Do you have any idea about this problem.

Slave Does not allow for memory space larger then 256

First off Great Library so far.

I would like to map more the 256 bytes to a modbus slave. I know this is the limit of any one transaction but still would like to have the option to map more.
From what i can see the limit is first and for most the fact that u8regsize member of the modbusHandler_t is a uint8_t.
I have sort got it working by just increasing this to a 16_t as well as all other locations where the address is cast to a 8_t. My question is am i missing another obvious method of allowing for a larger address space. as i would obviously preferer to try avoid deviating form current master.

Cheers

Problems with higher Baudrates on STM32F303K8

Hello alejoseb,

thank you for your great work of converting the modbuslibrary to STM32 HAL and FreeRTOS. I managed to copy your example for the F429 Modbus Slave to my STM32F303K8 Microcontroller. I'm using the serial port on uart2, which is routed through the usb on my development board to communicate with the F303 via QModbus on my PC. After changing the Priority of the global UART Interrupt to 5, everything seems to work fine at a Baudrate of 38400 kbit/s. But if I increase the baudrate to 115,2 kbit/s or even 57,6 kbit/s it stops working. Any ideas why this could be the case?
My Investigations of the problem lead to the ModbusSlaveTask(), where the RxBuffer is recieved (with getRxBuffer()-method), it gives me only 6 Bytes@57,6kbit/s and 2 Bytes@115,2kbit/s as return value and as these are invalid Framesizes the Message is not parsed further and a BAD_SIZE-Error is thrown.
If I understand your code correctly - pls correct me if i'm wrong - you are receiving every Byte from the UART through a seperate Interrupt and then sending it off to the ModbusQueue (at modH->QueueModbusHandle). The SlaveTask() is only notified if the xTimerT35-Callback is called, right? Why would it execute if it has not recieved all bytes yet?

I'm running my MCU at 64 MHz, which should be plenty for 115,2 kbit/s in my opinion.

I would be grateful for any tips to get a better understanding of your Modbus stack and my problem itself. If you need more information, feel free to ask, please.

Daniel

Master read queries sometimes sends two read request with no delays between (UART)

Hi,
First, thanks for the lib. It's a wonderful work.
I'm using it with a TouchGFX app on STM32H7, as a master device with UART. I'm polling my device from a modbus task StartTaskPollModbus, by sending 6 requests for reading 100 words with MB_FC_READ_REGISTERS at each request. It works fine for the first 5 requests, my slave is responding and datas are well processed by the lib. My problem is that at the 6th request, my master is sending the read request directly (no delay) after the 5th request on my UART TX, while the slave is still responding from the previous request on my UART RX.
For the 5 firsts read requests from my master, I can see on my scope that the most of the time, the master waits the slave answer to be complete before sending an other read request. But sometimes it sends two read request with no delay even before the 6th request. Though, at the 6 request it never waits for the slave answer of the previous request to be completed. See my code below. Any idea what could cause that ? Thanks!

void StartTaskPollModbus(void *argument)
{
  for(;;)
  {
        for (int i = 0; i < 6; i++)
        {
          modbusRead(100 * i, 100);
        }
	osDelay(300);
  }
}

void modbusRead(uint16_t regAdd, uint16_t regNo)
{
	modbus_t telegram;
	telegram.u8id = 1; // slave address
	telegram.u8fct = MB_FC_READ_REGISTERS; // function code
	telegram.u16RegAdd = regAdd;
	telegram.u16CoilsNo = regNo; // number of elements (coils or registers) to read
	telegram.u16reg = &modbusBuffer[regAdd]; // pointer to a memory array
	ModbusQuery(&ModbusH, telegram);
	ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}

// ModbusConfig.h
#define T35  2//5              // Timer T35 period (in ticks) for end frame detection.
#define MAX_BUFFER  128    // Maximum size for the communication buffer in bytes.
#define TIMEOUT_MODBUS 1000 // Timeout for master query (in ticks)
#define MAX_M_HANDLERS 2    //Maximum number of modbus handlers that can work concurrently
#define MAX_TELEGRAMS 50     //Max number of Telegrams in master queue

TCP Client library usage example

Hello,
I am trying to use your library in a project but I do not really know hoy to use it in a task.

Everything compiles fine, but it will not connect to the MTCP server on my LAN (which works with other devices).

Could you explain how to assign the server IP with xIpAddress?

Do you have an example for the library usage? I cannot see how to use it in a RTOS task.

Thank you!

Coil change according to input

Hi,

I'm new to stm32 programming and in general my knowledge is limited to basic university C courses. My question could be stupid, in that case feel free to close the issue.
I can read and write coils through a master simulator but I would like to set coils ON or OFF based on inputs (switches) on the stm32 board.
Is this possible? I basically would like to make a keyboard.

1 Master and Multiple Slave Error is back?

Hmm is anyone else seeing the problem noted here? #17

This issue seems to have re-appeared on the latest version of this library.

I am seeing one of my Modbus slave devices stop working after a few minutes, and the failure I'm seeing seems to match the previous issue linked above.

I'm using a standard Modbus RTU configuration over RS-485 with the DE pin.

How can I detect and signalize for incoming packets?

This isn't an issue, I just want some clarification and didn't know who to ask for.

Examples show how to set a pin after receiving a determined value on the registers. This isn't exactly what I wanna do.
How could I signalize (using a LED or drawing on a display) everytime a package is received on my device (slave)?

Thank you in advance.

Using Modbus LIB with USB CDC

Hello

Could you possibly explain how to, or where to read, or add some functional to implement not only uart port but also USB CDC ? Can't understand how to do it proper way.

Thank you

Generated failed in touchgfx

Hi @alejoseb . I use STM32F4-discovery and first step I use touchgfx to generated code but the touchgfx is fail to generated and show that " Generate Code
Generate
Wrote config/gcc/app.mk
Done
Generate Assets
make -f simulator/gcc/Makefile assets -j8
process_begin: CreateProcess(NULL, ../Middlewares/ST/touchgfx/framework/tools/imageconvert/build/win/imageconvert.out -r assets/images -w generated/images, ...) failed.
make (e=2): The system cannot find the file specified.

    make[1]: *** [images] Error 2
    generated/simulator/gcc/Makefile:215: recipe for target 'images' failed
    simulator/gcc/Makefile:32: recipe for target 'assets' failed
    make: *** [assets] Error 2
    Failed
Failed "

How to fix it ? Please give me some advice I am a newcomer to stm32 (sorry about my english)

problems with master mode uart hw

Using master rtu mode with uart I have problem because the rx buffer contains both tx bytes and rx bytes. The modH->u8BufferSize is the sum of the two parts and so the reception doesn't work.

with old version (without ring buffer) everything work but I need a different HAL_UART_TxCpltCallback

void HAL_UART_TxCpltCallback(UART_HandleTypeDef huart)
{
/
Modbus RTU callback BEGIN */
//BaseType_t xHigherPriorityTaskWoken = pdFALSE;
int i;
for (i = 0; i < numberHandlers; i++) {
if (mHandlers[i]->port == huart) {
//xTaskNotifyFromISR(mHandlers[i]->myTaskModbusAHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
break;
}
}
//portYIELD_FROM_ISR( xHigherPriorityTaskWoken )

the new version with RingBuffer is not working, (the same with original HAL_UART_TxCpltCallback or the modified one posted here)

I'm using STM32F767 microcontroller. Baudrate is 57600 8n1.

Can't get any interrupt when receive frame

Hi,

i've this strange behaviour and I can't figure it out why.

I've already used this library before and so I can't understand why I've so many trouble now, but basically I can't receive any interrupt when receiving a Modbus frame from the master.

I've configured my device as a slave with the following parameters:

/* Modbus Slave initialization */
modH->uModbusType = MB_SLAVE;
modH->port =  &huart3; // This is the UART port connected to STLINK in the discovery F429
modH->u8id = 1; //Master ID
modH->u16timeOut = 1000;
modH->EN_Port = UART3_TX_EN_GPIO_Port; // RS485 Enable
modH->EN_Pin = UART3_TX_EN_Pin; // RS485 Enable
modH->u16regs = ModbusDATARX;
modH->u16regsize= sizeof(ModbusDATARX)/sizeof(ModbusDATARX[0]);
modH->xTypeHW = USART_HW;

My GPIOs are set in this way:

GPIO_InitStruct.Pin = UART3_TX_EN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = UART3_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART3;
HAL_GPIO_Init(UART3_RX_GPIO_Port, &GPIO_InitStruct);

GPIO_InitStruct.Pin = UART3_TX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART3;
HAL_GPIO_Init(UART3_TX_GPIO_Port, &GPIO_InitStruct);

And the interrupt is this way:

/* UART3 interrupt Init */
HAL_NVIC_SetPriority(UART3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(UART3_IRQn);

And the uart is set in this way:

static void MX_UART3_Init(void)
{

  /* USER CODE BEGIN UART3_Init 0 */

  /* USER CODE END UART3_Init 0 */

  /* USER CODE BEGIN UART3_Init 1 */

  /* USER CODE END UART3_Init 1 */
  huart3.Instance = UART3;
  huart3.Init.BaudRate = 38400;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN UART3_Init 2 */

  /* USER CODE END UART3_Init 2 */

}

I'm putting a brekpoint here when I send messages though QModBus tool but it's never reached

void UART3_IRQHandler(void)
{
  /* USER CODE BEGIN UART3_IRQn 0 */
  
  /* USER CODE END UART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN UART3_IRQn 1 */
  
  /* USER CODE END UART3_IRQn 1 */
}

What I'm missing?

Thanks in advance for any help

Numbering of registers

Am I correct in thinking that, assuming the STM32 is a slave and implementing 5 coils, 5 holding registers, 5 input registers and 5 discretes, the numbering for each has to be unique? i.e. Coils might be 0 to 4, holding registers 5 to 9 etc. You cannot have coil 0 AND holding register 0 at they would use the same value.
Also, if you decide the holding registers are 5 to 9 there is nothing to stop the master from requesting, or writing to holding register 0 thereby actually reading or writing a coil even though a holding register action was specified.

Rearrange UART interrupt callbacks

Hi.
I mean is it possible to unify the two callback functions, put them in one file (RxCpltCallback is in Modbus.c)? This is not a vital problem, i have already make it for myself, because i use it with another library where i made it that way and i think it`s easier to exclude from build these source files and create a project related source file where we merge the two callback functions or do it in the main.c, and that way we don't have to touch the original source files. (UARTCallback.c). This is just my opinion, if for some reason is not right for You, then please let ignore it.
Thanks

Modbus TCP Slave

Hi @alejoseb , a question about modbusTCP slave mode, after receiveing a packet and processing it the connection is closed it's right?
In this way the master should open the connection before each connection?
But this mode is valid for a standard master?

Do you have a tools for PC useful for testing ?

Thank you

Can't Unzip archive

Help me please. Downloaded archive need password to unzip. Do you know it?

Fabulous Modbus Library

First of all, thank you for providing this service to us. I'm going to ask you a few questions about your library.

1-)t35 is set to =5, this is why 5 . Do we need to change at different baud rates?
2-) I have never seen other errors occur in the system except for the CRC error. For example, which error flag should be activated when the communication is interrupted, how can we try this?
3-) Does the system support 2 usart lines to work as slaves at the same time as a multiusart or will there be any confusion?
4-) Finally, how can we use the system outside of FreRtos.

Thank you in advance for your answers. If you do not want to answer here, we can discuss these issues via whatsapp or mail.
Thank you again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.