Improved BACnet Development Kit object handling and storing to SEEPROM and EEPROM. Added device property to check C-Stack size and amount unused.
This commit is contained in:
@@ -396,7 +396,7 @@ typedef enum {
|
||||
BINARY_INACTIVE = 0,
|
||||
BINARY_ACTIVE = 1,
|
||||
MAX_BINARY_PV = 1, /* for validating incoming values */
|
||||
BINARY_NULL = 2 /* our homemade way of storing this info */
|
||||
BINARY_NULL = 255 /* our homemade way of storing this info */
|
||||
} BACNET_BINARY_PV;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -40,6 +40,7 @@ BACNET_DEMO = ../../demo
|
||||
# local files for this project
|
||||
CSRC = main.c \
|
||||
init.c \
|
||||
stack.c \
|
||||
input.c \
|
||||
serial.c \
|
||||
rs485.c \
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "bacenum.h"
|
||||
#include "config.h"
|
||||
|
||||
/* Analog Input = Photocell */
|
||||
/* Analog Input */
|
||||
#define MAX_ANALOG_INPUTS 2
|
||||
#if (MAX_ANALOG_INPUTS > 9)
|
||||
#error Modify the Analog_Input_Name to handle multiple digits
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "led.h"
|
||||
#include "nvdata.h"
|
||||
|
||||
#define MAX_BINARY_OUTPUTS 2
|
||||
#if (MAX_BINARY_OUTPUTS > 9)
|
||||
@@ -44,13 +45,13 @@
|
||||
/* the Relinquish Default value */
|
||||
#define RELINQUISH_DEFAULT BINARY_INACTIVE
|
||||
/* Here is our Priority Array.*/
|
||||
static BACNET_BINARY_PV
|
||||
static uint8_t
|
||||
Binary_Output_Level[MAX_BINARY_OUTPUTS][BACNET_MAX_PRIORITY];
|
||||
/* Writable out-of-service allows others to play with our Present Value */
|
||||
/* without changing the physical output */
|
||||
static bool Binary_Output_Out_Of_Service[MAX_BINARY_OUTPUTS];
|
||||
static uint8_t Out_Of_Service[MAX_BINARY_OUTPUTS];
|
||||
/* polarity - normal or inverse */
|
||||
static BACNET_POLARITY Polarity[MAX_BINARY_OUTPUTS];
|
||||
static uint8_t Polarity[MAX_BINARY_OUTPUTS];
|
||||
|
||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||
static const int Binary_Output_Properties_Required[] = {
|
||||
@@ -93,24 +94,51 @@ void Binary_Output_Property_Lists(
|
||||
return;
|
||||
}
|
||||
|
||||
void Binary_Output_Init(
|
||||
void)
|
||||
void Binary_Output_Level_Set(
|
||||
unsigned int object_index,
|
||||
unsigned int priority,
|
||||
BACNET_BINARY_PV level)
|
||||
{
|
||||
unsigned i, j;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
|
||||
/* initialize all the analog output priority arrays to NULL */
|
||||
for (i = 0; i < MAX_BINARY_OUTPUTS; i++) {
|
||||
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
|
||||
Binary_Output_Level[i][j] = BINARY_NULL;
|
||||
}
|
||||
if (object_index < MAX_BINARY_OUTPUTS) {
|
||||
if (priority < BACNET_MAX_PRIORITY) {
|
||||
Binary_Output_Level[object_index][priority] = (uint8_t)level;
|
||||
seeprom_bytes_write(
|
||||
NV_SEEPROM_BINARY_OUTPUT(object_index,
|
||||
NV_SEEPROM_BO_PRIORITY_ARRAY_1+priority),
|
||||
&Binary_Output_Level[object_index][priority],
|
||||
1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
void Binary_Output_Polarity_Set(
|
||||
unsigned int object_index,
|
||||
BACNET_POLARITY polarity)
|
||||
{
|
||||
if (object_index < MAX_BINARY_OUTPUTS) {
|
||||
if (polarity < MAX_POLARITY) {
|
||||
Polarity[object_index] = POLARITY_NORMAL;
|
||||
seeprom_bytes_write(
|
||||
NV_SEEPROM_BINARY_OUTPUT(object_index,
|
||||
NV_SEEPROM_BO_POLARITY),
|
||||
&Polarity[object_index],
|
||||
1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Binary_Output_Out_Of_Service_Set(
|
||||
unsigned int object_index,
|
||||
bool flag)
|
||||
{
|
||||
if (object_index < MAX_BINARY_OUTPUTS) {
|
||||
Out_Of_Service[object_index] = flag;
|
||||
seeprom_bytes_write(
|
||||
NV_SEEPROM_BINARY_OUTPUT(object_index,
|
||||
NV_SEEPROM_BO_OUT_OF_SERVICE),
|
||||
&Out_Of_Service[object_index],
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
/* we simply have 0-n object instances. */
|
||||
@@ -153,14 +181,15 @@ static BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
|
||||
BACNET_BINARY_PV current_value = RELINQUISH_DEFAULT;
|
||||
unsigned index = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
Binary_Output_Init();
|
||||
index = Binary_Output_Instance_To_Index(object_instance);
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||
if (Binary_Output_Level[index][i] != BINARY_NULL) {
|
||||
current_value = Binary_Output_Level[index][i];
|
||||
if (current_value != BINARY_NULL) {
|
||||
value = Binary_Output_Level[index][i];
|
||||
break;
|
||||
}
|
||||
@@ -177,7 +206,7 @@ static void Binary_Output_Sync(
|
||||
unsigned index = Binary_Output_Instance_To_Index(object_instance);
|
||||
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
if (Binary_Output_Out_Of_Service[index]) {
|
||||
if (Out_Of_Service[index]) {
|
||||
return;
|
||||
}
|
||||
if (Polarity[index] == POLARITY_REVERSE) {
|
||||
@@ -240,7 +269,6 @@ int Binary_Output_Encode_Property_APDU(
|
||||
unsigned i = 0;
|
||||
bool state = false;
|
||||
|
||||
Binary_Output_Init();
|
||||
switch (property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
@@ -280,7 +308,7 @@ int Binary_Output_Encode_Property_APDU(
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
object_index = Binary_Output_Instance_To_Index(object_instance);
|
||||
state = Binary_Output_Out_Of_Service[object_index];
|
||||
state = Out_Of_Service[object_index];
|
||||
apdu_len = encode_application_boolean(&apdu[0], state);
|
||||
break;
|
||||
case PROP_POLARITY:
|
||||
@@ -299,10 +327,10 @@ int Binary_Output_Encode_Property_APDU(
|
||||
Binary_Output_Instance_To_Index(object_instance);
|
||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||
/* FIXME: check if we have room before adding it to APDU */
|
||||
if (Binary_Output_Level[object_index][i] == BINARY_NULL)
|
||||
present_value = Binary_Output_Level[object_index][i];
|
||||
if (present_value == BINARY_NULL) {
|
||||
len = encode_application_null(&apdu[apdu_len]);
|
||||
else {
|
||||
present_value = Binary_Output_Level[object_index][i];
|
||||
} else {
|
||||
len =
|
||||
encode_application_enumerated(&apdu[apdu_len],
|
||||
present_value);
|
||||
@@ -321,12 +349,11 @@ int Binary_Output_Encode_Property_APDU(
|
||||
object_index =
|
||||
Binary_Output_Instance_To_Index(object_instance);
|
||||
if (array_index <= BACNET_MAX_PRIORITY) {
|
||||
if (Binary_Output_Level[object_index][array_index] ==
|
||||
BINARY_NULL)
|
||||
present_value =
|
||||
Binary_Output_Level[object_index][array_index];
|
||||
if (present_value == BINARY_NULL) {
|
||||
len = encode_application_null(&apdu[apdu_len]);
|
||||
else {
|
||||
present_value =
|
||||
Binary_Output_Level[object_index][array_index];
|
||||
} else {
|
||||
len =
|
||||
encode_application_enumerated(&apdu[apdu_len],
|
||||
present_value);
|
||||
@@ -400,7 +427,7 @@ bool Binary_Output_Write_Property(
|
||||
(value.type.Enumerated <= MAX_BINARY_PV)) {
|
||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||
priority--;
|
||||
Binary_Output_Level[object_index][priority] = level;
|
||||
Binary_Output_Level_Set(object_index, priority,level);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
status = true;
|
||||
} else if (priority == 6) {
|
||||
@@ -418,9 +445,15 @@ bool Binary_Output_Write_Property(
|
||||
priority = wp_data->priority;
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
Binary_Output_Level[object_index][priority] = level;
|
||||
Binary_Output_Level_Set(object_index, priority,level);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
status = true;
|
||||
} else if (priority == 6) {
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
algorithm and may not be used for other purposes in any
|
||||
object. */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -432,8 +465,8 @@ bool Binary_Output_Write_Property(
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||
Binary_Output_Out_Of_Service[object_index] =
|
||||
value.type.Boolean;
|
||||
Binary_Output_Out_Of_Service_Set(object_index,
|
||||
value.type.Boolean);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
status = true;
|
||||
} else {
|
||||
@@ -443,9 +476,11 @@ bool Binary_Output_Write_Property(
|
||||
break;
|
||||
case PROP_POLARITY:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
|
||||
if (value.type.Enumerated <= MAX_POLARITY) {
|
||||
Polarity[object_index] =
|
||||
(BACNET_POLARITY)value.type.Enumerated;
|
||||
if (value.type.Enumerated < MAX_POLARITY) {
|
||||
Binary_Output_Polarity_Set(object_index,
|
||||
value.type.Enumerated);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
@@ -463,3 +498,37 @@ bool Binary_Output_Write_Property(
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void Binary_Output_Init(
|
||||
void)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
/* initialize all the analog output priority arrays to NULL */
|
||||
for (i = 0; i < MAX_BINARY_OUTPUTS; i++) {
|
||||
seeprom_bytes_read(
|
||||
NV_SEEPROM_BINARY_OUTPUT(i,NV_SEEPROM_BO_POLARITY),
|
||||
&Polarity[i],
|
||||
1);
|
||||
if (Polarity[i] >= MAX_POLARITY) {
|
||||
Binary_Output_Polarity_Set(i, POLARITY_NORMAL);
|
||||
}
|
||||
seeprom_bytes_read(
|
||||
NV_SEEPROM_BINARY_OUTPUT(i,NV_SEEPROM_BO_OUT_OF_SERVICE),
|
||||
&Out_Of_Service[i],
|
||||
1);
|
||||
if (Out_Of_Service[i] > 1) {
|
||||
Binary_Output_Out_Of_Service_Set(i, false);
|
||||
}
|
||||
for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
|
||||
seeprom_bytes_read(
|
||||
NV_SEEPROM_BINARY_OUTPUT(i,
|
||||
NV_SEEPROM_BO_PRIORITY_ARRAY_1+j),
|
||||
&Binary_Output_Level[i][j],
|
||||
1);
|
||||
}
|
||||
Binary_Output_Sync(i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "rs485.h"
|
||||
#include "version.h"
|
||||
#include "nvdata.h"
|
||||
#include "stack.h"
|
||||
/* objects */
|
||||
#include "device.h"
|
||||
#include "ai.h"
|
||||
@@ -495,6 +496,12 @@ int Device_Encode_Property_APDU(
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], dlmstp_max_master());
|
||||
break;
|
||||
case 512:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], stack_size());
|
||||
break;
|
||||
case 513:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
|
||||
@@ -45,4 +45,11 @@
|
||||
#include "iar2gcc.h"
|
||||
#include "bits.h"
|
||||
|
||||
/* SEEPROM is 24LC128 */
|
||||
//#define SEEPROM_PAGE_SIZE 128
|
||||
//#define SEEPROM_WORD_ADDRESS_16BIT 1
|
||||
/* SEEPROM is 24C16 */
|
||||
#define SEEPROM_PAGE_SIZE 16
|
||||
#define SEEPROM_WORD_ADDRESS_16BIT 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
#include "init.h"
|
||||
#include "stack.h"
|
||||
#include "timer.h"
|
||||
#include "input.h"
|
||||
#include "led.h"
|
||||
#include "seeprom.h"
|
||||
#include "nvdata.h"
|
||||
#include "timer.h"
|
||||
#include "dcc.h"
|
||||
#include "rs485.h"
|
||||
@@ -101,16 +102,41 @@ FUSES =
|
||||
LOCKBITS = LOCKBITS_DEFAULT;
|
||||
#endif
|
||||
|
||||
bool seeprom_version_test(void)
|
||||
{
|
||||
uint16_t version = 0;
|
||||
uint16_t id = 0;
|
||||
bool status = false;
|
||||
|
||||
seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
|
||||
seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2);
|
||||
|
||||
if ((id == SEEPROM_ID) && (version == SEEPROM_VERSION)) {
|
||||
status = true;
|
||||
} else {
|
||||
version = SEEPROM_VERSION;
|
||||
id = SEEPROM_ID;
|
||||
seeprom_bytes_write(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
|
||||
seeprom_bytes_write(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void bacnet_init(
|
||||
void)
|
||||
{
|
||||
MSTP_MAC_Address = input_address();
|
||||
dlmstp_set_mac_address(MSTP_MAC_Address);
|
||||
dlmstp_init(NULL);
|
||||
|
||||
if (!seeprom_version_test()) {
|
||||
/* invalid version data */
|
||||
}
|
||||
/* initialize objects */
|
||||
Device_Init();
|
||||
Binary_Output_Init();
|
||||
|
||||
|
||||
/* we need to handle who-is to support dynamic device binding */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||
/* Set the handlers for any confirmed services that we support. */
|
||||
|
||||
@@ -91,6 +91,34 @@
|
||||
#define NV_EEPROM_DEVICE_NAME_31 41
|
||||
#define NV_EEPROM_DEVICE_NAME_SIZE 32
|
||||
|
||||
/*=============== SEEPROM ================*/
|
||||
#define NV_SEEPROM_BINARY_OUTPUT_OFFSET 32
|
||||
#define NV_SEEPROM_BINARY_OUTPUT_0 10
|
||||
#define NV_SEEPROM_BINARY_OUTPUT(n,p) \
|
||||
(NV_SEEPROM_BINARY_OUTPUT_0 + \
|
||||
(NV_SEEPROM_BINARY_OUTPUT_OFFSET * (n)) + (p))
|
||||
/* BO properties */
|
||||
#define NV_SEEPROM_BO_POLARITY 0
|
||||
#define NV_SEEPROM_BO_OUT_OF_SERVICE 1
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_1 2
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_2 3
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_3 4
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_4 5
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_5 6
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_6 7
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_7 8
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_8 9
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_9 10
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_10 11
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_11 12
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_12 13
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_13 14
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_14 15
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_15 16
|
||||
#define NV_SEEPROM_BO_PRIORITY_ARRAY_16 17
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Return bytes from SEEPROM memory at address
|
||||
* RETURN: number of bytes read, or -1 on error
|
||||
* NOTES: The 24LC128 SEEPROM uses a two byte memory address
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
int seeprom_bytes_read(
|
||||
uint16_t eeaddr, /* SEEPROM starting memory address */
|
||||
@@ -274,7 +274,7 @@ error:
|
||||
/*************************************************************************
|
||||
* DESCRIPTION: Write some data and wait until it is sent
|
||||
* RETURN: number of bytes written, or -1 on error
|
||||
* NOTES: The 24LC128 SEEPROM uses a two byte memory address
|
||||
* NOTES: none
|
||||
**************************************************************************/
|
||||
int seeprom_bytes_write(
|
||||
uint16_t eeaddr, /* SEEPROM starting memory address */
|
||||
|
||||
@@ -29,10 +29,10 @@ extern uint8_t _end;
|
||||
extern uint8_t __stack;
|
||||
|
||||
#define STACK_CANARY (0xC5)
|
||||
void stack_paint(
|
||||
void stack_init(
|
||||
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
|
||||
|
||||
void stack_paint(
|
||||
void stack_init(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
@@ -50,3 +50,28 @@ void stack_paint(
|
||||
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned stack_size(void)
|
||||
{
|
||||
return (&__stack) - (&_end);
|
||||
}
|
||||
|
||||
uint8_t stack_byte(unsigned offset)
|
||||
{
|
||||
return *(&_end + offset);
|
||||
}
|
||||
|
||||
unsigned stack_unused(void)
|
||||
{
|
||||
uint8_t *p = &_end;
|
||||
unsigned count = 0;
|
||||
|
||||
while (p <= &__stack) {
|
||||
if ((*p) != STACK_CANARY) {
|
||||
count = p - (&_end);
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 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.
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef STACK_H
|
||||
#define STACK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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
|
||||
|
||||
Reference in New Issue
Block a user