diff --git a/bacnet-stack/ports/atmega168/Makefile b/bacnet-stack/ports/atmega168/Makefile
index 8a485445..81189598 100644
--- a/bacnet-stack/ports/atmega168/Makefile
+++ b/bacnet-stack/ports/atmega168/Makefile
@@ -36,6 +36,7 @@ BACNET_DEMO = ../../demo
# local files for this project
CSRC = main.c \
timer.c \
+ stack.c \
rs485.c \
dlmstp.c \
apdu.c \
diff --git a/bacnet-stack/ports/atmega168/bacnet.ewp b/bacnet-stack/ports/atmega168/bacnet.ewp
index 7c8d20a3..bf0d3369 100644
--- a/bacnet-stack/ports/atmega168/bacnet.ewp
+++ b/bacnet-stack/ports/atmega168/bacnet.ewp
@@ -2032,6 +2032,9 @@
$PROJ_DIR$\timer.c
+
+ $PROJ_DIR$\stack.c
+
$PROJ_DIR$\timer.h
diff --git a/bacnet-stack/ports/atmega168/device.c b/bacnet-stack/ports/atmega168/device.c
index 62dc0dfb..c291e3f7 100644
--- a/bacnet-stack/ports/atmega168/device.c
+++ b/bacnet-stack/ports/atmega168/device.c
@@ -34,6 +34,7 @@
#include "dlmstp.h"
#include "rs485.h"
#include "version.h"
+#include "stack.h"
/* objects */
#include "device.h"
#include "av.h"
@@ -160,11 +161,6 @@ bool Device_Object_List_Identifier(
return status;
}
-#if defined(__GNUC__)
-extern uint8_t _end;
-extern uint8_t __stack;
-#endif
-
/* return the length of the apdu encoded or -1 for error */
int Device_Encode_Property_APDU(
uint8_t * apdu,
@@ -326,43 +322,12 @@ int Device_Encode_Property_APDU(
apdu_len =
encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate());
break;
-#if defined(__GNUC__)
case 512:
- count = 1 + (&__stack) - (&_end);
- if (array_index == 0) {
- /* Array element zero is the number of bytes of stack */
- apdu_len = encode_application_unsigned(&apdu[0], count);
- } else if (array_index == BACNET_ARRAY_ALL) {
- /* if no index was specified, then try to encode the entire list */
- /* into one packet. Note that more than likely you will have */
- /* to return an error if the number of encoded objects exceeds */
- /* your maximum APDU size. */
- for (i = 1; i <= count; i++) {
- len = encode_application_unsigned(&apdu[0], *(&_end + i));
- apdu_len += len;
- /* assume next one is the same size as this one */
- /* can we all fit into the APDU? */
- if ((apdu_len + len) >= MAX_APDU) {
- *error_class = ERROR_CLASS_SERVICES;
- *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
- apdu_len = -1;
- break;
- }
- }
- } else if (array_index <= count) {
- apdu_len =
- encode_application_unsigned(&apdu[0],
- *(&_end + array_index));
- } else {
- *error_class = ERROR_CLASS_PROPERTY;
- *error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
- apdu_len = -1;
- }
+ apdu_len = encode_application_unsigned(&apdu[0], stack_size());
break;
case 513:
- apdu_len = encode_application_unsigned(&apdu[0], __stack);
+ apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
break;
-#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
diff --git a/bacnet-stack/ports/atmega168/main.c b/bacnet-stack/ports/atmega168/main.c
index b2010855..8672f4e2 100644
--- a/bacnet-stack/ports/atmega168/main.c
+++ b/bacnet-stack/ports/atmega168/main.c
@@ -139,34 +139,6 @@ static void input_switch_read(
}
}
-/* stack checking */
-#if defined(__GNUC__)
-extern uint8_t _end;
-extern uint8_t __stack;
-#define STACK_CANARY (0xC5)
-void StackPaint(
- void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
-
-void StackPaint(
- void)
-{
-#if 0
- uint8_t *p = &_end;
-
- while (p <= &__stack) {
- *p = STACK_CANARY;
- p++;
- }
-#else
- __asm volatile (
- " ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
- " ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
- " st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
- " cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
-#endif
-}
-#endif
-
static uint8_t PDUBuffer[MAX_MPDU];
int main(
void)
diff --git a/bacnet-stack/ports/atmega168/stack.c b/bacnet-stack/ports/atmega168/stack.c
new file mode 100644
index 00000000..217e3452
--- /dev/null
+++ b/bacnet-stack/ports/atmega168/stack.c
@@ -0,0 +1,94 @@
+/**************************************************************************
+*
+* Copyright (C) 2009 Steve Karg
+*
+* 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 "hardware.h"
+
+/* stack checking */
+#if defined(__GNUC__)
+extern uint8_t _end;
+extern uint8_t __stack;
+#endif
+
+#if defined(__GNUC__)
+#define STACK_CANARY (0xC5)
+void stack_init(
+ void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
+#endif
+
+void stack_init(
+ void)
+{
+#if defined(__GNUC__)
+#if 0
+ uint8_t *p = &_end;
+
+ while (p <= &__stack) {
+ *p = STACK_CANARY;
+ p++;
+ }
+#else
+ __asm volatile (
+ " ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
+ " ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
+ " st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
+ " cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
+#endif
+#endif
+}
+
+unsigned stack_size(void)
+{
+#if defined(__GNUC__)
+ return (&__stack) - (&_end);
+#else
+ return 0;
+#endif
+}
+
+uint8_t stack_byte(unsigned offset)
+{
+#if defined(__GNUC__)
+ return *(&_end + offset);
+#else
+ offset = offset;
+ return 0;
+#endif
+}
+
+unsigned stack_unused(void)
+{
+ unsigned count = 0;
+#if defined(__GNUC__)
+ uint8_t *p = &_end;
+
+ while (p <= &__stack) {
+ if ((*p) != STACK_CANARY) {
+ count = p - (&_end);
+ break;
+ }
+ p++;
+ }
+#endif
+ return count;
+}
diff --git a/bacnet-stack/ports/atmega168/stack.h b/bacnet-stack/ports/atmega168/stack.h
new file mode 100644
index 00000000..cf97bb7f
--- /dev/null
+++ b/bacnet-stack/ports/atmega168/stack.h
@@ -0,0 +1,48 @@
+/**************************************************************************
+*
+* Copyright (C) 2009 Steve Karg
+*
+* 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.
+*
+*********************************************************************/
+#ifndef STACK_H
+#define STACK_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ /* C stack checking */
+ void stack_init(void);
+
+ unsigned stack_size(void);
+
+ uint8_t stack_byte(unsigned offset);
+
+ unsigned stack_unused(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
+
\ No newline at end of file