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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
************
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user