You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm porting nanoMODBUS to a microcontroller (CH32V003).
I have the issue that i get a hardfault To diaganose that error i wrote a fake_data function, that simulates a coil read, that gives always the same data. char fakedata[8]={0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x3D, 0xCC};
In the hardfault interrupt, i look where the hardfault happened by using a global variable. It takes several iterations until this happens, it doesn't happen strait away.
The code is based on the arduino slave example, but the error seems to be inside the library.
What do i see?
It crashes inside the routine (_hardfault_was_inside_readwrite==1) and it has always 2 chars left in the buffer. (mb_recievebuffer_index=2) So i gues it's before the checksum is there.
/*
This example application sets up an RTU server and handles modbus requests
This server supports the following function codes:
FC 01 (0x01) Read Coils
FC 03 (0x03) Read Holding Registers
FC 15 (0x0F) Write Multiple Coils
FC 16 (0x10) Write Multiple registers
*/
nmbs_t nmbs;
// The data model of this sever will support coils addresses 0 to 100 and registers addresses from 0 to 32
#define COILS_ADDR_MAX 64
#define REGS_ADDR_MAX 32
// Our RTU address
#define RTU_SERVER_ADDRESS 1
// A single nmbs_bitfield variable can keep 2000 coils
nmbs_bitfield server_coils = {0};
uint16_t server_registers[REGS_ADDR_MAX] = {0};
// Read our coils values into coils_out
for (int i = 0; i < quantity; i++) {
bool value = nmbs_bitfield_read(server_coils, address + i);
nmbs_bitfield_write(coils_out, i, value);
}
// Write coils values to our server_coils
for (int i = 0; i < quantity; i++) {
nmbs_bitfield_write(server_coils, address + i, nmbs_bitfield_read(coils, i));
}
Hi, unfortunately I really don't have the time to inspect this... I see that your platform is RISC-V, so there may be a minuscule chance that the problem lies inside some non cross-platform code in the library, but first I would like to be 100% sure that it's not just a bug in your application.
Can you try to test the code on linux or on arduino, maybe with a debugger?
I'm porting nanoMODBUS to a microcontroller (CH32V003).
I have the issue that i get a hardfault To diaganose that error i wrote a fake_data function, that simulates a coil read, that gives always the same data.
char fakedata[8]={0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x3D, 0xCC};
In the hardfault interrupt, i look where the hardfault happened by using a global variable. It takes several iterations until this happens, it doesn't happen strait away.
The code is based on the arduino slave example, but the error seems to be inside the library.
What do i see?
It crashes inside the routine (_hardfault_was_inside_readwrite==1) and it has always 2 chars left in the buffer. (mb_recievebuffer_index=2) So i gues it's before the checksum is there.
@debevv can you please help to investigate?
`
#include "unified.h"
/*
This example application sets up an RTU server and handles modbus requests
This server supports the following function codes:
FC 01 (0x01) Read Coils
FC 03 (0x03) Read Holding Registers
FC 15 (0x0F) Write Multiple Coils
FC 16 (0x10) Write Multiple registers
*/
nmbs_t nmbs;
// The data model of this sever will support coils addresses 0 to 100 and registers addresses from 0 to 32
#define COILS_ADDR_MAX 64
#define REGS_ADDR_MAX 32
// Our RTU address
#define RTU_SERVER_ADDRESS 1
// A single nmbs_bitfield variable can keep 2000 coils
nmbs_bitfield server_coils = {0};
uint16_t server_registers[REGS_ADDR_MAX] = {0};
#define MB_RECIEVEBUFFER_SIZE 100
uint8_t mb_recievebuffer[MB_RECIEVEBUFFER_SIZE];
uint32_t mb_recievebuffer_index=0;
void delay1msec(void){
uint32_t countdown=8000;
while(countdown--) asm("");
}
uint8_t _hardfault_was_inside_readwrite=0;
void fake_data(uint8_t* buf,uint16_t count){
_hardfault_was_inside_readwrite=5;
if((mb_recievebuffer_index+count)<=MB_RECIEVEBUFFER_SIZE){
memcpy(&mb_recievebuffer[mb_recievebuffer_index],buf,count);
mb_recievebuffer_index+=count;
}
_hardfault_was_inside_readwrite=1;
}
int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
_hardfault_was_inside_readwrite=2;
while(byte_timeout_ms--){
// uint32_t recbytes=mcu_tracer_usart_recieved_bytes();
// if(recbytes>0){
// //copies the number of recieved bytes
// uint32_t datalen;
// uint8_t *data;
// data=mcu_tracer_rx_pingpong_buf(&datalen);
// if((mb_recievebuffer_index+datalen)>=MB_RECIEVEBUFFER_SIZE){
// datalen=MB_RECIEVEBUFFER_SIZE-mb_recievebuffer_index;
// }
// memcpy(&mb_recievebuffer[mb_recievebuffer_index],data,datalen);
// mb_recievebuffer_index+=datalen;
// }
if(count<=mb_recievebuffer_index){
_hardfault_was_inside_readwrite=3;
memcpy(buf,&mb_recievebuffer[0],count);
mb_recievebuffer_index=mb_recievebuffer_index-count;
if(mb_recievebuffer_index>0){
_hardfault_was_inside_readwrite=4;
memmove(&mb_recievebuffer[0],&mb_recievebuffer[count],mb_recievebuffer_index);
}
_hardfault_was_inside_readwrite=1;
return count;
}
// delay1msec();
// byte_timeout_ms--;
// if(byte_timeout_ms<1){
// memcpy(buf,&mb_recievebuffer[0],mb_recievebuffer_index);
// mb_recievebuffer_index=0;
// return mb_recievebuffer_index;
// }
_hardfault_was_inside_readwrite=1;
return -1;
}
}
int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
return count;
while(mcu_tracer_usart_send_busy()){
delay1msec();
byte_timeout_ms--;
if(byte_timeout_ms<1) break;
}
MBHW_dir_set_write();
//delay1msec();
mcu_tracer_usart_send(buf,count);
mcu_tracer_usart_txdone_wait();
//even when the transmission is done, one last byte is processing, therefore this delay!
uint32_t countdown=2000;
while(countdown--) asm("");
MBHW_dir_set_read();
return count;
}
void onError() {
// Set the led ON on error
}
nmbs_error handle_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void *arg) {
return NMBS_ERROR_NONE; //deactive funciton to avoid errors
if (address + quantity > COILS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Read our coils values into coils_out
for (int i = 0; i < quantity; i++) {
bool value = nmbs_bitfield_read(server_coils, address + i);
nmbs_bitfield_write(coils_out, i, value);
}
return NMBS_ERROR_NONE;
}
nmbs_error handle_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id, void *arg) {
if (address + quantity > COILS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Write coils values to our server_coils
for (int i = 0; i < quantity; i++) {
nmbs_bitfield_write(server_coils, address + i, nmbs_bitfield_read(coils, i));
}
return NMBS_ERROR_NONE;
}
nmbs_error handler_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id, void *arg) {
if (address + quantity > REGS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Read our registers values into registers_out
for (int i = 0; i < quantity; i++)
registers_out[i] = server_registers[address + i];
return NMBS_ERROR_NONE;
}
nmbs_error handle_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers, uint8_t unit_id, void *arg) {
if (address + quantity > REGS_ADDR_MAX + 1)
return NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS;
// Write registers values to our server_registers
for (int i = 0; i < quantity; i++)
server_registers[address + i] = registers[i];
return NMBS_ERROR_NONE;
}
void Nanomb_init(void) {
nmbs_platform_conf platform_conf;
platform_conf.transport = NMBS_TRANSPORT_RTU;
platform_conf.read = read_serial;
platform_conf.write = write_serial;
platform_conf.arg = NULL;
nmbs_callbacks callbacks = {0};
callbacks.read_coils = handle_read_coils;
callbacks.write_multiple_coils = handle_write_multiple_coils;
callbacks.read_holding_registers = handler_read_holding_registers;
callbacks.write_multiple_registers = handle_write_multiple_registers;
// Create the modbus server
nmbs_error err = nmbs_server_create(&nmbs, RTU_SERVER_ADDRESS, &platform_conf, &callbacks);
if (err != NMBS_ERROR_NONE) {
onError();
}
nmbs_set_read_timeout(&nmbs, 1000);
nmbs_set_byte_timeout(&nmbs, 100);
}
void nanomb_task(void){
char fakedata[8]={0x01, 0x01, 0x00, 0x00, 0x00, 0x08, 0x3D, 0xCC};
fake_data(&fakedata[0],8);
nmbs_server_poll(&nmbs);
}
`
The text was updated successfully, but these errors were encountered: