kopia lustrzana https://github.com/SP8EBC/ParaTNC
timeouts added to modbus rtu serial i/o handling
rodzic
3a55ebadcb
commit
bad16f5a44
|
@ -123,7 +123,7 @@ void srl_keep_timeout(srl_context_t *ctx) {
|
|||
;
|
||||
}
|
||||
|
||||
if (ctx->srl_rx_state != SRL_RX_NOT_CONFIG && ctx->srl_rx_timeout_waiting_enable == 1) {
|
||||
if ((ctx->srl_rx_state == SRL_WAITING_TO_RX || ctx->srl_rx_state == SRL_RXING ) && ctx->srl_rx_timeout_waiting_enable == 1) {
|
||||
if (master_time - ctx->srl_rx_waiting_start_time > ctx->srl_rx_timeout_trigger_value_in_msec) {
|
||||
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
|
||||
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
|
||||
|
@ -336,6 +336,9 @@ uint8_t srl_receive_data(srl_context_t *ctx, int num, char start, char stop, cha
|
|||
return SRL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function start the transfer with
|
||||
*/
|
||||
uint8_t srl_receive_data_with_instant_timeout(srl_context_t *ctx, int num, char start, char stop, char echo, char len_addr, char len_modifier) {
|
||||
if (ctx->srl_rx_state == SRL_RXING)
|
||||
return SRL_BUSY;
|
||||
|
@ -480,6 +483,9 @@ void srl_irq_handler(srl_context_t *ctx) {
|
|||
// raise a flag to signalize that timeout shall be calulated from now.
|
||||
ctx->srl_rx_timeout_calc_started = 1;
|
||||
|
||||
// disable the waiting timeout
|
||||
ctx->srl_rx_timeout_waiting_enable = 0;
|
||||
|
||||
// if there is any data remaining to receive
|
||||
if (ctx->srl_rx_bytes_counter < ctx->srl_rx_bytes_req) {
|
||||
|
||||
|
@ -680,6 +686,11 @@ void srl_switch_tx_delay(srl_context_t *ctx, uint8_t disable_enable) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function controls the timeout which is calculated for data reception (when the
|
||||
* state is set to SRL_RXING). The calculation starts after the first byte appears in
|
||||
* data register and protect against stalling in the middle of data transfer
|
||||
*/
|
||||
void srl_switch_timeout(srl_context_t *ctx, uint8_t disable_enable, uint32_t value) {
|
||||
if (disable_enable == 1)
|
||||
ctx->srl_rx_timeout_enable = 1;
|
||||
|
@ -697,6 +708,13 @@ void srl_switch_timeout(srl_context_t *ctx, uint8_t disable_enable, uint32_t val
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function enables the timeout which is calculated for the waiting state for
|
||||
* the data reception to begin (the first byte on serial port). It must be called for
|
||||
* each RX transaction it is required as this timeout is cleared/disabled after the first
|
||||
* byte received by the serial port (when the state changes from SRL_WAITING_TO_RX to
|
||||
* SRL_RXING)
|
||||
*/
|
||||
void srl_switch_timeout_for_waiting(srl_context_t *ctx, uint8_t disable_enable) {
|
||||
if (disable_enable == 1)
|
||||
ctx->srl_rx_timeout_waiting_enable = 1;
|
||||
|
|
|
@ -16,7 +16,14 @@ int32_t rtu_parser_03_04_registers(uint8_t* input, uint16_t input_ln, rtu_regist
|
|||
uint16_t data = 0;
|
||||
|
||||
// iterator through input table and registers table
|
||||
int i = 0, j = 4;
|
||||
int i = 0, j = 3;
|
||||
|
||||
// rewind the input buffer if the first byte is not valid modbus rtu slave address
|
||||
if (*input < 1 || *input > 0xF7) {
|
||||
// don't loop here and assume that the modbus response is shifted only
|
||||
// by one byte
|
||||
input++;
|
||||
}
|
||||
|
||||
// 7 bytes is the shortest meaningful Modbus RTU frame
|
||||
// with a value of single register
|
||||
|
@ -31,12 +38,12 @@ int32_t rtu_parser_03_04_registers(uint8_t* input, uint16_t input_ln, rtu_regist
|
|||
output->slave_address = data;
|
||||
|
||||
// fetch function code
|
||||
data = *(input + 2);
|
||||
data = *(input + 1);
|
||||
|
||||
// check if the function code is correct or not
|
||||
if (data == 0x03 || data == 0x04) {
|
||||
// fetch the function result lenght in bytes
|
||||
data = *(input + 3);
|
||||
data = *(input + 2);
|
||||
|
||||
// store amount of registers in this response
|
||||
output->number_of_registers = data / 2;
|
||||
|
|
|
@ -165,6 +165,13 @@ int32_t rtu_serial_pool(rtu_pool_queue_t* queue, srl_context_t* serial_context)
|
|||
switch (rtu_pool) {
|
||||
case RTU_POOL_IDLE: {
|
||||
|
||||
// Enabling the timeout for Modbus-RTU.
|
||||
// This timeout starts after first received byte and triggers if
|
||||
// the slave will hang up and stop the transmission before the end of the frame
|
||||
// It doesn't need to be called each time but this is the only function which takes
|
||||
// the pointer to serial context
|
||||
srl_switch_timeout(serial_context, 1, 0);
|
||||
|
||||
// check the function it at current queue position
|
||||
if (queue->function_id[queue->it] == 0x03) {
|
||||
// read holding registers
|
||||
|
@ -240,6 +247,10 @@ int32_t rtu_serial_pool(rtu_pool_queue_t* queue, srl_context_t* serial_context)
|
|||
srl_receive_data_with_callback(serial_context, rtu_serial_callback);
|
||||
//srl_receive_data(serial_context, 8, 0, 0, 0, 0, 0);
|
||||
|
||||
// enable the timeout in case the RTU slave won't respond
|
||||
// at all or there is no slaves connected to RS485 bus
|
||||
srl_switch_timeout_for_waiting(serial_context, 1);
|
||||
|
||||
// switch the state
|
||||
rtu_pool = RTU_POOL_RECEIVING;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue