Fixes after STM32 example merge
This commit is contained in:
parent
3bf5ed37c8
commit
c660369a43
@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.16)
|
||||
set(PROJ_NAME stm32-blackpill)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare( stm32_cmake
|
||||
GIT_REPOSITORY https://github.com/ObKo/stm32-cmake
|
||||
GIT_TAG v2.1.0
|
||||
GIT_SHALLOW TRUE
|
||||
FetchContent_Declare(stm32_cmake
|
||||
GIT_REPOSITORY https://github.com/ObKo/stm32-cmake
|
||||
GIT_TAG v2.1.0
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_Populate(stm32_cmake)
|
||||
set(CMAKE_TOOLCHAIN_FILE ${stm32_cmake_SOURCE_DIR}/cmake/stm32_gcc.cmake)
|
||||
@ -20,24 +20,24 @@ find_package(CMSIS COMPONENTS STM32F401CC REQUIRED)
|
||||
find_package(HAL COMPONENTS STM32F4 REQUIRED)
|
||||
|
||||
add_compile_options(
|
||||
-mcpu=cortex-m4
|
||||
-mfpu=fpv4-sp-d16
|
||||
-mfloat-abi=hard
|
||||
)
|
||||
-mcpu=cortex-m4
|
||||
-mfpu=fpv4-sp-d16
|
||||
-mfloat-abi=hard
|
||||
)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set( FREERTOS_HEAP "4")
|
||||
set( FREERTOS_PORT "GCC_ARM_CM4F")
|
||||
set(FREERTOS_HEAP "4")
|
||||
set(FREERTOS_PORT "GCC_ARM_CM4F")
|
||||
|
||||
add_library(freertos_config INTERFACE)
|
||||
target_include_directories(freertos_config SYSTEM
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
FetchContent_Declare( freertos_kernel
|
||||
GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||
GIT_TAG V11.1.0
|
||||
GIT_SHALLOW TRUE
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
FetchContent_Declare(freertos_kernel
|
||||
GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||
GIT_TAG V11.1.0
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(freertos_kernel)
|
||||
@ -45,82 +45,82 @@ FetchContent_MakeAvailable(freertos_kernel)
|
||||
set(WIZ_CHIP W5500)
|
||||
|
||||
FetchContent_Declare(
|
||||
wizchip
|
||||
GIT_REPOSITORY https://github.com/donghoonpark/wizchip-cmake
|
||||
GIT_SHALLOW TRUE
|
||||
wizchip
|
||||
GIT_REPOSITORY https://github.com/donghoonpark/wizchip-cmake
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(wizchip)
|
||||
|
||||
FetchContent_Declare(
|
||||
nanomodbus
|
||||
GIT_REPOSITORY https://github.com/debevv/nanoMODBUS
|
||||
GIT_TAG v1.18.1
|
||||
GIT_SHALLOW TRUE
|
||||
nanomodbus
|
||||
GIT_REPOSITORY https://github.com/debevv/nanoMODBUS
|
||||
GIT_TAG v1.18.1
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
|
||||
FetchContent_GetProperties(nanomodbus)
|
||||
if(NOT nanomodbus_POPULATED)
|
||||
FetchContent_Populate(nanomodbus)
|
||||
endif()
|
||||
if (NOT nanomodbus_POPULATED)
|
||||
FetchContent_Populate(nanomodbus)
|
||||
endif ()
|
||||
|
||||
add_library(nanomodbus ${nanomodbus_SOURCE_DIR}/nanomodbus.c)
|
||||
target_include_directories(nanomodbus PUBLIC ${nanomodbus_SOURCE_DIR})
|
||||
|
||||
set(TARGET_NAMES modbus_rtu modbus_tcp)
|
||||
|
||||
foreach(TARGET_NAME ${TARGET_NAMES})
|
||||
foreach (TARGET_NAME ${TARGET_NAMES})
|
||||
|
||||
add_executable(${TARGET_NAME}
|
||||
${TARGET_NAME}.c
|
||||
bsp/blackpill/blackpill.c
|
||||
nmbs/port.c
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
${TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bsp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nmbs
|
||||
)
|
||||
|
||||
if(${TARGET_NAME} STREQUAL "modbus_rtu")
|
||||
target_compile_definitions(
|
||||
${TARGET_NAME} PRIVATE
|
||||
NMBS_RTU
|
||||
add_executable(${TARGET_NAME}
|
||||
${TARGET_NAME}.c
|
||||
bsp/blackpill/blackpill.c
|
||||
nmbs/port.c
|
||||
)
|
||||
elseif(${TARGET_NAME} STREQUAL "modbus_tcp")
|
||||
target_compile_definitions(
|
||||
${TARGET_NAME} PRIVATE
|
||||
NMBS_TCP
|
||||
|
||||
target_include_directories(
|
||||
${TARGET_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bsp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/nmbs
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
${TARGET_NAME}
|
||||
STM32::NoSys
|
||||
CMSIS::STM32::F401CC
|
||||
HAL::STM32::F4::CORTEX
|
||||
HAL::STM32::F4::RCC
|
||||
HAL::STM32::F4::PWR
|
||||
HAL::STM32::F4::GPIO
|
||||
HAL::STM32::F4::TIM
|
||||
HAL::STM32::F4::UART
|
||||
HAL::STM32::F4::USART
|
||||
HAL::STM32::F4::SPI
|
||||
HAL::STM32::F4::DMA
|
||||
wizchip
|
||||
freertos_kernel
|
||||
nanomodbus
|
||||
)
|
||||
if (${TARGET_NAME} STREQUAL "modbus_rtu")
|
||||
target_compile_definitions(
|
||||
${TARGET_NAME} PRIVATE
|
||||
NMBS_RTU
|
||||
)
|
||||
elseif (${TARGET_NAME} STREQUAL "modbus_tcp")
|
||||
target_compile_definitions(
|
||||
${TARGET_NAME} PRIVATE
|
||||
NMBS_TCP
|
||||
)
|
||||
endif ()
|
||||
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${TARGET_NAME}>
|
||||
)
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${TARGET_NAME}> ${TARGET_NAME}.hex
|
||||
)
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${TARGET_NAME}> ${TARGET_NAME}.bin
|
||||
)
|
||||
target_link_libraries(
|
||||
${TARGET_NAME}
|
||||
STM32::NoSys
|
||||
CMSIS::STM32::F401CC
|
||||
HAL::STM32::F4::CORTEX
|
||||
HAL::STM32::F4::RCC
|
||||
HAL::STM32::F4::PWR
|
||||
HAL::STM32::F4::GPIO
|
||||
HAL::STM32::F4::TIM
|
||||
HAL::STM32::F4::UART
|
||||
HAL::STM32::F4::USART
|
||||
HAL::STM32::F4::SPI
|
||||
HAL::STM32::F4::DMA
|
||||
wizchip
|
||||
freertos_kernel
|
||||
nanomodbus
|
||||
)
|
||||
|
||||
endforeach()
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${TARGET_NAME}>
|
||||
)
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${TARGET_NAME}> ${TARGET_NAME}.hex
|
||||
)
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${TARGET_NAME}> ${TARGET_NAME}.bin
|
||||
)
|
||||
|
||||
endforeach ()
|
||||
@ -11,27 +11,23 @@
|
||||
static void blink(void* args);
|
||||
static void modbus(void* args);
|
||||
|
||||
uint32_t HAL_GetTick(void)
|
||||
{
|
||||
uint32_t HAL_GetTick(void) {
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
BSP_Init();
|
||||
|
||||
xTaskCreate(blink, "blink", 128, NULL, 4, NULL);
|
||||
xTaskCreate(blink, "blink", 128, NULL, 4, NULL);
|
||||
xTaskCreate(modbus, "modbus", 128 * 16, NULL, 2, NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
for(;;){}
|
||||
for (;;) {}
|
||||
}
|
||||
|
||||
static void blink(void* args)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
static void blink(void* args) {
|
||||
for (;;) {
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
|
||||
vTaskDelay(500);
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
|
||||
@ -40,15 +36,19 @@ static void blink(void* args)
|
||||
}
|
||||
|
||||
nmbs_t nmbs;
|
||||
nmbs_server_t nmbs_server =
|
||||
{
|
||||
.id = 0x01,
|
||||
.coils = {0,},
|
||||
.regs = {0,},
|
||||
nmbs_server_t nmbs_server = {
|
||||
.id = 0x01,
|
||||
.coils =
|
||||
{
|
||||
0,
|
||||
},
|
||||
.regs =
|
||||
{
|
||||
0,
|
||||
},
|
||||
};
|
||||
|
||||
static void modbus(void* args)
|
||||
{
|
||||
static void modbus(void* args) {
|
||||
#if TEST_SERVER
|
||||
nmbs_server_init(&nmbs, &nmbs_server);
|
||||
#endif
|
||||
@ -59,7 +59,7 @@ static void modbus(void* args)
|
||||
nmbs_client_init(&nmbs);
|
||||
#endif
|
||||
|
||||
for(;;){
|
||||
for (;;) {
|
||||
#if TEST_SERVER
|
||||
nmbs_server_poll(&nmbs);
|
||||
taskYIELD();
|
||||
@ -68,9 +68,8 @@ static void modbus(void* args)
|
||||
nmbs_set_destination_rtu_address(&nmbs, 0x01);
|
||||
nmbs_error status = nmbs_read_holding_registers(&nmbs, 0, 32, regs_test);
|
||||
status = nmbs_write_multiple_registers(&nmbs, 0, 32, regs_test);
|
||||
if(status != NMBS_ERROR_NONE)
|
||||
{
|
||||
while(true){}
|
||||
if (status != NMBS_ERROR_NONE) {
|
||||
while (true) {}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1,85 +1,68 @@
|
||||
#include "blackpill/blackpill.h"
|
||||
#include "wizchip.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <socket.h>
|
||||
#include "nanomodbus.h"
|
||||
#include "nmbs/port.h"
|
||||
#include "task.h"
|
||||
#include <socket.h>
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
wiz_NetInfo net_info = {
|
||||
.mac = { 0xEA, 0x11, 0x22, 0x33, 0x44, 0xEA },
|
||||
.ip = {192, 168, 137, 100}, // You can find this ip if you set your ethernet port ip as 192.168.137.XXX
|
||||
.sn = {255, 255, 255, 0},
|
||||
.gw = {192, 168, 137, 1},
|
||||
.dns = {0, 0, 0, 0},
|
||||
}; // Network information.
|
||||
.mac = {0xEA, 0x11, 0x22, 0x33, 0x44, 0xEA},
|
||||
.ip = {192, 168, 137, 100}, // You can find this ip if you set your ethernet port ip as 192.168.137.XXX
|
||||
.sn = {255, 255, 255, 0},
|
||||
.gw = {192, 168, 137, 1},
|
||||
.dns = {0, 0, 0, 0},
|
||||
}; // Network information.
|
||||
|
||||
uint8_t transaction_buf_sizes[] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2
|
||||
}; // All 2kB buffer setting for each sockets
|
||||
uint8_t transaction_buf_sizes[] = {2, 2, 2, 2, 2, 2, 2, 2}; // All 2kB buffer setting for each sockets
|
||||
|
||||
#if USE_HAL_SPI_REGISTER_CALLBACKS == 0
|
||||
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef* hspi) {
|
||||
wizchip_dma_rx_cplt((void*) hspi);
|
||||
}
|
||||
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef* hspi) {
|
||||
wizchip_dma_tx_cplt((void*) hspi);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t HAL_GetTick(void)
|
||||
{
|
||||
uint32_t HAL_GetTick(void) {
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
static void blink(void* args);
|
||||
static void modbus(void* args);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
BSP_Init();
|
||||
wizchip_register_hal(
|
||||
&hspi1,
|
||||
(fHalSpiTransaction) HAL_SPI_Receive,
|
||||
(fHalSpiTransaction) HAL_SPI_Transmit,
|
||||
(fHalSpiTransactionDma) HAL_SPI_Receive_DMA,
|
||||
(fHalSpiTransactionDma) HAL_SPI_Transmit_DMA,
|
||||
GPIOA,
|
||||
GPIO_PIN_15,
|
||||
(fHalGpioWritePin) HAL_GPIO_WritePin
|
||||
);
|
||||
wizchip_register_hal(&hspi1, (fHalSpiTransaction) HAL_SPI_Receive, (fHalSpiTransaction) HAL_SPI_Transmit,
|
||||
(fHalSpiTransactionDma) HAL_SPI_Receive_DMA, (fHalSpiTransactionDma) HAL_SPI_Transmit_DMA,
|
||||
GPIOA, GPIO_PIN_15, (fHalGpioWritePin) HAL_GPIO_WritePin);
|
||||
|
||||
wizchip_init(transaction_buf_sizes, transaction_buf_sizes);
|
||||
setSHAR(net_info.mac);
|
||||
setSIPR(net_info.ip);
|
||||
setSUBR(net_info.sn);
|
||||
setGAR (net_info.gw);
|
||||
setGAR(net_info.gw);
|
||||
|
||||
xTaskCreate(blink, "blink", 128, NULL, 4, NULL);
|
||||
xTaskCreate(modbus, "modbus", 128 * 16, NULL, 2, NULL);
|
||||
xTaskCreate(blink, "blink", 128, NULL, 4, NULL);
|
||||
xTaskCreate(modbus, "modbus", 128 * 16, NULL, 2, NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
while(true)
|
||||
{
|
||||
}
|
||||
while (true) {}
|
||||
}
|
||||
|
||||
static void blink(void* args)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
static void blink(void* args) {
|
||||
for (;;) {
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
|
||||
vTaskDelay(500);
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
|
||||
@ -88,41 +71,43 @@ static void blink(void* args)
|
||||
}
|
||||
|
||||
static nmbs_t nmbs;
|
||||
static nmbs_server_t nmbs_server =
|
||||
{
|
||||
.id = 0x01,
|
||||
.coils = {0,},
|
||||
.regs = {0,},
|
||||
static nmbs_server_t nmbs_server = {
|
||||
.id = 0x01,
|
||||
.coils =
|
||||
{
|
||||
0,
|
||||
},
|
||||
.regs =
|
||||
{
|
||||
0,
|
||||
},
|
||||
};
|
||||
static void modbus(void* args)
|
||||
{
|
||||
static void modbus(void* args) {
|
||||
int status;
|
||||
|
||||
nmbs_server_init(&nmbs, &nmbs_server);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
switch ((status = getSn_SR(MB_SOCKET)))
|
||||
{
|
||||
case SOCK_ESTABLISHED:
|
||||
nmbs_server_poll(&nmbs);
|
||||
break;
|
||||
|
||||
case SOCK_INIT :
|
||||
listen(MB_SOCKET);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSED:
|
||||
socket(MB_SOCKET, Sn_MR_TCP, 502, 0);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSE_WAIT :
|
||||
disconnect(MB_SOCKET);
|
||||
break;
|
||||
for (;;) {
|
||||
switch ((status = getSn_SR(MB_SOCKET))) {
|
||||
case SOCK_ESTABLISHED:
|
||||
nmbs_server_poll(&nmbs);
|
||||
break;
|
||||
|
||||
default:
|
||||
taskYIELD();
|
||||
break;
|
||||
case SOCK_INIT:
|
||||
listen(MB_SOCKET);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSED:
|
||||
socket(MB_SOCKET, Sn_MR_TCP, 502, 0);
|
||||
break;
|
||||
|
||||
case SOCK_CLOSE_WAIT:
|
||||
disconnect(MB_SOCKET);
|
||||
break;
|
||||
|
||||
default:
|
||||
taskYIELD();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include <string.h>
|
||||
#include "nmbs/port.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NMBS_TCP
|
||||
static int32_t read_socket(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg);
|
||||
@ -10,58 +10,60 @@ static int32_t write_socket(const uint8_t* buf, uint16_t count, int32_t byte_tim
|
||||
static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg);
|
||||
static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg);
|
||||
|
||||
#if MB_UART_DMA
|
||||
#if MB_UART_DMA
|
||||
#include "queue.h"
|
||||
xQueueHandle rtu_rx_q;
|
||||
uint8_t rtu_rx_b[MB_RX_BUF_SIZE];
|
||||
uint8_t rtu_rx_b[MB_RX_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static nmbs_server_t* server;
|
||||
|
||||
static nmbs_error server_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id,
|
||||
void* arg);
|
||||
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out,
|
||||
uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_single_coil(uint16_t address, bool value, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils,
|
||||
uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_single_register(uint16_t address, uint16_t value, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers, uint8_t unit_id, void* arg);
|
||||
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers,
|
||||
uint8_t unit_id, void* arg);
|
||||
|
||||
nmbs_error nmbs_server_init(nmbs_t* nmbs, nmbs_server_t* _server)
|
||||
{
|
||||
nmbs_error nmbs_server_init(nmbs_t* nmbs, nmbs_server_t* _server) {
|
||||
nmbs_platform_conf conf;
|
||||
nmbs_callbacks cb;
|
||||
nmbs_callbacks cb;
|
||||
|
||||
nmbs_platform_conf_create(&conf);
|
||||
#ifdef NMBS_TCP
|
||||
conf.transport = NMBS_TRANSPORT_TCP;
|
||||
conf.read = read_socket;
|
||||
conf.transport = NMBS_TRANSPORT_TCP;
|
||||
conf.read = read_socket;
|
||||
conf.write = write_socket;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef NMBS_RTU
|
||||
conf.transport = NMBS_TRANSPORT_RTU;
|
||||
conf.read = read_serial;
|
||||
conf.transport = NMBS_TRANSPORT_RTU;
|
||||
conf.read = read_serial;
|
||||
conf.write = write_serial;
|
||||
#endif
|
||||
|
||||
server = _server;
|
||||
|
||||
nmbs_callbacks_create(&cb);
|
||||
cb.read_coils = server_read_coils;
|
||||
cb.read_holding_registers = server_read_holding_registers;
|
||||
cb.write_single_coil = server_write_single_coil;
|
||||
cb.write_multiple_coils = server_write_multiple_coils;
|
||||
cb.write_single_register = server_write_single_register;
|
||||
cb.write_multiple_registers = server_write_multiple_registers;
|
||||
cb.read_coils = server_read_coils;
|
||||
cb.read_holding_registers = server_read_holding_registers;
|
||||
cb.write_single_coil = server_write_single_coil;
|
||||
cb.write_multiple_coils = server_write_multiple_coils;
|
||||
cb.write_single_register = server_write_single_register;
|
||||
cb.write_multiple_registers = server_write_multiple_registers;
|
||||
|
||||
#if MB_UART_DMA
|
||||
#if MB_UART_DMA
|
||||
rtu_rx_q = xQueueCreate(MB_RX_BUF_SIZE, sizeof(uint8_t));
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(&MB_UART, rtu_rx_b, MB_RX_BUF_SIZE);
|
||||
#endif
|
||||
|
||||
nmbs_error status = nmbs_server_create(nmbs, server->id, &conf, &cb);
|
||||
if(status != NMBS_ERROR_NONE)
|
||||
{
|
||||
if (status != NMBS_ERROR_NONE) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -71,25 +73,23 @@ nmbs_error nmbs_server_init(nmbs_t* nmbs, nmbs_server_t* _server)
|
||||
return NMBS_ERROR_NONE;
|
||||
}
|
||||
|
||||
nmbs_error nmbs_client_init(nmbs_t* nmbs)
|
||||
{
|
||||
nmbs_error nmbs_client_init(nmbs_t* nmbs) {
|
||||
nmbs_platform_conf conf;
|
||||
|
||||
nmbs_platform_conf_create(&conf);
|
||||
#ifdef NMBS_TCP
|
||||
conf.transport = NMBS_TRANSPORT_TCP;
|
||||
conf.read = read_socket;
|
||||
conf.transport = NMBS_TRANSPORT_TCP;
|
||||
conf.read = read_socket;
|
||||
conf.write = write_socket;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef NMBS_RTU
|
||||
conf.transport = NMBS_TRANSPORT_RTU;
|
||||
conf.read = read_serial;
|
||||
conf.transport = NMBS_TRANSPORT_RTU;
|
||||
conf.read = read_serial;
|
||||
conf.write = write_serial;
|
||||
#endif
|
||||
|
||||
nmbs_error status = nmbs_client_create(nmbs, &conf);
|
||||
if(status != NMBS_ERROR_NONE)
|
||||
{
|
||||
if (status != NMBS_ERROR_NONE) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -100,27 +100,21 @@ nmbs_error nmbs_client_init(nmbs_t* nmbs)
|
||||
}
|
||||
|
||||
|
||||
static nmbs_server_t* get_server(uint8_t id)
|
||||
{
|
||||
if(id == server->id)
|
||||
{
|
||||
static nmbs_server_t* get_server(uint8_t id) {
|
||||
if (id == server->id) {
|
||||
return server;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static nmbs_error server_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_read_coils(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id,
|
||||
void* arg) {
|
||||
nmbs_server_t* server = get_server(unit_id);
|
||||
|
||||
for(size_t i = 0; i < quantity; i++)
|
||||
{
|
||||
if((address>>3) > COIL_BUF_SIZE)
|
||||
{
|
||||
for (size_t i = 0; i < quantity; i++) {
|
||||
if ((address >> 3) > COIL_BUF_SIZE) {
|
||||
return NMBS_ERROR_INVALID_REQUEST;
|
||||
}
|
||||
nmbs_bitfield_write(coils_out, address, nmbs_bitfield_read(server->coils, address));
|
||||
@ -129,14 +123,12 @@ static nmbs_error server_read_coils(uint16_t address, uint16_t quantity, nmbs_bi
|
||||
return NMBS_ERROR_NONE;
|
||||
}
|
||||
|
||||
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quantity, uint16_t* registers_out,
|
||||
uint8_t unit_id, void* arg) {
|
||||
nmbs_server_t* server = get_server(unit_id);
|
||||
|
||||
for(size_t i = 0; i < quantity; i++)
|
||||
{
|
||||
if(address > REG_BUF_SIZE)
|
||||
{
|
||||
for (size_t i = 0; i < quantity; i++) {
|
||||
if (address > REG_BUF_SIZE) {
|
||||
return NMBS_ERROR_INVALID_REQUEST;
|
||||
}
|
||||
registers_out[i] = server->regs[address++];
|
||||
@ -144,24 +136,20 @@ static nmbs_error server_read_holding_registers(uint16_t address, uint16_t quant
|
||||
return NMBS_ERROR_NONE;
|
||||
}
|
||||
|
||||
static nmbs_error server_write_single_coil(uint16_t address, bool value, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_write_single_coil(uint16_t address, bool value, uint8_t unit_id, void* arg) {
|
||||
uint8_t coil = 0;
|
||||
if(value)
|
||||
{
|
||||
if (value) {
|
||||
coil |= 0x01;
|
||||
}
|
||||
return server_write_multiple_coils(address, 1, &coil, unit_id, arg);
|
||||
}
|
||||
|
||||
static nmbs_error server_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_write_multiple_coils(uint16_t address, uint16_t quantity, const nmbs_bitfield coils,
|
||||
uint8_t unit_id, void* arg) {
|
||||
nmbs_server_t* server = get_server(unit_id);
|
||||
|
||||
for(size_t i = 0; i < quantity; i++)
|
||||
{
|
||||
if((address>>3) > COIL_BUF_SIZE)
|
||||
{
|
||||
for (size_t i = 0; i < quantity; i++) {
|
||||
if ((address >> 3) > COIL_BUF_SIZE) {
|
||||
return NMBS_ERROR_INVALID_REQUEST;
|
||||
}
|
||||
nmbs_bitfield_write(server->coils, address, nmbs_bitfield_read(coils, i));
|
||||
@ -170,20 +158,17 @@ static nmbs_error server_write_multiple_coils(uint16_t address, uint16_t quantit
|
||||
return NMBS_ERROR_NONE;
|
||||
}
|
||||
|
||||
static nmbs_error server_write_single_register(uint16_t address, uint16_t value, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_write_single_register(uint16_t address, uint16_t value, uint8_t unit_id, void* arg) {
|
||||
uint16_t reg = value;
|
||||
return server_write_multiple_registers(address, 1, ®, unit_id, arg);
|
||||
}
|
||||
|
||||
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers, uint8_t unit_id, void* arg)
|
||||
{
|
||||
static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t quantity, const uint16_t* registers,
|
||||
uint8_t unit_id, void* arg) {
|
||||
nmbs_server_t* server = get_server(unit_id);
|
||||
|
||||
for(size_t i = 0; i < quantity; i++)
|
||||
{
|
||||
if(address > REG_BUF_SIZE)
|
||||
{
|
||||
for (size_t i = 0; i < quantity; i++) {
|
||||
if (address > REG_BUF_SIZE) {
|
||||
return NMBS_ERROR_INVALID_REQUEST;
|
||||
}
|
||||
server->regs[address++] = registers[i];
|
||||
@ -192,66 +177,53 @@ static nmbs_error server_write_multiple_registers(uint16_t address, uint16_t qua
|
||||
}
|
||||
|
||||
#ifdef NMBS_TCP
|
||||
int32_t read_socket(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg)
|
||||
{
|
||||
int32_t read_socket(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
|
||||
uint32_t tick_start = HAL_GetTick();
|
||||
while(recv(MB_SOCKET, buf, count) != count)
|
||||
{
|
||||
if(HAL_GetTick() - tick_start >= (uint32_t)byte_timeout_ms)
|
||||
{
|
||||
while (recv(MB_SOCKET, buf, count) != count) {
|
||||
if (HAL_GetTick() - tick_start >= (uint32_t) byte_timeout_ms) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int32_t write_socket(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg)
|
||||
{
|
||||
int32_t write_socket(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
|
||||
return send(MB_SOCKET, buf, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NMBS_RTU
|
||||
static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg)
|
||||
{
|
||||
static int32_t read_serial(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
|
||||
#if MB_UART_DMA
|
||||
uint32_t tick_start = HAL_GetTick();
|
||||
while(uxQueueMessagesWaiting(rtu_rx_q) < count)
|
||||
{
|
||||
if(HAL_GetTick() - tick_start >= (uint32_t)byte_timeout_ms)
|
||||
{
|
||||
while (uxQueueMessagesWaiting(rtu_rx_q) < count) {
|
||||
if (HAL_GetTick() - tick_start >= (uint32_t) byte_timeout_ms) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
xQueueReceive(rtu_rx_q, buf + i, 1);
|
||||
}
|
||||
return count;
|
||||
#else
|
||||
HAL_StatusTypeDef status = HAL_UART_Receive(&MB_UART, buf, count, byte_timeout_ms);
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if (status == HAL_OK) {
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg)
|
||||
{
|
||||
#if MB_UART_DMA
|
||||
static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms, void* arg) {
|
||||
#if MB_UART_DMA
|
||||
HAL_UART_Transmit_DMA(&MB_UART, buf, count);
|
||||
#else
|
||||
HAL_StatusTypeDef status = HAL_UART_Transmit(&MB_UART, buf, count, byte_timeout_ms);
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if (status == HAL_OK) {
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -259,16 +231,13 @@ static int32_t write_serial(const uint8_t* buf, uint16_t count, int32_t byte_tim
|
||||
|
||||
|
||||
#if MB_UART_DMA
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
||||
{
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t Size) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if(huart == &MB_UART)
|
||||
{
|
||||
for(int i = 0; i < Size; i++)
|
||||
{
|
||||
if (huart == &MB_UART) {
|
||||
for (int i = 0; i < Size; i++) {
|
||||
xQueueSendFromISR(rtu_rx_q, rtu_rx_b + i, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(huart, rtu_rx_b, MB_RX_BUF_SIZE);
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(huart, rtu_rx_b, MB_RX_BUF_SIZE);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
// You may add your additional uart handler below
|
||||
|
||||
@ -6,32 +6,32 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// Max size of coil and register area
|
||||
#define COIL_BUF_SIZE 1024
|
||||
#define REG_BUF_SIZE 2048
|
||||
#define COIL_BUF_SIZE 1024
|
||||
#define REG_BUF_SIZE 2048
|
||||
|
||||
// NanoModbus include
|
||||
#include "nanomodbus.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
#ifdef NMBS_TCP
|
||||
// modbus tcp
|
||||
// modbus tcp
|
||||
#define MB_SOCKET 1
|
||||
#include <socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef NMBS_RTU
|
||||
// modbus rtu
|
||||
#define MB_UART huart1
|
||||
#define MB_UART_DMA 1
|
||||
#define MB_RX_BUF_SIZE 256
|
||||
#define MB_UART huart1
|
||||
#define MB_UART_DMA 1
|
||||
#define MB_RX_BUF_SIZE 256
|
||||
extern UART_HandleTypeDef MB_UART;
|
||||
#endif
|
||||
|
||||
typedef struct tNmbsServer{
|
||||
uint8_t id;
|
||||
uint8_t coils[COIL_BUF_SIZE];
|
||||
typedef struct tNmbsServer {
|
||||
uint8_t id;
|
||||
uint8_t coils[COIL_BUF_SIZE];
|
||||
uint16_t regs[REG_BUF_SIZE];
|
||||
}nmbs_server_t;
|
||||
} nmbs_server_t;
|
||||
|
||||
nmbs_error nmbs_server_init(nmbs_t* nmbs, nmbs_server_t* server);
|
||||
nmbs_error nmbs_client_init(nmbs_t* nmbs);
|
||||
|
||||
@ -1,29 +1,37 @@
|
||||
# STM32 nanomodbus porting
|
||||
# STM32 nanomodbus porting
|
||||
|
||||
## Target hardware
|
||||
|
||||

|
||||
|
||||
- Blackpill board
|
||||
- STM32F401CCUx
|
||||
- STM32F401CCUx
|
||||
- USART1 (with/without) DMA
|
||||
- PA9 : TX1
|
||||
- PA10 : RX1
|
||||
- PA9 : TX1
|
||||
- PA10 : RX1
|
||||
- SPI1 with DMA (connected to W5500)
|
||||
- PB3 : SCK1
|
||||
- PB4 : MISO1
|
||||
- PB5 : MOSI1
|
||||
- PA15 : NSS (Software select)
|
||||
- PB3 : SCK1
|
||||
- PB4 : MISO1
|
||||
- PB5 : MOSI1
|
||||
- PA15 : NSS (Software select)
|
||||
|
||||
## Toolchain and environment
|
||||
|
||||
Tested on Mac OS Sonoma(Apple Silicon) & Windows 10 but other os having same toolchain should have no problem.
|
||||
|
||||
- arm-none-eabi-gcc
|
||||
- arm-none-eabi-gcc
|
||||
- cmake
|
||||
- ninja
|
||||
- openocd
|
||||
- vscode
|
||||
- CMake
|
||||
- cortex-debug
|
||||
- CMake
|
||||
- cortex-debug
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j16
|
||||
```
|
||||
|
||||
Loading…
Reference in New Issue
Block a user