305 lines
14 KiB
Plaintext
305 lines
14 KiB
Plaintext
FAQ - Frequently Asked Questions about the BACnet Stack
|
|
|
|
Q-1: Do you know the typical footprint of the stack (MS/TP use)?
|
|
|
|
A-1a: It fits on a PIC18F6720 (128K bytes flash 3840 bytes RAM) and
|
|
there is lots of room for the application. In one device with 8 Binary
|
|
Value objects, 8 Binary Input objects, 1 Analog Input object, and
|
|
supporting ReadProperty, WriteProperty, DeviceCommunicationControl,
|
|
TimeSync, ReinitializeDevice, Who-Is, I-Am services, the BACnet stack
|
|
used about 32K words of the code space.
|
|
|
|
A-1b: It fits on a ATmega168 (16K bytes flash, 1024 bytes RAM). In one
|
|
device with 9 Analog Value objects supporting ReadProperty, Who-Is,
|
|
I-Am services, and 128 byte Maximum APDU. Using the Win-AVR (GCC-AVR)
|
|
compiler, the AVR Memory Usage:
|
|
Program: 16350 bytes (99.8% Full)
|
|
Data: 630 bytes (61.5% Full)
|
|
Using the IAR compiler, the AVR Memory Usage:
|
|
10 055 bytes of CODE memory (+ 36 range fill )
|
|
553 bytes of DATA memory (+ 24 absolute )
|
|
|
|
Q-2: The homepage used to say that the MS/TP code does not work. Still
|
|
true?
|
|
|
|
A-2: MS/TP works correctly as of the 0.2.6 release. I spent a several
|
|
days correcting it while working on the RTOS-32 port, and then a full
|
|
day fine-tuning it while working on the PIC18F6720 that I used at the
|
|
2006 BACnet International Plugfest. I also successfully used MS/TP
|
|
with the 0.4.0 release at the 2007 BACnet International Plugfest on an
|
|
Atmel AVR ATmega168.
|
|
|
|
Q-3: Does the stack have some specific requirements regarding the
|
|
hardware (e.g. non-volatile memory, 32-bit CPU, ...)?
|
|
|
|
A-3: Not really. The specific stuff is in the ports/ directory, and
|
|
that is expected to be modified by the end user if necessary. Big
|
|
Endian and Little Endian used to be automatic, but that took up too
|
|
much code space, so there is a BIG_ENDIAN define in the makefile. Most
|
|
of the variables are defined using the ANSI C-99 uint8_t, uint16_t,
|
|
uint32_t, int8_t, int16_t, int32_t from stdint.h, along with bool from
|
|
stdbool.h. Most of the APDU size returns are int.
|
|
|
|
Q-4: Does the stack have some specific requirements regarding OS? What
|
|
OS features are used (threads, timers, semaphors, events, mutexes...)?
|
|
|
|
A-4: No, I did not use any OS features (except for the the ports to
|
|
specific OS's: port/rtos32/, port/win32/ and port/linux/ which uses
|
|
some tasks or threads for the MS/TP datalink layer or sockets for the
|
|
BACnet/IP layers). Since my target was embedded, I kept every thing
|
|
single-threaded (but multithread safe except where noted) to keep it
|
|
easy to follow and easy to implement in a microcontroller just running
|
|
a main() loop.
|
|
|
|
Q-5: What is the difference between the two datalink layers BACnet/IP
|
|
and BACnet Ethernet? In BACnet/IP, is the MAC address needed?
|
|
|
|
A-5: The BACnet/IP datalink layer uses the BACnet Virtual Link Control
|
|
(BVLC) for networking using UDP/IP. The IPv4 address (x.x.x.x) and the
|
|
port number (0xBAC0) is stored as the MAC address. IPv6 will utilize a
|
|
virtual MAC address which will be the Device ID. See Annex J or bip.c
|
|
in the BACnet stack.
|
|
|
|
BACnet Ethernet uses the Ethernet MAC address, and communicates using
|
|
the IEEE 802.2/802.3 (see ANSI/ASHRAE 135-2004-7 Data Link/Physical
|
|
Layers: ISO 8802-3 ("Ethernet") LAN). See ethernet.c in the
|
|
port/linux/ directory of the BACnet stack.
|
|
|
|
Q-6: What do I need to do to learn about BACnet? Can this project
|
|
help?
|
|
|
|
A-6: Open source projects are great since they allow you to look over
|
|
the internals of a program or library. However, sometimes you just
|
|
want to see something work. I created about a dozen example
|
|
applications for testing. One of the applications is
|
|
demo/server/bacserv that acts like a BACnet server device. Run it on
|
|
one PC or hardware platform, and then use the other example
|
|
applications on another PC to interact with it. Monitor the BACnet
|
|
network activity with the WireShark protocol analyzer. Modify the
|
|
example applications - "Take chances, make mistakes, get messy." Have
|
|
fun! Join the BACnet developers mailing list and ask lots of questions
|
|
so others can learn and help too!
|
|
|
|
Q-7: The stack is working fine with demo/server/bacserv. But in the
|
|
WireShark protocol analyzer, I am able to see only 'Who-Is' and 'I
|
|
-Am' query/responses. The ReadProperty query/responses are not there
|
|
in the capture viewer. Why?
|
|
|
|
A-7: If you are only able to see broadcast messages like Who-Is and
|
|
I-Am, then you are probably networking using an Ethernet switch
|
|
(bridge) to connect WireShark to the devices. The Ethernet switch
|
|
(bridge) actually routes the unicast messages between ports and does
|
|
not send them to all ports (unless configured to do so). If you use an
|
|
Ethernet Hub or run WireShark from one of the devices under test, you
|
|
will then see the ReadProperty messages.
|
|
|
|
Q-8: I intend to write a little program to implement the comunication
|
|
between Bacnet devices and tcp/ip devices, but not use PAD and
|
|
BACnet/IP. Can I do that in a standard way?
|
|
|
|
A-8: You describe what the BACnet committee just published recently:
|
|
Addendum 135-2004c, BACnet Web Services, which has been approved by
|
|
ASHRAE and ANSI.
|
|
|
|
I don't have web services implemented in the BACnet stack at
|
|
SourceForge, but you could certainly use the stack do so.
|
|
|
|
Q-9: How do I create the required objects (analog inputs, analog
|
|
outputs, binary inputs, binary outputs) to support the hardware on my
|
|
board?
|
|
|
|
A-9: See the example application demo/server for an example of a
|
|
server application with objects included. The simple answer is that
|
|
they exist in the Device object in the Object_List property. Every
|
|
BACnet device is required to have a Device Object, and one of the
|
|
required properties is the Object_List property.
|
|
|
|
The example objects are in demo/object and those that are included in
|
|
the device are in demo/object/device.c as defined in 5 locations in
|
|
the file. For each object type:
|
|
|
|
1. #include the header file for the object
|
|
2. Device_Object_List_Count() needs to include a call to a
|
|
count function from the object type.
|
|
3. Device_Object_List_Identifier() needs to include some code
|
|
to get the object instance for each object.
|
|
4. Device_Valid_Object_Id() needs to get the object name for
|
|
each object.
|
|
5. PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED needs to set a bit for
|
|
each object type supported.
|
|
|
|
Additionally, for each service that interacts with objects, you will
|
|
need to include handling for that object. See demo/handler/h_rp.c to
|
|
see how the different objects are accessed for the ReadProperty
|
|
service. See demo/handler/h_wp.c to see how the different objects are
|
|
accessed for the WriteProperty service. If those are the only services
|
|
that you are going to use, then most of the work has been done other
|
|
than selecting which object types you are going to support.
|
|
|
|
As for how many of what object, see the individual object files for
|
|
examples of how that works (see demo/object directory). Also note that
|
|
there are optional properties of some objects that may or may not have
|
|
an example included in this demo code. For example, a Binary Value
|
|
object optionally includes a Priority_Array. There is an example in
|
|
the demo/object that includes a Priority_Array, and an example in
|
|
ports/pic18f6720 that does not have the Priority_Array.
|
|
|
|
You can read/write to the properties using demo/readprop and
|
|
demo/writeprop example client applications that run under Windows or
|
|
Linux command line.
|
|
|
|
Q-10: Since each Device object must have an object identifier that is
|
|
unique internetwork-wide, how is this ID determined?
|
|
|
|
A-10: Device object instance number is normally configured on site
|
|
after the device is installed. Therefore, the Device object instance
|
|
number should be configurable between 0 and 4194303 inclusive (see
|
|
bacdef.h for BACNET_MAX_INSTANCE). If your hardware does not have any
|
|
user interface, you can have the device default to 4194303 and
|
|
implement WriteProperty service to the Object_Identifier of the Device
|
|
object. You could also have some other method for configuring the
|
|
Device Object instance number such as an RS-232 terminal interface or
|
|
HTTP screen configuration like a home internet router.
|
|
|
|
Note that 4194303 is known as "unconfigured" and is not really a valid
|
|
device instance number. Also, all devices are required to respond with
|
|
their own Device object instance number when 4194303 is requested.
|
|
|
|
Q-11: For the objects supported by the device, they are required to be
|
|
unique within the BACnet device that maintains them. Can I start with
|
|
an object instance number of 0 or 1 and increment accordingly for each
|
|
new object created within the device?
|
|
|
|
A-11: For each object type, you can create any object instance numbers
|
|
between 0 and 4194302 inclusive. How you choose to number them is up
|
|
to you.
|
|
|
|
In the example object in demo/object/ I numbered them sequentially
|
|
starting at 0. If you do choose to use some other numbering scheme, be
|
|
sure to update the Index_To_Instance(), Valid_Instance(), Count(), and
|
|
Name() functions of each object type to correctly handle your
|
|
numbering scheme.
|
|
|
|
Q-12: For the object names, do you really use AV-## or ANALOG VALUE #
|
|
in your system? All of our AV values have unique names like
|
|
"ACTIVE_ALARM", "REVISION", "DUCT_STATIC".
|
|
|
|
A-12: As long as your names are unique in your device (i.e. no
|
|
duplicate names) you can use your names. In the demo objects, I just
|
|
use "AV-1" or "ANALOG VALUE 1" as the Object_Name where 1 is the
|
|
object instance number. Update the Name() function for each object
|
|
type if you change from the default names.
|
|
|
|
Q-13: I need to have about 100 Analog Value objects and 100 Binary
|
|
Value objects in my device. When I try to define over 15 objects I get
|
|
a memory error from the PIC compiler. What is the problem?
|
|
|
|
A-13: If you are using the unmodified Analog Value or Binary Value
|
|
objects from demo/objects, they include a priority array. That means
|
|
that each object has 16 Present_Values stored for each object, plus an
|
|
Out_Of_Service status. Each object would consume about 17 bytes.
|
|
15*17=255 bytes. Limit for udata = 255 bytes on the PIC using the
|
|
Microchip compiler.
|
|
|
|
Output and value objects are not required to have Out_Of_Service
|
|
writable. Value objects are not required to have a priority array. If
|
|
you need or want to have priority arrays for your objects, then you
|
|
might consider storing the Binary Value object Present_Value in some
|
|
smaller form (currently it is stored as enumeration which consumes a
|
|
byte on a PIC). There are Binary Value and Analog Value object
|
|
examples that do not include a priority array in the ports/pic18f6720/
|
|
directory.
|
|
|
|
Q-14: What do I have to do to reduce the size of the firmware made
|
|
from this BACnet stack?
|
|
|
|
A-14: Here are the things that you can do to shrink the firmware size:
|
|
|
|
1. For MS/TP, change the state machine to use a fixed memory
|
|
structure rather than a pointer to a structure. Some microcontroller
|
|
compilers generate more code when having to dereference the structure.
|
|
This limits you to a single MS/TP datalink.
|
|
2. Remove unused services by
|
|
* remove the service C file from the makefile
|
|
* remove the function call to setup the service
|
|
* remove the service handler
|
|
3. Remove unnecessary objects by:
|
|
* Remove the demo/object C file from the makefile
|
|
* remove function calls to the demo/object C file.
|
|
* Change the number of objects that you have.
|
|
* Only a Device object is required.
|
|
* Update the Device object
|
|
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED
|
|
4. Remove unused function calls by:
|
|
* #if 0 and #endif around the unused functions
|
|
(especially in bacdcode.c)
|
|
* Compile and Link. If the linker fails, then that
|
|
function was needed.
|
|
* Some compilers, like GCC, have garbage collection for
|
|
unused functions and code. If enabled, the linker will eliminate the
|
|
unused functions and code. Use the GCC compiler and linker directive
|
|
to enable this feature.
|
|
|
|
Q-15: I have downloaded the BACnet stack but can't get demo/server to
|
|
work. I am using a single computer. In one console window I run
|
|
demo/server/bacserv. In another console window I run demo/whois/bacwi.
|
|
When I capture packets with WireShark, I see the I-Am broadcast packet
|
|
being sent by demo/server/bacserv when it starts. I also see the
|
|
Who-Is broadcast packet sent by demo/whois/bacwi. But
|
|
demo/server/bacserv never receives any message. How do I make it work?
|
|
|
|
A-15: This is a common issue with BACnet/IP. The server application
|
|
binds to the BACnet/IP UDP port 47808 on that computer, and therefore,
|
|
the client application is unable to receive broadcast messages on port
|
|
47808 since those packets are only going to the server application.
|
|
|
|
The correct solution is to use BVLC (BACnet Virtual Link Control)
|
|
where the client applications use BACnet Foreign Device Registration,
|
|
and some application (probably the server) runs a BBMD (BACnet
|
|
Broadcast Management Device).
|
|
|
|
You can do one of the following:
|
|
|
|
1. Use QEMU or Bochs or VMWare or some other virtual machine to
|
|
simulate another computer, and run server or client on a virtual
|
|
computer.
|
|
2. Use the BACnet/IP BACnet Virtual Link Control (BVLC) features.
|
|
The client demo applications are configured to use environment
|
|
variables to establish a BBMD connection as a foreign device. Set the
|
|
BACNET_BBMD_PORT and BACNET_BBMD_ADDRESS of the BBMD. Note that the
|
|
demo/server application is configured as a BBMD.
|
|
3. Write npdu router code to route from BACnet/IP to another
|
|
datalink layer. Make server application on one datalink layer and make
|
|
client applications on another datalink layer.
|
|
4. Add external BACnet router or BACnet devices. Run a BACnet
|
|
demo/server on another PC.
|
|
|
|
Q-16: My Linux computer doesn't use eth0 for for the BACnet
|
|
connection. My Windows computer has more than one network connnection.
|
|
How can I choose the interface to use for the demo applications?
|
|
|
|
A-16: Set the environment variable BACNET_IFACE. For Windows, set
|
|
BACNET_IFACE=169.254.119.240 or whatever the address of the interface
|
|
returned by ipconfig command. For Linux, use BACNET_IFACE=eth0 or
|
|
whatever the name of the interface returned by the ifconfig command.
|
|
Setting the environment variable under Windows can be done on the
|
|
command line:
|
|
|
|
> set BACNET_IFACE=169.254.119.240
|
|
|
|
Setting the environment variable under Linux can be done from the
|
|
command line:
|
|
|
|
$ BACNET_IFACE=ath0
|
|
$ export BACNET_IFACE
|
|
|
|
Q-16: I need to communicate with an MS/TP Slave Node. Can I configure
|
|
the demo applications to use a static address binding?
|
|
|
|
A-16: Yes, static address binding is supported as of 0.4.3. Use a file
|
|
called address_cache (which is defined in src/address.c). The file
|
|
format is record based as follows:
|
|
;DeviceID MAC SNET SADR MAX-APDU
|
|
4194302 05 0 0 50
|
|
55555 C0:A8:00:18:BA:C0 26001 19 50
|