2025-12-17 16:57:23 +08:00
|
|
|
#include "modbus.h"
|
2025-12-19 17:02:27 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
#define MAX_NODES 20
|
|
|
|
|
#define MAX_callback_NODES 10
|
|
|
|
|
#define TABLE_SIZE (sizeof(table)/ sizeof(table[0]))
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
static modbus_task node_pool[MAX_NODES];
|
|
|
|
|
static uint8_t node_used[MAX_NODES] = {0};
|
|
|
|
|
static modbus_task* free_list =NULL;
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
static CallbackNode callback_pool[MAX_callback_NODES];
|
|
|
|
|
static CallbackNode* callback_list_head = NULL;
|
|
|
|
|
static CallbackNode* callback_free_list = NULL;
|
2025-12-17 16:57:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
void modbus_init(void)
|
|
|
|
|
{
|
2025-12-19 17:02:27 +08:00
|
|
|
for(int i = MAX_NODES-1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
node_pool[i].next = free_list;
|
|
|
|
|
free_list = &node_pool[i];
|
|
|
|
|
node_used[i] = 0;
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
modbus_task* allocate_task(void)
|
|
|
|
|
{
|
|
|
|
|
if(free_list == NULL)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
modbus_task* node = free_list;
|
|
|
|
|
free_list = free_list->next;
|
|
|
|
|
uint8_t index = node - node_pool;
|
|
|
|
|
node_used[index] = 1;
|
|
|
|
|
|
|
|
|
|
memset(node, 0, sizeof(modbus_task));
|
|
|
|
|
node->next = NULL;
|
|
|
|
|
|
|
|
|
|
return node;
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void free_task(modbus_task* node)
|
|
|
|
|
{
|
|
|
|
|
if(node == NULL)return;
|
|
|
|
|
|
|
|
|
|
uint8_t index = node - node_pool;
|
|
|
|
|
if(index < 0 || index >= MAX_NODES || node_used[index] == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node->next = free_list;
|
|
|
|
|
free_list = node;
|
|
|
|
|
node_used[index] = 0;
|
|
|
|
|
|
2025-12-17 16:57:23 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void check_align_table(uint8_t slave, uint16_t addr, uint8_t* data)
|
|
|
|
|
{
|
|
|
|
|
for(int i = 0; i < TABLE_SIZE; i++ )
|
|
|
|
|
{
|
|
|
|
|
if((table[i].slave == slave)&&(table[i].reg_addr) == addr)
|
|
|
|
|
{
|
|
|
|
|
if(addr == 1000)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if(addr == 2000)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void callback_pool_init(void)
|
|
|
|
|
{
|
|
|
|
|
for(int i = MAX_callback_NODES-1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
callback_pool[i].next = callback_free_list;
|
|
|
|
|
callback_free_list = &callback_pool[i];
|
|
|
|
|
}
|
|
|
|
|
callback_list_head = NULL;
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
CallbackNode* allocate_callback_node(void)
|
|
|
|
|
{
|
|
|
|
|
if(callback_free_list == NULL) return NULL;
|
|
|
|
|
CallbackNode* node = callback_free_list;
|
|
|
|
|
callback_free_list = callback_free_list->next;
|
|
|
|
|
|
|
|
|
|
memset(node, 0, sizeof(CallbackNode));
|
|
|
|
|
node->next = NULL;
|
|
|
|
|
|
|
|
|
|
return node;
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void free_callback_node(CallbackNode* node)
|
|
|
|
|
{
|
|
|
|
|
if(node == NULL)return;
|
|
|
|
|
|
|
|
|
|
uint8_t index = node - callback_pool;
|
|
|
|
|
if(index < 0 || index >= MAX_callback_NODES )
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
node->next = callback_free_list;
|
|
|
|
|
callback_free_list = node;
|
|
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
|
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void reg_callback(uint8_t slave, uint16_t addr, ModbusCallback func)
|
|
|
|
|
{
|
|
|
|
|
if(func == NULL)return;
|
|
|
|
|
CallbackNode* new_node = allocate_callback_node();
|
|
|
|
|
if(new_node == NULL)return;
|
|
|
|
|
|
|
|
|
|
new_node->slave = slave;
|
|
|
|
|
new_node->addr = addr;
|
|
|
|
|
new_node->callback = func;
|
|
|
|
|
new_node->next = NULL;
|
|
|
|
|
|
|
|
|
|
new_node->next = callback_list_head;
|
|
|
|
|
callback_list_head = new_node;
|
|
|
|
|
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
void execute_callback()
|
|
|
|
|
{
|
2025-12-17 16:57:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-12-19 17:02:27 +08:00
|
|
|
}
|
2025-12-17 16:57:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|