Added Zephyr settings and basic device in subsys. (#697)

* Added Zephyr settings subsys to enable storing of BACnet values according to BACnet object property value path.

* Added BACnet Basic features to enable basic samples. Refactored the zephyr BACnet profile B-SS sample to use BACnet basic subsys.
This commit is contained in:
Steve Karg
2024-07-19 17:12:20 -05:00
committed by GitHub
parent 90714c094c
commit 1e889b633c
33 changed files with 3400 additions and 213 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(b-ss)
target_sources(app PRIVATE src/main.c)
+1 -1
View File
@@ -7,7 +7,7 @@ Overview
********
This is a simple application demonstrating configuration of a
BACnet B-SS device profile.
BACnet B-SS (simple sensor) device profile.
Requirements
************
+101 -54
View File
@@ -1,83 +1,130 @@
# General config
#CONFIG_ASSERT=y
#CONFIG_ASSERT_LEVEL=2
#CONFIG_ASSERT_VERBOSE=y
# Compiler library config
#CONFIG_PICOLIBC=y
#CONFIG_PICOLIBC_USE_MODULE=y
#CONFIG_REQUIRES_FULL_LIBC=y
#CONFIG_MINIMAL_LIBC=y
# system
# some heap is needed for the shell
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_KERNEL_MEM_POOL=y
CONFIG_MAIN_THREAD_PRIORITY=7
#CONFIG_PICOLIBC=y
CONFIG_ISR_STACK_SIZE=8192
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=2048
CONFIG_INIT_STACKS=y
# BACnet Library
CONFIG_BACNETSTACK=y
CONFIG_BACNETSTACK_BACNET_BASIC=y
# BACnet Library - options
CONFIG_BACNET_MAX_CHARACTER_STRING_BYTES=128
CONFIG_BACAPP_MINIMAL=y
CONFIG_BACNET_PROPERTY_ARRAY_LISTS=y
# BACnet Library - objects
CONFIG_BACNET_BASIC_OBJECT_NETWORK_PORT=y
CONFIG_BACNET_BASIC_OBJECT_ANALOG_INPUT=y
# BACnet Library - shell
CONFIG_BACNET_BASIC_DEVICE_SHELL=y
# BACnet settings subsystem
#CONFIG_BACNETSTACK_BACNET_SETTINGS=y
#CONFIG_BACNET_SETTINGS=y
#CONFIG_BACNET_SETTINGS_SHELL=y
# BIP Options
CONFIG_BACDL_BIP=y
CONFIG_BACDL_BIP_PORT=47808
CONFIG_BACDL_BIP_ADDRESS_INDEX=0
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_IPV4_AUTO=y
#CONFIG_NET_CONFIG_SETTINGS=y
#CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.80"
#CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
#CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"
#CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.168.1.1"
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=4
# BIP6 Options
#CONFIG_BACDL_BIP6=y
CONFIG_BACDL_BIP6_PORT=47808
CONFIG_BACDL_BIP6_ADDRESS_INDEX=1
CONFIG_NET_IPV6_MLD=y
CONFIG_NET_IPV4=n
CONFIG_NET_ARP=n
CONFIG_BACDL_BIP6_ADDRESS_INDEX=0
CONFIG_BACDL_BIP6_MCAST_ADDRESS="FE80::0020" # YABE unicast workaround
CONFIG_NEWLIB_LIBC=y
# pthreads
CONFIG_POSIX_API=y
CONFIG_PTHREAD_IPC=y
CONFIG_POSIX_MQUEUE=y
#CONFIG_BACDL_BIP6_PORT=47808
#CONFIG_BACDL_BIP6_ADDRESS_INDEX=0
#CONFIG_BACDL_BIP6_MCAST_ADDRESS="FE80::0020"
#CONFIG_NET_IPV6=y
#CONFIG_NET_IPV6_MLD=y
#CONFIG_NET_CONFIG_MY_IPV6_ADDR="FE80::0010"
#CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4
#CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
# networking
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_ARP=y
CONFIG_NET_TCP=y
#CONFIG_NET_ARP=y
#CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
#CONFIG_NET_DHCPV4=y
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_SHELL=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.10.80"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.10.1"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.168.10.1"
CONFIG_NET_LLDP=y
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
CONFIG_NET_CONFIG_MY_IPV6_ADDR="FE80::0010"
# Promiscuous mode on layer 2 is required to receive IPv6 multicasts.
# Ethernet hardware will not respond to MAC 33:33:x:x:x:x without this:
CONFIG_ETH_MCUX_PROMISCUOUS_MODE=y
#CONFIG_LOG_STRDUP_BUF_COUNT=4
#CONFIG_LOG_STRDUP_MAX_STRING=96
CONFIG_DNS_RESOLVER=y
CONFIG_SLIP_STATISTICS=n
CONFIG_NET_SHELL=y
#CONFIG_DNS_RESOLVER=y
#CONFIG_SLIP_STATISTICS=n
CONFIG_NET_TX_STACK_SIZE=8192
CONFIG_NET_RX_STACK_SIZE=8192
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=4
# logging
# Enable Shell, Console, and Logging features
CONFIG_CONSOLE=y
CONFIG_PRINTK=y
CONFIG_SHELL=y
CONFIG_KERNEL_SHELL=y
CONFIG_THREAD_MONITOR=y
#CONFIG_BOOT_BANNER=n
CONFIG_THREAD_NAME=y
CONFIG_DEVICE_SHELL=y
#CONFIG_POSIX_CLOCK=y
#CONFIG_DATE_SHELL=y
CONFIG_LOG=y
#CONFIG_LOG_STRDUP_BUF_COUNT=4
#CONFIG_LOG_STRDUP_MAX_STRING=96
#CONFIG_NET_CONN_LOG_LEVEL_DEFAULT=n
#CONFIG_NET_CONN_LOG_LEVEL_DBG=y
#CONFIG_NET_IF_LOG_LEVEL_DEFAULT=n
CONFIG_NET_IF_LOG_LEVEL_DBG=y
CONFIG_NET_LOG=y
CONFIG_LOG=y
CONFIG_BACNETSTACK_LOG_LEVEL_DBG=y
# system
CONFIG_ISR_STACK_SIZE=8192
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=2048
# enable the thread, stack, and runtime stats
#CONFIG_THREAD_ANALYZER=y
#CONFIG_THREAD_STACK_INFO=y
#CONFIG_THREAD_RUNTIME_STATS=y
#CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=n
#CONFIG_SCHED_THREAD_USAGE=y
#CONFIG_SCHED_THREAD_USAGE_ANALYSIS=y
#CONFIG_STATS=y
#CONFIG_STATS_SHELL=y
#
# Storage
#
#CONFIG_FLASH=y
#CONFIG_FLASH_MAP=y
#CONFIG_FLASH_PAGE_LAYOUT=y
# native_posix uses a simulated flash
#CONFIG_FLASH_SIMULATOR=y
#CONFIG_DISK_ACCESS=y.
#CONFIG_FILE_SYSTEM=y
#CONFIG_FILE_SYSTEM_LITTLEFS=y
#CONFIG_FILE_SYSTEM_SHELL=y
#CONFIG_NVS=y
#CONFIG_SETTINGS=y
#CONFIG_SETTINGS_NVS=y
#CONFIG_SETTINGS_RUNTIME=y
#CONFIG_SETTINGS_FILE=y
#CONFIG_SETTINGS_SHELL=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_INIT_STACKS=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=131072
+1 -1
View File
@@ -4,4 +4,4 @@ sample:
tests:
bacnet-stack.sample.profile.b-ss:
tags: bacnet
platform_allow: qemu_x86 native_posix native_posix_64
platform_allow: qemu_x86 native_posix native_posix_64 native_sim
+21 -134
View File
@@ -4,154 +4,41 @@
* SPDX-License-Identifier: MIT
*/
#include <kernel.h>
#include <zephyr/kernel.h>
#include <stdint.h>
#include "bacnet/config.h"
/* BACnet Stack defines - first */
#include "bacnet/bacdef.h"
#include "bacnet/bacdcode.h"
#include "bacnet/apdu.h"
#include "bacnet/dcc.h"
#include "bacnet/iam.h"
#include "bacnet/npdu.h"
#include "bacnet/getevent.h"
/* BACnet Stack core API */
#include "bacnet/version.h"
#include "bacnet/basic/services.h"
#include "bacnet/datalink/dlenv.h"
#include "bacnet/basic/sys/filename.h"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/basic/tsm/tsm.h"
#include "bacnet/datalink/datalink.h"
#include "bacnet/basic/binding/address.h"
/* include the device object */
/* BACnet Stack basic device API - see bacnet_basic/device.c for details */
#include "bacnet/basic/object/device.h"
#include "bacnet/basic/object/lc.h"
#include "bacnet/basic/object/trendlog.h"
#if defined(INTRINSIC_REPORTING)
#include "bacnet/basic/object/nc.h"
#endif /* defined(INTRINSIC_REPORTING) */
/* BACnet Stack basic objects - also enable in prj.conf */
#include "bacnet/basic/object/ai.h"
#if (BACNET_PROTOCOL_REVISION >= 17)
#include "bacnet/basic/object/netport.h"
#endif
#include "bacnet_basic/bacnet_basic.h"
/* Logging module registration is already done in ports/zephyr/main.c */
#include <logging/log.h>
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(bacnet, CONFIG_BACNETSTACK_LOG_LEVEL);
/** Buffer used for receiving */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/** Initialize the handlers we will utilize.
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
*/
static void service_handlers_init(void)
{
Device_Init(NULL);
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS,
handler_who_has);
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler(
handler_unrecognized_service);
/* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE,
handler_write_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device);
/* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
}
void main(void)
int main(void)
{
LOG_INF("\n*** BACnet Profile B-SS Sample ***\n");
LOG_INF("BACnet Stack Version " BACNET_VERSION_TEXT);
/* initialize objects for this basic sample */
Device_Init(NULL);
Device_Set_Object_Instance_Number(260123);
Analog_Input_Create(1);
Analog_Input_Name_Set(1, "Sensor");
LOG_INF("BACnet Device ID: %u", Device_Object_Instance_Number());
LOG_INF("BACnet Device Max APDU: %d", MAX_APDU);
service_handlers_init();
datalink_init(NULL);
/* work happens in server module */
/* configure the timeout values */
int64_t last_ms = k_uptime_get();
/* broadcast an I-Am on startup */
Send_I_Am(&Handler_Transmit_Buffer[0]);
int64_t address_binding_tmr = 0;
#if defined(INTRINSIC_REPORTING)
int64_t recipient_scan_tmr = 0;
#endif
#if defined(BACNET_TIME_MASTER)
BACNET_DATE_TIME bdatetime = { 0 };
#endif
for (;;) {
k_sleep(K_MSEC(1)); /* Allows debug prints */
BACNET_ADDRESS src = { 0 }; /* address where message came from */
const unsigned timeout_ms = 1;
int64_t current_ms = k_uptime_get();
/* returns 0 bytes on timeout */
uint16_t const pdu_len = datalink_receive(&src, &Rx_Buf[0],
MAX_MPDU, timeout_ms);
/* process */
if (pdu_len > 0) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (current_ms - last_ms > 1000) {
const uint32_t elapsed_milliseconds =
(uint32_t)(current_ms - last_ms);
//TODO: const uint32_t elapsed_seconds = elapsed_milliseconds / 1000UL;
last_ms = current_ms;
//TODO: dcc_timer_seconds(elapsed_seconds);
//TODO: datalink_maintenance_timer(elapsed_seconds);
//TODO: dlenv_maintenance_timer(elapsed_seconds);
//TODO: Load_Control_State_Machine_handler():
//TODO: handler_cov_timer_seconds(elapsed_seconds);
//TODO: tsm_timer_milliseconds(elapsed_milliseconds);
//TODO: trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
//TODO: Device_local_reporting();
#endif
#if defined(BACNET_TIME_MASTER)
//TODO: Device_getCurrentDateTime(&bdatetime);
//TODO: handler_Timesync_task(&bdatetime);
#endif
address_binding_tmr += elapsed_milliseconds;
#if defined(INTRINSIC_REPORTING)
recipient_scan_tmr += elapsed_milliseconds;
#endif
}
//TODO: handler_cov_task();
/* scan cache address */
if (address_binding_tmr >= 60 * 1000) {
//TODO: address_cache_timer(address_binding_tmr / 1000);
address_binding_tmr = 0;
}
#if defined(INTRINSIC_REPORTING)
/* try to find addresses of recipients */
if (recipient_scan_tmr >= NC_RESCAN_RECIPIENTS_SECS * 1000) {
//TODO: Notification_Class_find_recipient();
recipient_scan_tmr = 0;
}
#endif
/* output */
/* blink LEDs, Turn on or off outputs, etc */
}
return 0;
}