Added shell functions
This commit is contained in:
parent
9d017f9f8d
commit
852c5c72be
|
|
@ -8,7 +8,9 @@
|
||||||
"canbus.h": "c",
|
"canbus.h": "c",
|
||||||
"kernel.h": "c",
|
"kernel.h": "c",
|
||||||
"settings.h": "c",
|
"settings.h": "c",
|
||||||
"can.h": "c"
|
"can.h": "c",
|
||||||
|
"stdlib.h": "c",
|
||||||
|
"reboot.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.default.compileCommands": [
|
"C_Cpp.default.compileCommands": [
|
||||||
"build/compile_commands.json",
|
"build/compile_commands.json",
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
compatible = "iten,valve-node", "st,stm32f103rb";
|
compatible = "iten,valve-node", "st,stm32f103rb";
|
||||||
|
|
||||||
can_loopback0: can_loopback0 {
|
can_loopback0: can_loopback0 {
|
||||||
status = "okay";
|
status = "disabled";
|
||||||
compatible = "zephyr,can-loopback";
|
compatible = "zephyr,can-loopback";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
zephyr,shell-uart = &usart1;
|
zephyr,shell-uart = &usart1;
|
||||||
zephyr,sram = &sram0;
|
zephyr,sram = &sram0;
|
||||||
zephyr,flash = &flash0;
|
zephyr,flash = &flash0;
|
||||||
//zephyr,canbus = &can1;
|
zephyr,canbus = &can1;
|
||||||
zephyr,canbus = &can_loopback0;
|
//zephyr,canbus = &can_loopback0;
|
||||||
};
|
};
|
||||||
|
|
||||||
leds: leds {
|
leds: leds {
|
||||||
|
|
@ -79,6 +79,10 @@
|
||||||
gpios = <&gpiob 13 0>;
|
gpios = <&gpiob 13 0>;
|
||||||
label = "Motor Open";
|
label = "Motor Open";
|
||||||
};
|
};
|
||||||
|
fake: fake {
|
||||||
|
gpios = <&gpiob 11 GPIO_PULL_UP>;
|
||||||
|
label = "CAN RX pullup";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ CONFIG_MODBUS_ROLE_CLIENT=y
|
||||||
CONFIG_CAN=y
|
CONFIG_CAN=y
|
||||||
CONFIG_CAN_INIT_PRIORITY=80
|
CONFIG_CAN_INIT_PRIORITY=80
|
||||||
#CONFIG_CAN_MAX_FILTER=5
|
#CONFIG_CAN_MAX_FILTER=5
|
||||||
|
CONFIG_CAN_ACCEPT_RTR=y
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
CONFIG_FLASH=y
|
CONFIG_FLASH=y
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/sys/byteorder.h>
|
#include <zephyr/sys/byteorder.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "modbus.h"
|
||||||
|
|
||||||
int canbus_node_id = 1; // Default node ID for CAN bus
|
int canbus_node_id = 1; // Default node ID for CAN bus
|
||||||
|
|
||||||
|
|
@ -11,7 +12,7 @@ const struct device *const can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus));
|
||||||
struct k_thread rx_thread_data;
|
struct k_thread rx_thread_data;
|
||||||
|
|
||||||
K_THREAD_STACK_DEFINE(rx_thread_stack, CANBUS_RX_THREAD_STACK_SIZE);
|
K_THREAD_STACK_DEFINE(rx_thread_stack, CANBUS_RX_THREAD_STACK_SIZE);
|
||||||
CAN_MSGQ_DEFINE(commands_msq, 2);
|
CAN_MSGQ_DEFINE(commands_msq, CANBUS_RX_MSGQ_SIZE);
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(canbus, CONFIG_LOG_CAN_LEVEL);
|
LOG_MODULE_REGISTER(canbus, CONFIG_LOG_CAN_LEVEL);
|
||||||
|
|
||||||
|
|
@ -20,14 +21,16 @@ static void rx_thread(void *arg1, void *arg2, void *arg3)
|
||||||
ARG_UNUSED(arg1);
|
ARG_UNUSED(arg1);
|
||||||
ARG_UNUSED(arg2);
|
ARG_UNUSED(arg2);
|
||||||
ARG_UNUSED(arg3);
|
ARG_UNUSED(arg3);
|
||||||
|
|
||||||
const struct can_filter filter = {
|
const struct can_filter filter = {
|
||||||
.flags = CAN_FILTER_IDE,
|
.flags = 0, // No special flags,
|
||||||
.id = (canbus_node_id << 8) | 0x00, // Standard ID with node ID in the first byte
|
.id = (canbus_node_id << 8) | 0x00, // Standard ID with node ID in the first byte
|
||||||
.mask = CAN_STD_ID_MASK & 0xFFFFFF00U // Mask for standard ID, ignoring the last byte
|
.mask = CAN_STD_ID_MASK & 0xFFFFFF00U // Mask for standard ID, ignoring the last byte
|
||||||
};
|
};
|
||||||
|
|
||||||
struct can_frame frame;
|
struct can_frame frame;
|
||||||
int filter_id;
|
int filter_id;
|
||||||
|
extern struct k_msgq modbus_msgq;
|
||||||
|
|
||||||
filter_id = can_add_rx_filter_msgq(can_dev, &commands_msq, &filter);
|
filter_id = can_add_rx_filter_msgq(can_dev, &commands_msq, &filter);
|
||||||
LOG_DBG("RX thread started. Filter ID: %d, flags: 0x%02x, id: 0x%08x, mask: 0x%08x", filter_id, filter.flags, filter.id, filter.mask);
|
LOG_DBG("RX thread started. Filter ID: %d, flags: 0x%02x, id: 0x%08x, mask: 0x%08x", filter_id, filter.flags, filter.id, filter.mask);
|
||||||
|
|
@ -37,10 +40,6 @@ static void rx_thread(void *arg1, void *arg2, void *arg3)
|
||||||
k_msgq_get(&commands_msq, &frame, K_FOREVER);
|
k_msgq_get(&commands_msq, &frame, K_FOREVER);
|
||||||
LOG_DBG("Received CAN frame: ID=0x%08x, DLC=%u, Flags=0x%02x",
|
LOG_DBG("Received CAN frame: ID=0x%08x, DLC=%u, Flags=0x%02x",
|
||||||
frame.id, frame.dlc, frame.flags);
|
frame.id, frame.dlc, frame.flags);
|
||||||
if (IS_ENABLED(CONFIG_CAN_ACCEPT_RTR) && (frame.flags & CAN_FRAME_RTR) != 0U)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t target_node = (frame.id >> 8) & 0xFF; // Extract the target node from the ID
|
uint8_t target_node = (frame.id >> 8) & 0xFF; // Extract the target node from the ID
|
||||||
if (target_node != canbus_node_id)
|
if (target_node != canbus_node_id)
|
||||||
|
|
@ -50,9 +49,49 @@ static void rx_thread(void *arg1, void *arg2, void *arg3)
|
||||||
}
|
}
|
||||||
uint8_t target_register = frame.id & 0xFF; // Extract the register address from the ID
|
uint8_t target_register = frame.id & 0xFF; // Extract the register address from the ID
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_CAN_ACCEPT_RTR) && (frame.flags & CAN_FRAME_RTR) != 0U)
|
||||||
|
{
|
||||||
|
LOG_DBG("Received RTR frame for register address: 0x%02x", target_register);
|
||||||
|
switch (target_register)
|
||||||
|
{
|
||||||
|
case CANBUS_REGISTER_WATER_LEVEL_MM:
|
||||||
|
case CANBUS_REGISTER_WATER_MINIMUM:
|
||||||
|
case CANBUS_REGISTER_WATER_MAXIMUM:
|
||||||
|
LOG_DBG("Handling water sensor request for node %d", target_node);
|
||||||
|
modbus_register_t reg_max;
|
||||||
|
reg_max.reg = target_register;
|
||||||
|
reg_max.command = CANBUS_REGISTER_COMMAND_GET; // Set command to GET
|
||||||
|
k_msgq_put(&modbus_msgq, ®_max, K_NO_WAIT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_WRN("Received RTR frame for unknown register address: 0x%02x", target_register);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// Log the received frame details
|
// Log the received frame details
|
||||||
LOG_DBG("Received CAN frame: ID=0x%08x, DLC=%u, Flags=0x%02x, Target Node=%d, Register Address=%d",
|
LOG_DBG("Received CAN frame: ID=0x%08x, DLC=%u, Flags=0x%02x, Target Node=%d, Register Address=0x%02x",
|
||||||
frame.id, frame.dlc, frame.flags, target_node, target_register);
|
frame.id, frame.dlc, frame.flags, target_node, target_register);
|
||||||
|
switch (target_register)
|
||||||
|
{
|
||||||
|
case CANBUS_REGISTER_WATER_MINIMUM:
|
||||||
|
case CANBUS_REGISTER_WATER_MAXIMUM:
|
||||||
|
LOG_DBG("Handling water sensor data for node %d", target_node);
|
||||||
|
modbus_register_t reg;
|
||||||
|
reg.reg = target_register;
|
||||||
|
reg.command = CANBUS_REGISTER_COMMAND_SET; // Set command to SET
|
||||||
|
if (frame.dlc >= sizeof(reg.value)) // Ensure enough data length for value
|
||||||
|
{
|
||||||
|
reg.value = sys_get_be16(frame.data); // Convert received data to big-endian format
|
||||||
|
LOG_DBG("Received value: %d, 0x%04x", reg.value, reg.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERR("Received frame with insufficient data length: %u", frame.dlc);
|
||||||
|
continue; // Skip processing if data length is invalid
|
||||||
|
}
|
||||||
|
k_msgq_put(&modbus_msgq, ®, K_NO_WAIT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
LOG_HEXDUMP_DBG(frame.data, sizeof(frame.data) * sizeof(frame.data[0]), "Frame data:");
|
LOG_HEXDUMP_DBG(frame.data, sizeof(frame.data) * sizeof(frame.data[0]), "Frame data:");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,11 +151,12 @@ int canbus_init(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
rc = can_start(can_dev);
|
rc = can_start(can_dev);
|
||||||
if (rc != 0) {
|
if (rc != 0)
|
||||||
printf("Error starting CAN controller [%d]", rc);
|
{
|
||||||
return 0;
|
printf("Error starting CAN controller [%d]", rc);
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
LOG_DBG("CAN device %s is ready", can_dev->name);
|
LOG_DBG("CAN device %s is ready", can_dev->name);
|
||||||
|
|
||||||
LOG_DBG("Trying to start rx thread");
|
LOG_DBG("Trying to start rx thread");
|
||||||
|
|
@ -137,7 +177,7 @@ int canbus_init(void)
|
||||||
return 0; // Return 0 on success
|
return 0; // Return 0 on success
|
||||||
}
|
}
|
||||||
|
|
||||||
int canbus_send_message(uint8_t destination_node, uint8_t register_address, uint8_t *data, size_t data_length)
|
int canbus_send_register(uint8_t destination_node, uint8_t register_address, uint8_t *data, size_t data_length)
|
||||||
{
|
{
|
||||||
struct can_frame frame;
|
struct can_frame frame;
|
||||||
if (data_length > sizeof(frame.data))
|
if (data_length > sizeof(frame.data))
|
||||||
|
|
@ -155,7 +195,8 @@ int canbus_send_message(uint8_t destination_node, uint8_t register_address, uint
|
||||||
|
|
||||||
// Send the CAN frame
|
// Send the CAN frame
|
||||||
int rc = can_send(can_dev, &frame, K_MSEC(100), canbus_tx_callback, NULL);
|
int rc = can_send(can_dev, &frame, K_MSEC(100), canbus_tx_callback, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
|
{
|
||||||
LOG_ERR("Failed to send CAN message: %d", rc);
|
LOG_ERR("Failed to send CAN message: %d", rc);
|
||||||
return rc; // Return error code
|
return rc; // Return error code
|
||||||
}
|
}
|
||||||
|
|
@ -163,3 +204,25 @@ int canbus_send_message(uint8_t destination_node, uint8_t register_address, uint
|
||||||
LOG_DBG("CAN message sent: ID=0x%08x, DLC=%u", frame.id, frame.dlc);
|
LOG_DBG("CAN message sent: ID=0x%08x, DLC=%u", frame.id, frame.dlc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int canbus_request_register(uint8_t node_id, uint8_t register_address)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct can_frame frame;
|
||||||
|
|
||||||
|
// Prepare the CAN frame for the request
|
||||||
|
frame.id = (node_id << 8) | register_address; // Standard ID with node ID in the first byte
|
||||||
|
frame.dlc = 0; // No data for request
|
||||||
|
frame.flags = CAN_FRAME_RTR; // Set RTR flag for request
|
||||||
|
|
||||||
|
// Send the CAN frame
|
||||||
|
rc = can_send(can_dev, &frame, K_MSEC(100), canbus_tx_callback, NULL);
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
LOG_ERR("Failed to send CAN request: %d", rc);
|
||||||
|
return rc; // Return error code
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("CAN request sent: ID=0x%08x", frame.id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
#include <zephyr/drivers/can.h>
|
#include <zephyr/drivers/can.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
|
#include "canbus_registers.h"
|
||||||
|
|
||||||
#define CANBUS_RX_THREAD_STACK_SIZE (512)
|
#define CANBUS_RX_THREAD_STACK_SIZE (512)
|
||||||
#define CANBUS_RX_THREAD_PRIORITY (-2)
|
#define CANBUS_RX_THREAD_PRIORITY (5)
|
||||||
|
#define CANBUS_RX_MSGQ_SIZE (5)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct can_frame_t{
|
||||||
/** Standard (11-bit) or extended (29-bit) CAN identifier. */
|
/** Standard (11-bit) or extended (29-bit) CAN identifier. */
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
/** Data Length Code (DLC) indicating data length in bytes. */
|
/** Data Length Code (DLC) indicating data length in bytes. */
|
||||||
|
|
@ -24,6 +26,7 @@ typedef struct {
|
||||||
} can_frame_t;
|
} can_frame_t;
|
||||||
|
|
||||||
int canbus_init(void);
|
int canbus_init(void);
|
||||||
int canbus_send_message(uint8_t destination_node, uint8_t register_address, uint8_t *data, size_t data_length);
|
int canbus_send_register(uint8_t node_id, uint8_t register_address, uint8_t *data, size_t data_length);
|
||||||
|
int canbus_request_register(uint8_t node_id, uint8_t register_address);
|
||||||
|
|
||||||
#endif // __CANBUS_H__
|
#endif // __CANBUS_H__
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __CANBUS_REGISTERS_H__
|
||||||
|
#define __CANBUS_REGISTERS_H__
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CANBUS_REGISTER_VALVE_COMMAND = 0x00,
|
||||||
|
CANBUS_REGISTER_VALVE_STATE = 0x01,
|
||||||
|
|
||||||
|
CANBUS_REGISTER_WATER_LEVEL_MM = 0x10,
|
||||||
|
CANBUS_REGISTER_WATER_MINIMUM = 0x11,
|
||||||
|
CANBUS_REGISTER_WATER_MAXIMUM = 0x12,
|
||||||
|
} canbus_registers_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CANBUS_REGISTER_COMMAND_SET = 0x00,
|
||||||
|
CANBUS_REGISTER_COMMAND_GET = 0x01,
|
||||||
|
} canbus_register_command_t;
|
||||||
|
|
||||||
|
#endif // __CANBUS_REGISTERS_H__
|
||||||
|
|
@ -6,6 +6,77 @@ LOG_MODULE_REGISTER(config, CONFIG_LOG_SETTINGS_LEVEL);
|
||||||
|
|
||||||
extern int canbus_node_id; // Default node ID for CAN bus
|
extern int canbus_node_id; // Default node ID for CAN bus
|
||||||
|
|
||||||
|
// Only compile shell commands if CONFIG_SHELL is enabled
|
||||||
|
// and CONFIG_REBOOT is enabled, as rebooting is required to apply changes
|
||||||
|
#ifdef CONFIG_SHELL
|
||||||
|
#ifndef CONFIG_REBOOT
|
||||||
|
#error You must enable CONFIG_REBOOT to use the shell commands
|
||||||
|
#endif // CONFIG_REBOOT
|
||||||
|
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
#include <zephyr/sys/reboot.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int reboot_system(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
// Reboot the system
|
||||||
|
shell_print(shell, "Rebooting node in 1 second...");
|
||||||
|
k_sleep(K_MSEC(1000)); // Wait for 1 second before rebooting
|
||||||
|
sys_reboot(SYS_REBOOT_COLD); // Perform a cold reboot
|
||||||
|
return 0; // Return 0 on success
|
||||||
|
}
|
||||||
|
|
||||||
|
int shell_print_config(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
// Print the current settings for the CAN bus node ID
|
||||||
|
shell_print(shell, "Current configuration settings:");
|
||||||
|
shell_print(shell, "%26s <%d>", "CANBUS node ID:", canbus_node_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int shell_set_canbus_node_id(const struct shell *shell, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
shell_print(shell, "argument count: %zu", argc);
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
shell_error(shell, "Usage: config set_nodeid <value>");
|
||||||
|
return -EINVAL; // Invalid argument
|
||||||
|
}
|
||||||
|
|
||||||
|
int new_node_id = atoi(argv[1]);
|
||||||
|
if (new_node_id < 1 || new_node_id > 7)
|
||||||
|
{
|
||||||
|
shell_error(shell, "Invalid CAN bus node ID: <%d>. Must be between 1 and 7.", new_node_id);
|
||||||
|
return -EINVAL; // Invalid argument
|
||||||
|
}
|
||||||
|
|
||||||
|
canbus_node_id = new_node_id;
|
||||||
|
LOG_INF("Set CAN bus node ID to <%d>", canbus_node_id);
|
||||||
|
|
||||||
|
// Save the new node ID to settings
|
||||||
|
int rc = settings_save_one("canbus/node_id", &canbus_node_id, sizeof(canbus_node_id));
|
||||||
|
if (rc < 0)
|
||||||
|
{
|
||||||
|
shell_error(shell, "Failed to save CAN bus node ID: %d", rc);
|
||||||
|
return rc; // Save error
|
||||||
|
}
|
||||||
|
|
||||||
|
shell_print(shell, "CAN bus node ID set to <%d> and saved to settings", canbus_node_id);
|
||||||
|
shell_warn(shell, "Reboot the node (command: 'reboot') to apply changes.");
|
||||||
|
return 0; // Return 0 on success
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||||
|
config_cmds,
|
||||||
|
SHELL_CMD_ARG(print, NULL, "Print current configuration settings", shell_print_config, 0, 0),
|
||||||
|
SHELL_CMD_ARG(set_nodeid, NULL, "Set canbus node id", shell_set_canbus_node_id, 2, 0),
|
||||||
|
SHELL_SUBCMD_SET_END
|
||||||
|
);
|
||||||
|
|
||||||
|
SHELL_CMD_REGISTER(config, &config_cmds, "Configuration commands", NULL);
|
||||||
|
SHELL_CMD_REGISTER(reboot, NULL, "Reboot the node", reboot_system);
|
||||||
|
#endif // CONFIG_SHELL
|
||||||
|
|
||||||
static int settings_canbus(const char *key, size_t len, settings_read_cb read_cb, void *cb_arg)
|
static int settings_canbus(const char *key, size_t len, settings_read_cb read_cb, void *cb_arg)
|
||||||
{
|
{
|
||||||
const char *next;
|
const char *next;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#include <zephyr/modbus/modbus.h>
|
#include <zephyr/modbus/modbus.h>
|
||||||
|
|
||||||
|
#define MODBUS_THREAD_STACK_SIZE (512)
|
||||||
|
#define MODBUS_THREAD_PRIORITY (6)
|
||||||
|
#define MODBUS_MSGQ_SIZE (5)
|
||||||
|
|
||||||
const static struct modbus_iface_param client_param = {
|
const static struct modbus_iface_param client_param = {
|
||||||
.mode = MODBUS_MODE_RTU,
|
.mode = MODBUS_MODE_RTU,
|
||||||
.rx_timeout = 50000,
|
.rx_timeout = 50000,
|
||||||
|
|
@ -12,6 +16,12 @@ const static struct modbus_iface_param client_param = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t reg;
|
||||||
|
uint8_t command; // 0 for set, 1 for get
|
||||||
|
int16_t value;
|
||||||
|
} modbus_register_t;
|
||||||
|
|
||||||
int mb_init_client(void);
|
int mb_init_client(void);
|
||||||
int mb_read_holding_registers(int node, uint16_t reg_addr, uint16_t *data, size_t len);
|
int mb_read_holding_registers(int node, uint16_t reg_addr, uint16_t *data, size_t len);
|
||||||
int mb_read_water_level(double *mb_read_water_level);
|
int mb_read_water_level(double *mb_read_water_level);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,20 @@
|
||||||
CONFIG_LOG=y
|
CONFIG_LOG=y
|
||||||
CONFIG_LOG_DEFAULT_LEVEL=3
|
CONFIG_LOG_DEFAULT_LEVEL=3
|
||||||
CONFIG_LOG_SETTINGS_LEVEL=4
|
# CONFIG_LOG_SETTINGS_LEVEL=4
|
||||||
CONFIG_LOG_CAN_LEVEL=4
|
# CONFIG_LOG_CAN_LEVEL=4
|
||||||
CONFIG_CBPRINTF_FP_SUPPORT=y
|
CONFIG_CBPRINTF_FP_SUPPORT=y
|
||||||
|
|
||||||
CONFIG_UART_CONSOLE=y # Console on USART1
|
CONFIG_UART_CONSOLE=y # Console on USART1
|
||||||
#CONFIG_RTT_CONSOLE=y
|
#CONFIG_RTT_CONSOLE=y
|
||||||
#CONFIG_USE_SEGGER_RTT=y
|
#CONFIG_USE_SEGGER_RTT=y
|
||||||
|
|
||||||
|
# CAN loopback mode for testing
|
||||||
CONFIG_LOOPBACK_MODE=y
|
CONFIG_LOOPBACK_MODE=y
|
||||||
|
CONFIG_SHELL=y
|
||||||
|
CONFIG_CAN_SHELL=y
|
||||||
|
CONFIG_GPIO_SHELL=y
|
||||||
|
CONFIG_REBOOT=y
|
||||||
|
|
||||||
|
# CONFIG_USE_SEGGER_RTT=y
|
||||||
|
# CONFIG_SHELL_BACKEND_RTT=y
|
||||||
|
# CONFIG_SHELL_BACKEND_SERIAL=n
|
||||||
|
|
@ -7,12 +7,75 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/sys/byteorder.h>
|
#include <zephyr/sys/byteorder.h>
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
|
||||||
#include "canbus.h"
|
#include "canbus.h"
|
||||||
|
#include "modbus.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL);
|
LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL);
|
||||||
|
|
||||||
|
K_THREAD_STACK_DEFINE(fake_modbus_stack, MODBUS_THREAD_STACK_SIZE);
|
||||||
|
K_MSGQ_DEFINE(modbus_msgq, sizeof(modbus_register_t), 10, 4);
|
||||||
|
|
||||||
|
int water_min = 0;
|
||||||
|
int water_max = 2000; // Maximum water level in mm
|
||||||
|
|
||||||
|
void fake_modbus_thread(void *arg1, void *arg2, void *arg3)
|
||||||
|
{
|
||||||
|
modbus_register_t reg;
|
||||||
|
ARG_UNUSED(arg1);
|
||||||
|
ARG_UNUSED(arg2);
|
||||||
|
ARG_UNUSED(arg3);
|
||||||
|
|
||||||
|
LOG_INF("Fake Modbus thread started");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
k_msgq_get(&modbus_msgq, ®, K_FOREVER);
|
||||||
|
LOG_INF("Received Modbus register: 0x%02x, command: %s, value: %d", reg.reg, reg.command ? "GET" : "SET", reg.value);
|
||||||
|
switch (reg.command)
|
||||||
|
{
|
||||||
|
case CANBUS_REGISTER_COMMAND_SET:
|
||||||
|
switch (reg.reg)
|
||||||
|
{
|
||||||
|
case CANBUS_REGISTER_WATER_MINIMUM:
|
||||||
|
water_min = reg.value;
|
||||||
|
LOG_INF("Set water minimum to %d mm", water_min);
|
||||||
|
break;
|
||||||
|
case CANBUS_REGISTER_WATER_MAXIMUM:
|
||||||
|
water_max = reg.value;
|
||||||
|
LOG_INF("Set water maximum to %d mm", water_max);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_INF("Received unknown command: 0x%02x for register: 0x%02x", reg.command, reg.reg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CANBUS_REGISTER_COMMAND_GET:
|
||||||
|
switch (reg.reg)
|
||||||
|
{
|
||||||
|
case CANBUS_REGISTER_WATER_LEVEL_MM:
|
||||||
|
// Simulate reading water level in mm
|
||||||
|
reg.value = (water_min + water_max) / 2; // Example: average of min and max
|
||||||
|
LOG_INF("Read water level: %d mm", reg.value);
|
||||||
|
break;
|
||||||
|
case CANBUS_REGISTER_WATER_MINIMUM:
|
||||||
|
reg.value = water_min;
|
||||||
|
LOG_INF("Read water minimum: %d mm", reg.value);
|
||||||
|
break;
|
||||||
|
case CANBUS_REGISTER_WATER_MAXIMUM:
|
||||||
|
reg.value = water_max;
|
||||||
|
LOG_INF("Read water maximum: %d mm", reg.value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_INF("Received unknown command: 0x%02x for register: 0x%02x", reg.command, reg.reg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
@ -32,25 +95,38 @@ int main(void)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
LOG_INF("CAN bus initialized successfully");
|
LOG_INF("CAN bus initialized successfully");
|
||||||
uint16_t counter = 0;
|
|
||||||
k_sleep(K_SECONDS(1)); // Sleep for 1 second before starting the loop
|
|
||||||
|
|
||||||
|
struct k_thread fake_modbus_thread_data;
|
||||||
|
k_tid_t fake_modbus_tid = k_thread_create(&fake_modbus_thread_data, fake_modbus_stack,
|
||||||
|
K_THREAD_STACK_SIZEOF(fake_modbus_stack), fake_modbus_thread, NULL, NULL, NULL,
|
||||||
|
MODBUS_THREAD_PRIORITY, 0, K_NO_WAIT);
|
||||||
|
if (fake_modbus_tid == NULL)
|
||||||
|
{
|
||||||
|
LOG_ERR("Failed to create fake Modbus thread");
|
||||||
|
return -ENOMEM; // Not enough memory to create thread
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("Fake Modbus thread created successfully");
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
uint8_t data[2] = {0x00};
|
canbus_request_register(0x01, CANBUS_REGISTER_WATER_LEVEL_MM); // Request water level in mm
|
||||||
UNALIGNED_PUT(sys_cpu_to_be16(counter), (uint16_t *)&data[0]);
|
k_sleep(K_MSEC(150)); // Wait for 150 ms to allow the request to be processed
|
||||||
canbus_send_message(1, 0x01, data, sizeof(data)); // Example message sending
|
canbus_request_register(0x01, CANBUS_REGISTER_WATER_MINIMUM); // Request water minimum
|
||||||
LOG_DBG("Sent message with counter: %d", counter);
|
k_sleep(K_MSEC(150)); // Wait for 150 ms to allow the request to be processed
|
||||||
canbus_send_message(2, 0x01, data, sizeof(data)); // Example message sending
|
|
||||||
LOG_DBG("Sent message with counter: %d", counter);
|
int water_tmp = -100;
|
||||||
counter++;
|
uint8_t data[2];
|
||||||
if (counter > 1000) // Reset counter after 1000
|
sys_put_be16(water_tmp, data); // Convert water_tmp to big-endian format
|
||||||
{
|
rc = canbus_send_register(0x01, CANBUS_REGISTER_WATER_MINIMUM, data, sizeof(data));
|
||||||
counter = 0;
|
k_sleep(K_MSEC(150)); // Wait for 150 ms to allow the request to be processed
|
||||||
}
|
canbus_request_register(0x01, CANBUS_REGISTER_WATER_LEVEL_MM); // Request water level in mm
|
||||||
|
k_sleep(K_MSEC(150)); // Wait for 150 ms to allow the request to be processed
|
||||||
|
canbus_request_register(0x01, CANBUS_REGISTER_WATER_MINIMUM); // Request water minimum
|
||||||
|
|
||||||
k_sleep(K_SECONDS(5)); // Sleep for 5 second before next iteration
|
k_sleep(K_SECONDS(5)); // Sleep for 5 second before next iteration
|
||||||
return 0; // Exit the loop after one iteration for testing purposes
|
return 0; // Exit the loop after one iteration for testing purposes
|
||||||
// In a real application, you would likely not return here and continue the loop indefinitely
|
// In a real application, you would remove this return statement
|
||||||
|
// to keep the loop running indefinitely.
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue