Getting the RTOS-32 port working again. Also getting the MS/TP state machine working. Soon!

This commit is contained in:
skarg
2006-08-23 21:32:16 +00:00
parent afea6e10bf
commit 52ee5a5619
18 changed files with 853 additions and 256 deletions
@@ -67,6 +67,7 @@ file_047=no
file_048=no
file_049=no
file_050=no
file_051=no
[FILE_INFO]
file_000=C:\code\bacnet-stack\abort.c
file_001=C:\code\bacnet-stack\apdu.c
@@ -119,6 +120,7 @@ file_047=C:\code\bacnet-stack\demo\object\ao.h
file_048=C:\code\bacnet-stack\demo\object\device.h
file_049=stdbool.h
file_050=stdint.h
file_051=hardware.h
[SUITE_INFO]
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
suite_state=
Binary file not shown.
+9 -20
View File
@@ -71,23 +71,17 @@ void My_Read_Property_Handler(uint8_t * service_request,
int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_NPDU_DATA npdu_data;
len = rp_decode_service_request(service_request, service_len, &data);
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* bad decoding - send an abort */
if (len == -1) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
if (len < 0) {
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, ABORT_REASON_OTHER);
send = true;
} else if (service_data->segmented_message) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
send = true;
} else {
switch (data.object_type) {
case OBJECT_DEVICE:
@@ -101,10 +95,7 @@ void My_Read_Property_Handler(uint8_t * service_request,
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
pdu_len +=
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
send = true;
pdu_len = rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], service_data->invoke_id, &data);
} else
error = true;
} else
@@ -116,15 +107,13 @@ void My_Read_Property_Handler(uint8_t * service_request,
}
}
if (error) {
pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
send = true;
}
if (send) {
bytes_sent = datalink_send_pdu(src, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
}
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
return;
}
+53 -25
View File
@@ -34,18 +34,17 @@
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include "bacdcode.h"
#include "bip.h"
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
static int interface = SOCKET_ERROR; /* SOCKET_ERROR means no open interface */
#endif
void bip_set_interface(char *ifname)
{
/*dummy function - to make the demos compile easier */
(void)ifname;
}
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
/*-----------------------------------*/
static void Error(const char *Msg)
{
@@ -70,7 +69,6 @@ void InterfaceCleanup(void)
#endif
}
}
#endif
static void NetInitialize(void)
/* initialize the TCP/IP stack */
@@ -78,16 +76,9 @@ static void NetInitialize(void)
int Result;
#ifndef HOST
RTKernelInit(0); /* get the kernel going */
if (!RTKDebugVersion()) /* switch of all diagnostics and error messages of RTIP-32 */
xn_callbacks()->cb_wr_screen_string_fnc = NULL;
CLKSetTimerIntVal(10 * 1000); /* 10 millisecond tick */
RTKDelay(1);
RTCMOSSetSystemTime(); /* get the right time-of-day */
#ifdef RTUSB_VER
RTURegisterCallback(USBAX172); /* ax172 and ax772 drivers */
RTURegisterCallback(USBAX772);
@@ -207,30 +198,67 @@ static void NetInitialize(void)
}
#endif
/******************************************************************
* DESCRIPTION: Converts the byte stored address to an inet address
* RETURN: none
* ALGORITHM: none
* NOTES: none
******************************************************************/
static void RTIP_To_Network_Address(
BYTE *octet_address,
struct in_addr *addr)
{
uint32_t ip_address = 0; /* for decoding the subnet mask */
decode_unsigned32(octet_address, &ip_address);
addr->s_addr = htonl(ip_address);
return;
}
static void set_broadcast_address(uint32_t net_address)
{
long broadcast_address = 0;
long mask = 0;
/* Note: sometimes INADDR_BROADCAST does not let me get
any unicast messages. Not sure why... */
#if USE_INADDR
(void) net_address;
bip_set_broadcast_addr(INADDR_BROADCAST);
#else
if (IN_CLASSA(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
else if (IN_CLASSB(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
else if (IN_CLASSC(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
else if (IN_CLASSD(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
else
broadcast_address = INADDR_BROADCAST;
bip_set_broadcast_addr(htonl(broadcast_address));
#endif
}
bool bip_init(void)
{
int rv = 0; /* return from socket lib calls */
struct sockaddr_in sin = { -1 };
int value = 1;
int sock_fd = -1;
struct in_addr my_addr;
NetInitialize();
bip_set_address(TargetIP[0], TargetIP[1], TargetIP[2], TargetIP[3]);
/* FIXME: */
#if 0
bip_set_address(NetMask[0], NetMask[1], NetMask[2], NetMask[3]);
extern unsigned long bip_get_addr(void);
unsigned long broadcast_address = 0;
unsigned long subnet_mask = 0;
/* local broadcast address */
broadcast_address = bip_get_addr();
broadcast_address |= ~(BIP_Subnet_Mask.s_addr);
/* configure standard BACnet/IP port */
RTIP_To_Network_Address(TargetIP, &my_addr);
bip_set_addr(my_addr.s_addr);
set_broadcast_address(my_addr.s_addr);
bip_set_port(0xBAC0);
#endif
/* assumes that the driver has already been initialized */
sock_fd = socket(AF_INET, SOCK_DGRAM, IPROTO_UDP);
+268
View File
@@ -0,0 +1,268 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#if PRINT_ENABLED
#include <stdio.h>
#endif
#include "bacdef.h"
#include "mstp.h"
#include "dlmstp.h"
#include "rs485.h"
#include "npdu.h"
/* receive buffer */
static DLMSTP_PACKET Receive_Buffer;
/* temp buffer for NPDU insertion */
static uint8_t PDU_Buffer[MAX_MPDU];
/* local MS/TP port data */
static volatile struct mstp_port_struct_t MSTP_Port;
void dlmstp_init(void)
{
/* initialize buffer */
Receive_Buffer.ready = false;
Receive_Buffer.pdu_len = 0;
/* initialize hardware */
RS485_Initialize();
MSTP_Init(&MSTP_Port, MSTP_Port.This_Station);
}
void dlmstp_cleanup(void)
{
/* nothing to do for static buffers */
}
/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
int bytes_sent = 0;
unsigned npdu_len = 0;
uint8_t frame_type = 0;
uint8_t destination = 0; /* destination address */
BACNET_ADDRESS src;
if (MSTP_Port.TxReady == false) {
if (npdu_data->confirmed_message)
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
else
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
/* load destination MAC address */
if (dest && dest->mac_len == 1) {
destination = dest->mac[0];
} else {
#if PRINT_ENABLED
fprintf(stderr, "mstp: invalid destination MAC address!\n");
#endif
return -2;
}
dlmstp_get_my_address(&src);
npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data);
if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) {
#if PRINT_ENABLED
fprintf(stderr, "mstp: PDU is too big to send!\n");
#endif
return -4;
}
memmove(&PDU_Buffer[npdu_len], pdu, pdu_len);
bytes_sent = MSTP_Create_Frame(
(uint8_t *)&MSTP_Port.TxBuffer[0],
sizeof(MSTP_Port.TxBuffer),
MSTP_Port.TxFrameType,
destination,
MSTP_Port.This_Station,
&PDU_Buffer[0],
npdu_len + pdu_len);
MSTP_Port.TxLength = bytes_sent;
MSTP_Port.TxReady = true;
}
return bytes_sent;
}
void dlmstp_task(void)
{
RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port);
MSTP_Master_Node_FSM(&MSTP_Port);
}
/* called about once a millisecond */
void dlmstp_millisecond_timer(void)
{
MSTP_Millisecond_Timer(&MSTP_Port);
}
/* returns the number of octets in the PDU, or zero on failure */
/* This function is expecting to be polled. */
uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{
uint16_t pdu_len = 0;
(void) timeout;
/* see if there is a packet available */
if (Receive_Buffer.ready)
{
memmove(src, &Receive_Buffer.address, sizeof(Receive_Buffer.address));
pdu_len = Receive_Buffer.pdu_len;
memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu);
Receive_Buffer.ready = false;
}
return pdu_len;
}
void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src, uint8_t mstp_address)
{
int i = 0;
if (mstp_address == MSTP_BROADCAST_ADDRESS)
{
/* mac_len = 0 if broadcast address */
src->mac_len = 0;
src->mac[0] = 0;
}
else
{
src->mac_len = 1;
src->mac[0] = mstp_address;
}
/* fill with 0's starting with index 1; index 0 filled above */
for (i = 1; i <MAX_MAC_LEN; i++) {
src->mac[i] = 0;
}
src->net = 0;
src->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
src->adr[i] = 0;
}
}
/* for the MS/TP state machine to use for putting received data */
uint16_t dlmstp_put_receive(
uint8_t src, /* source MS/TP address */
uint8_t * pdu, /* PDU data */
uint16_t pdu_len)
{
if (Receive_Buffer.ready)
{
/* FIXME: what to do when we miss a message? */
pdu_len = 0;
}
else
{
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
Receive_Buffer.pdu_len = pdu_len;
memmove(Receive_Buffer.pdu, pdu, sizeof(Receive_Buffer.pdu));
Receive_Buffer.ready = true;
}
return pdu_len;
}
void dlmstp_set_my_address(uint8_t mac_address)
{
/* FIXME: Master Nodes can only have address 1-127 */
MSTP_Port.This_Station = mac_address;
return;
}
/* This parameter represents the value of the Max_Info_Frames property of */
/* the node's Device object. The value of Max_Info_Frames specifies the */
/* maximum number of information frames the node may send before it must */
/* pass the token. Max_Info_Frames may have different values on different */
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(unsigned max_info_frames)
{
MSTP_Port.Nmax_info_frames = max_info_frames;
return;
}
unsigned dlmstp_max_info_frames(void)
{
return MSTP_Port.Nmax_info_frames;
}
/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(uint8_t max_master)
{
MSTP_Port.Nmax_master = max_master;
return;
}
uint8_t dlmstp_max_master(void)
{
return MSTP_Port.Nmax_master;
}
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0; /* counter */
my_address->mac_len = 1;
my_address->mac[0] = MSTP_Port.This_Station;
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
}
return;
}
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac_len = 1;
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* len=0 denotes broadcast address */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
+15
View File
@@ -34,6 +34,7 @@
#include <windows.h>
#include "ethernet.h"
#include "bacdcode.h"
#include "npdu.h"
/* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
@@ -86,12 +87,14 @@ bool ethernet_init(char *interface_name)
/* returns bytes sent on success, negative number on failure */
int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
BACNET_ADDRESS * src, /* source address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
int bytes = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
int npdu_len = 0;
int i = 0;
/* don't waste time if the socket is not valid */
@@ -131,8 +134,16 @@ int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
mtu[mtu_len++] = 0x82; /* DSAP for BACnet */
mtu[mtu_len++] = 0x82; /* SSAP for BACnet */
mtu[mtu_len++] = 0x03; /* Control byte in header */
npdu_len = npdu_encode_pdu(&mtu[17], dest, src, npdu_data);
mtu_len = 17 + npdu_len;
if ((mtu_len + pdu_len) > MAX_MPDU) {
fprintf(stderr, "ethernet: PDU is too big to send!\n");
return -4;
}
memcpy(&mtu[mtu_len], pdu, pdu_len);
mtu_len += pdu_len;
/* packet length - only the logical portion, not the address */
encode_unsigned16(&mtu[12], 3 + npdu_len + pdu_len);
/* Send the packet */
bytes = send(Ethernet_Socket, (const char *) &mtu, mtu_len, 0);
@@ -147,6 +158,7 @@ int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
/* function to send a packet out the 802.2 socket */
/* returns bytes sent on success, negative number on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
@@ -157,10 +169,13 @@ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* FIXME: npdu_data? */
/* function to send a packet out the 802.2 socket */
/* returns 1 on success, 0 on failure */
return ethernet_send(dest, /* destination address */
&src, /* source address */
npdu_data,
pdu, /* any data to be sent - may be null */
pdu_len); /* number of bytes of data */
}
+90 -30
View File
@@ -28,35 +28,106 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <conio.h> /* for kbhit */
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "handlers.h"
#include "net.h"
#include "datalink.h"
#include "iam.h"
#include "txbuf.h"
/* RTOS-32 */
#include "rtkernel.h"
#if defined(RTK32_VER)
#define _USER32_
#define _KERNEL32_
#include <windows.h>
#include <rttarget.h> /* for RTCMOSSetSystemTime */
#include <rtfiles.h> /* file system */
#include <rtfsys.h> /* file system */
#include <Rttbios.h>
#endif
#include <rtcom.h> /* serial port driver */
#include <itimer.h> /* time measurement & timer interrupt rate control */
#include <rtkeybrd.h> /* interrupt handler for the keyboard */
/* buffers used for transmit and receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
#ifdef BACDL_MSTP
volatile struct mstp_port_struct_t MSTP_Port; /* port data */
static uint8_t MSTP_MAC_Address = 0x05; /* local MAC address */
#endif
static void Init_Service_Handlers(void)
{
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, WhoIsHandler);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* 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
(UnrecognizedServiceHandler);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
ReadPropertyHandler);
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
WritePropertyHandler);
handler_write_property);
}
void millisecond_task(void)
{
Time ticks = 0; /* task cycle */
const int UPDATE_CYCLE = 5; /* task cycle in mS */
int i = 0; /* loop counter */
ticks = RTKGetTime() + MilliSecsToTicks(UPDATE_CYCLE);
while (TRUE)
{
RTKDelayUntil(ticks);
for (i = 0; i < UPDATE_CYCLE; i++)
dlmstp_millisecond_timer();
ticks += MilliSecsToTicks(UPDATE_CYCLE);
}
}
void RTOS_Initialize(void)
{
/* allow OS to setup IRQ 1 by using a dummy call */
(void)kbhit();
RTKernelInit(0); /* get the kernel going */
RTKeybrdInit();
//(void)CPUMoniInit(); /* not needed - just monitor idle task */
RTComInit();
ITimerInit();
if (RTCallDebugger(RT_DBG_MONITOR,0,0) != -1)
{
/* Win32 structured exception - if no handler is
installed, TerminateProcess() will be called,
which will reboot - a good thing in our case. */
RTRaiseCPUException(0); // Divide Error DIV and IDIV instructions.
RTRaiseCPUException(1); // Debug Any code or data reference.
RTRaiseCPUException(2); // NMI
RTRaiseCPUException(3); // Breakpoint INT 3 instruction.
RTRaiseCPUException(4); // Overflow INTO instruction.
RTRaiseCPUException(5); // BOUND Range Exceeded BOUND instruction.
RTRaiseCPUException(6); // Invalid Opcode (Undefined Opcode)
// RTRaiseCPUException(7); // Device Not Available (No Math Coprocessor)
RTRaiseCPUException(8); // Double Fault any exception instruction,NMI,INTR.
RTRaiseCPUException(9); // Co-Processor overrun
RTRaiseCPUException(10); // Invalid TSS Task switch or TSS access.
RTRaiseCPUException(11); // Segment Not Present Loading segment registers
RTRaiseCPUException(12); // Stack Seg Fault Stack ops /SS reg loads.
RTRaiseCPUException(13); // General Protection Any memory reference
RTRaiseCPUException(14); // Page Fault Any memory reference.
RTRaiseCPUException(15); // reserved
RTRaiseCPUException(16); // Floating-Point Error (Math Fault)
}
/* setup 1ms timer tick */
SetTimerIntVal(1000);
/* per recommendation in manual */
RTKDelay(1);
RTCMOSSetSystemTime(); /* get the right time-of-day */
/* create timer tick task */
RTKCreateTask(millisecond_task,1,1024*8,"millisec task");
}
int main(int argc, char *argv[])
@@ -69,6 +140,7 @@ int main(int argc, char *argv[])
(void) argv;
Device_Set_Object_Instance_Number(126);
Init_Service_Handlers();
RTOS_Initialize();
/* init the physical layer */
#ifdef BACDL_BIP
if (!bip_init())
@@ -79,39 +151,27 @@ int main(int argc, char *argv[])
return 1;
#endif
#ifdef BACDL_MSTP
RS485_Initialize();
MSTP_Init(&MSTP_Port, MSTP_MAC_Address);
dlmstp_set_my_address(0x05);
dlmstp_init();
#endif
iam_send(&Handler_Transmit_Buffer[0]);
/* loop forever */
for (;;) {
/* input */
#ifdef BACDL_MSTP
MSTP_Millisecond_Timer(&MSTP_Port);
/* note: also called by RS-485 Receive ISR */
RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port);
dlmstp_task();
#endif
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
/* returns 0 bytes on timeout */
pdu_len = bacdl_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
#endif
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (I_Am_Request) {
I_Am_Request = false;
Send_IAm();
}
/* output */
#ifdef BACDL_MSTP
MSTP_Master_Node_FSM(&MSTP_Port);
#endif
/* blink LEDs, Turn on or off outputs, etc */
}
+32 -7
View File
@@ -22,19 +22,36 @@ PRODUCT_RTB = $(PRODUCT).rtb
PRODUCT_EXE = $(PRODUCT).exe
# Choose the Data Link Layer to Enable
DEFINES = -DDOC;BACDL_BIP=1
#DEFINES = -DDOC;BACDL_ETHERNET=1
#DEFINES = -DDOC;BACDL_MSTP=1
#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_BIP=1
#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_ETHERNET=1
#DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_ARCNET=1
DEFINES = -DDOC;BIG_ENDIAN=0;TSM_ENABLED=1;PRINT_ENABLED=1;BACDL_MSTP=1
SRCS = init.c main.c ethernet.c bip-init.c \
rs485.c \
SRCS = main.c \
ethernet.c \
bip-init.c \
dlmstp.c \
rs485.c \
init.c \
..\..\bip.c \
..\..\mstp.c \
..\..\crc.c \
..\..\handlers.c \
..\..\demo\handler\h_iam.c \
..\..\demo\handler\h_whois.c \
..\..\demo\handler\h_wp.c \
..\..\demo\handler\h_rp.c \
..\..\demo\handler\noserv.c \
..\..\demo\handler\txbuf.c \
..\..\demo\handler\s_rp.c \
..\..\demo\handler\s_whois.c \
..\..\bacdcode.c \
..\..\bacstr.c \
..\..\bactext.c \
..\..\indtext.c \
..\..\bacapp.c \
..\..\bigend.c \
..\..\whois.c \
..\..\dcc.c \
..\..\iam.c \
..\..\rp.c \
..\..\wp.c \
@@ -44,6 +61,12 @@ SRCS = init.c main.c ethernet.c bip-init.c \
..\..\demo\object\device.c \
..\..\demo\object\ai.c \
..\..\demo\object\ao.c \
..\..\demo\object\av.c \
..\..\demo\object\bi.c \
..\..\demo\object\bo.c \
..\..\demo\object\bv.c \
..\..\demo\object\lsp.c \
..\..\demo\object\mso.c \
..\..\datalink.c \
..\..\tsm.c \
..\..\address.c \
@@ -59,6 +82,7 @@ OBJS = $(SRCS:.c=.obj)
#
CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg
LINK = $(BORLAND_DIR)\bin\tlink32
#LINK = $(BORLAND_DIR)\bin\ilink32
TLIB = $(BORLAND_DIR)\bin\tlib
LOCATE = $(RTOS32_DIR)\bin\rtloc
@@ -66,7 +90,7 @@ LOCATE = $(RTOS32_DIR)\bin\rtloc
# Include directories
#
CC_DIR = $(BORLAND_DIR)\BIN
INCL_DIRS = -I$(BORLAND_DIR)\include;$(RTOS32_DIR)\include;..\..\;.
INCL_DIRS = -I$(BORLAND_DIR)\include;$(RTOS32_DIR)\include;..\..\;..\..\demo\handler\;..\..\demo\object\;.
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
@@ -156,6 +180,7 @@ bcc32.cfg :
Copy &&|
$(CFLAGS)
-c
#-g2 #stop after gN warnings
-y #include line numbers in OBJ's
-v #include debug info
-w+ #turn on all warnings
+31 -2
View File
@@ -34,18 +34,47 @@
#include <stdlib.h>
#include <process.h>
#ifdef BACDL_BIP
#include "bip.h"
#ifndef HOST
#include <rtipapi.h>
#include "netcfg.h"
#include <rttarget.h>
#include <rtk32.h>
#include <clock.h>
#include <socket.h>
/*
* Definitions of bits in internet address integers.
* On subnets, the decomposition of addresses to host and net parts
* is done according to subnet mask, not the masks here.
*/
#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
#define IN_CLASSA_NET 0xff000000
#define IN_CLASSA_NSHIFT 24
#define IN_CLASSA_HOST 0x00ffffff
#define IN_CLASSA_MAX 128
#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
#define IN_CLASSB_NET 0xffff0000
#define IN_CLASSB_NSHIFT 16
#define IN_CLASSB_HOST 0x0000ffff
#define IN_CLASSB_MAX 65536
#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
#define IN_CLASSC_NET 0xffffff00
#define IN_CLASSC_NSHIFT 8
#define IN_CLASSC_HOST 0x000000ff
#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */
#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */
#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */
#define IN_MULTICAST(i) IN_CLASSD(i)
#else
#include <winsock.h>
#endif
#define close closesocket
#endif
typedef size_t socklen_t;
#endif
+4 -4
View File
@@ -34,10 +34,10 @@
#if defined(AUTO_IP) /* use xn_autoip() to get an IP address */
static BYTE TargetIP[] = { 0, 0, 0, 0 }; /* will be filled at run-time */
static BYTE NetMask[] = { 255, 255, 255, 0 };
static BYTE MinIP[] = { 192, 168, 1, 128 };
static BYTE MaxIP[] = { 192, 168, 1, 255 };
static BYTE DefaultGateway[] = { 192, 168, 1, 1 }; /* set to zero if not available or required */
static BYTE DNSServer[] = { 192, 168, 1, 1 }; /* ditto */
static BYTE MinIP[] = { 192, 168, 0, 128 };
static BYTE MaxIP[] = { 192, 168, 0, 255 };
static BYTE DefaultGateway[] = { 192, 168, 0, 1 }; /* set to zero if not available or required */
static BYTE DNSServer[] = { 192, 168, 0, 1 }; /* ditto */
#elif defined(DHCP) /* use DHCP */
#include <dhcpcapi.h>
static BYTE TargetIP[] = { 0, 0, 0, 0 }; /* will be filled at run-time */
+39 -5
View File
@@ -27,6 +27,9 @@
#include <rtkernel.h>
#include <rtcom.h>
#include <itimer.h>
#if PRINT_ENABLED
#include <stdio.h>
#endif
#include "mstp.h"
/* note: use the RTKernel-C API so that it can use this library */
@@ -69,11 +72,29 @@ static void RS485_Standard_Port_Settings(long port, long *pIRQ,
}
}
static int TestCOMPort(
int Base)/* base address of UART */
{
int i;
for (i=0; i<256; i++)
{
RTOut(Base+7, (BYTE)i); // write scratch register
RTOut(Base+1, RTIn(Base+1)); // read/write IER
if (RTIn(Base+7) != i) // check scratch register
return FALSE;
}
return TRUE;
}
static RS485_Open_Port(int port, /* COM port number - COM1 = 0 */
long baud, /* baud rate */
unsigned base, /* io base address */
int irq)
{ /* hardware IRQ number */
if (!TestCOMPort(base))
return;
/* setup the COM IO */
SetIOBase(port, base);
SetIRQ(port, irq);
@@ -90,6 +111,9 @@ static RS485_Open_Port(int port, /* COM port number - COM1 = 0 */
/* enable the 485 via the DTR pin */
RS485_IO_ENABLE(port);
RS485_RECEIVE_ENABLE(port);
#if PRINT_ENABLED
fprintf(stderr,"RS485: COM%d Enabled\r\n",port+1);
#endif
return;
}
@@ -115,6 +139,21 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
RTKScheduler();
RS485_RECEIVE_ENABLE(RS485_Port);
#if PRINT_ENABLED
{
int i = 0;
fprintf(stderr,"RS485 Tx:");
for (i = 0; i < nbytes; i++)
{
fprintf(stderr," %02X",buffer[i]);
if ((!(i%20)) && (i != 0))
{
fprintf(stderr,"\r\n ");
}
}
fprintf(stderr,"\r\n");
}
#endif
return;
}
@@ -147,8 +186,3 @@ void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
}
}
}
void RS485_Process_Tx_Message(void)
{
/* nothing to do */
}
+1 -1
View File
@@ -15,7 +15,7 @@ PRODUCT = bacnet
PRODUCT_EXE = $(PRODUCT).exe
# Choose the Data Link Layer to Enable
DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1
DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1;BIG_ENDIAN=0
SRCS = main.c bip-init.c \
..\..\bip.c \