Added multiple uBASIC program objects to stm32f4xx example port. (#995)
This commit is contained in:
@@ -8,37 +8,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "bacnet/basic/object/program.h"
|
||||
#include "bacnet/basic/program/ubasic/ubasic.h"
|
||||
#include "bacnet/basic/sys/mstimer.h"
|
||||
|
||||
/* uBASIC-Plus program object */
|
||||
static struct ubasic_data UBASIC_DATA = { 0 };
|
||||
/* timer for the task */
|
||||
static struct mstimer UBASIC_Timer;
|
||||
static uint32_t UBASIC_Instance = 0;
|
||||
static const char *UBASIC_Program =
|
||||
/* program listing with either \0, \n, or ';' at the end of each line.
|
||||
note: indentation is not required */
|
||||
"println 'Demo - BACnet & GPIO';"
|
||||
"bac_create(0, 1, 'ADC-1');"
|
||||
"bac_create(0, 2, 'ADC-2');"
|
||||
"bac_create(4, 1, 'LED-1');"
|
||||
"bac_create(4, 2, 'LED-2');"
|
||||
":startover;"
|
||||
" a = aread(1);"
|
||||
" c = avgw(a, c, 10);"
|
||||
" bac_write(0, 1, 85, c);"
|
||||
" b = aread(2);"
|
||||
" d = avgw(b, d, 10);"
|
||||
" bac_write(0, 2, 85, d);"
|
||||
" h = bac_read(4, 1, 85);"
|
||||
" dwrite(1, (h % 2));"
|
||||
" i = bac_read(4, 2, 85);"
|
||||
" dwrite(2, (i % 2));"
|
||||
" sleep (0.2);"
|
||||
"goto startover;"
|
||||
"end;";
|
||||
/* context structure */
|
||||
|
||||
/**
|
||||
* @brief Load the program into the uBASIC interpreter
|
||||
@@ -47,9 +25,14 @@ static const char *UBASIC_Program =
|
||||
*/
|
||||
static int Program_Load(void *context)
|
||||
{
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
struct ubasic_data *data = (struct ubasic_data *)context;
|
||||
|
||||
ubasic_load_program(data, UBASIC_Program);
|
||||
ubasic_load_program(data, NULL);
|
||||
(void)ubasic_program_location(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -61,6 +44,9 @@ static int Program_Load(void *context)
|
||||
*/
|
||||
static int Program_Run(void *context)
|
||||
{
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
struct ubasic_data *data = (struct ubasic_data *)context;
|
||||
int result = 0;
|
||||
|
||||
@@ -68,6 +54,7 @@ static int Program_Run(void *context)
|
||||
if (result <= 0) {
|
||||
return -1;
|
||||
}
|
||||
(void)ubasic_program_location(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -79,9 +66,12 @@ static int Program_Run(void *context)
|
||||
*/
|
||||
static int Program_Halt(void *context)
|
||||
{
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
struct ubasic_data *data = (struct ubasic_data *)context;
|
||||
|
||||
data->status.bit.isRunning = 0;
|
||||
ubasic_halt_program(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -93,10 +83,14 @@ static int Program_Halt(void *context)
|
||||
*/
|
||||
static int Program_Restart(void *context)
|
||||
{
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
struct ubasic_data *data = (struct ubasic_data *)context;
|
||||
|
||||
ubasic_clear_variables(data);
|
||||
ubasic_load_program(data, UBASIC_Program);
|
||||
ubasic_load_program(data, NULL);
|
||||
(void)ubasic_program_location(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -108,9 +102,13 @@ static int Program_Restart(void *context)
|
||||
*/
|
||||
static int Program_Unload(void *context)
|
||||
{
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
struct ubasic_data *data = (struct ubasic_data *)context;
|
||||
|
||||
ubasic_clear_variables(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,29 +117,74 @@ static int Program_Unload(void *context)
|
||||
*/
|
||||
void Program_UBASIC_Task(void)
|
||||
{
|
||||
size_t index, max_index;
|
||||
uint32_t instance;
|
||||
|
||||
if (mstimer_expired(&UBASIC_Timer)) {
|
||||
mstimer_reset(&UBASIC_Timer);
|
||||
Program_Timer(UBASIC_Instance, mstimer_interval(&UBASIC_Timer));
|
||||
max_index = Program_Count();
|
||||
for (index = 0; index < max_index; index++) {
|
||||
instance = Program_Index_To_Instance(index);
|
||||
Program_Timer(instance, mstimer_interval(&UBASIC_Timer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the uBASIC program object
|
||||
* @param instance Instance number of the program object
|
||||
* @brief Create one uBASIC program object
|
||||
* @param requested_instance Instance number of the program object
|
||||
* @param context Pointer to the uBASIC data structure
|
||||
* @param program Pointer to the uBASIC program
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
void Program_UBASIC_Init(uint32_t instance)
|
||||
int Program_UBASIC_Create(
|
||||
uint32_t requested_instance,
|
||||
struct ubasic_data *context,
|
||||
const char *program)
|
||||
{
|
||||
ubasic_port_init(&UBASIC_DATA);
|
||||
UBASIC_Instance = Program_Create(instance);
|
||||
Program_Context_Set(UBASIC_Instance, &UBASIC_DATA);
|
||||
Program_Load_Set(UBASIC_Instance, Program_Load);
|
||||
Program_Run_Set(UBASIC_Instance, Program_Run);
|
||||
Program_Halt_Set(UBASIC_Instance, Program_Halt);
|
||||
Program_Restart_Set(UBASIC_Instance, Program_Restart);
|
||||
Program_Unload_Set(UBASIC_Instance, Program_Unload);
|
||||
/* auto-run the program */
|
||||
Program_Change_Set(UBASIC_Instance, PROGRAM_REQUEST_RUN);
|
||||
/* start the cyclic 10ms run timer for the program object */
|
||||
mstimer_set(&UBASIC_Timer, 10);
|
||||
uint32_t instance = 0;
|
||||
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
if (Program_Valid_Instance(requested_instance)) {
|
||||
instance = requested_instance;
|
||||
if (program) {
|
||||
context->program = program;
|
||||
}
|
||||
Program_Change_Set(instance, PROGRAM_REQUEST_RESTART);
|
||||
} else {
|
||||
instance = Program_Create(requested_instance);
|
||||
if (instance == BACNET_MAX_INSTANCE) {
|
||||
return -1;
|
||||
}
|
||||
if (program) {
|
||||
context->program = program;
|
||||
} else {
|
||||
context->program = "end;";
|
||||
}
|
||||
Program_Context_Set(instance, context);
|
||||
Program_Load_Set(instance, Program_Load);
|
||||
Program_Run_Set(instance, Program_Run);
|
||||
Program_Halt_Set(instance, Program_Halt);
|
||||
Program_Restart_Set(instance, Program_Restart);
|
||||
Program_Unload_Set(instance, Program_Unload);
|
||||
Program_Location_Set(instance, context->location);
|
||||
ubasic_port_init(context);
|
||||
/* auto-run the program */
|
||||
Program_Change_Set(instance, PROGRAM_REQUEST_RUN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the uBASIC program object
|
||||
* @param requested_instance Instance number of the program object
|
||||
* @return 0 on success, non-zero on error
|
||||
*/
|
||||
void Program_UBASIC_Init(unsigned long task_ms)
|
||||
{
|
||||
/* start the cyclic 10ms run timer for the program object */
|
||||
mstimer_set(&UBASIC_Timer, task_ms);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user