Test program for Pawn 4 interpreter. Looks for a main.amx on the mbed 'drive', loads it, and calls the main() function within it.

Dependencies:   Pawn4 mbed

Welcome to the Pawn 4 mbed test program. This program is designed to show off all features of the Pawn mbed port. Currently, it will do the following:

- Create a Pawn VM instance - Add the following modules to the Pawn VM - mbed - console (used only for printf currently) - time (date/time, delay functions) - Look for a main.amx file at the root of the mbed file system. If found, will attempt to load whole file into memory. IMPORTANT: when the program opens the file on the mbed file system, the mbed will unmount itself from any connected PC/Mac, possibly resulting in a rude-looking OS message (I am looking at you OS X). It will reappear when the program closes the main.amx file. - Attempt to execute the main function in the loaded script - When the main routine returns, it will currently sit in a loop blinking LED4. It may be better to simply re-run the main routine. Perhaps a special return value can determine what we do...

Also see the Pawn4 library project for details on how to set up your development environment on the mbed itself and how to build scripts.

main.cpp

Committer:
tylerwilson
Date:
2013-05-22
Revision:
2:4400650fe664
Parent:
1:3b4d6ea39002

File content as of revision 2:4400650fe664:

// 
// Simple Pawn 4.x test, built for the mbed LPC1786 and LPC11U24 versions
//
// Copyright (c) 2012-2013 Pulse-Robotics, Inc.
// 
// Author(s): Tyler Wilson
//
#include <stdarg.h>
#include <stdlib.h>

#include "mbed.h"

#include "osdefs.h"
#include "amx.h"
#include "amxaux.h"
#include "amxconsole.h"
#include "amxtime.h"
#include "amxmbed.h"
#include "amxpool.h"

#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
    #define MAX_IMAGE 1024*32
#elif defined(TARGET_LPC11U24)
    #define MAX_IMAGE 1024*4
#endif

// Objects we may need
//DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
DigitalOut led4(LED4);
Serial pc(USBTX, USBRX);
LocalFileSystem local("local");

// local prototypes
void mbed_set_serial(Serial* serial);
//int heap_stats_callback(void* pBuffer, char const* pFormatString, ...);


int main()
{
    pc.baud(115200);
    mbed_set_serial(&pc);  // so the interp. sends and gets to the right place
    
//    pc.printf("LEDs: 0x%x,0x%x,0x%x,0x%x\n\r", LED1, LED2, LED3, LED4);
  
// heap test
//    char OutputBuffer[256];
//    OutputBuffer[0] = '\0';
//    _heapstats(heap_stats_callback, OutputBuffer);
//    pc.printf("%s\n\r", OutputBuffer);
    
    int err = AMX_ERR_NONE;
    AMX amx;
    
     // init pool
//    void* pool = malloc(4096);
//    amx_poolinit(pool, 4096);

    size_t size = aux_ProgramSize("/local/main.amx");
    pc.printf("/local/main.amx needs %d of memory\n\r", size);

    pc.printf("loading /local/main.amx\n\r");
    err = aux_LoadProgram(&amx, "/local/main.amx", 0);
    pc.printf("Finished loading, with result %s.\n\r", aux_StrError(err));

    if (err == AMX_ERR_NONE)
    {
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
        int count = 0, r = 0, i=0;
        ucell uaddr;
        cell *addr;

        r = amx_NumNatives(&amx, &count);
        pc.printf("natives: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetNative(&amx, i, temp);
            pc.printf("native: %s\n\r", temp);
        }

        r = amx_NumPublics(&amx, &count);
        pc.printf("publics: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetPublic(&amx, i, temp, &uaddr);
            pc.printf("public: %s, %x\n\r", temp, uaddr);
        }

        r = amx_NumPubVars(&amx, &count);
        pc.printf("pubvars: %d (result:%d)\n\r", count, r);
        for (i=0; i<count; i++) {
            char temp[16];
            r = amx_GetPubVar(&amx, i, temp, &addr);
            pc.printf("pubvar: %s, %x\n\r", temp, addr);
        }
        
        r = amx_NumTags(&amx, &count);
        pc.printf("tags: %d (result:%d)\n\r", count, r);
        pc.printf("\n\r");
#endif

        // for print and friends
        amx_ConsoleInit(&amx);
        // for time functions
        amx_TimeInit(&amx);
        // for mbed-specific functions
        amx_mbedInit(&amx);
        
        cell ret;
        pc.printf("calling main() via amx_Exec\n\r");
        err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN);
        pc.printf("amx_Exec returned %d, main returned %d\n\r", err, ret);
        
        while (err == AMX_ERR_SLEEP)
        {
            // let other parts of the system run
            wait_ms(10);
            
            err = amx_Exec(&amx, &ret, AMX_EXEC_CONT);
            pc.printf("amx_Exec returned %d, main returned %d\n\r", err, ret);
        }
        
        // clean up our extension modules, in reverse order
        amx_mbedCleanup(&amx);
        amx_TimeCleanup(&amx);
        amx_ConsoleCleanup(&amx);
        
        pc.printf("calling auxFreeProgram\n\r");
        aux_FreeProgram(&amx);
        pc.printf("called auxFreeProgram\n\r");
    }        

    while (true)
    {
        led4 = !led4;
        wait_ms(400);
    }
}

#if 0
int heap_stats_callback(void* pBuffer, char const* pFormatString, ...)
{
    char* pStringEnd = (char*)pBuffer + strlen((char*)pBuffer);
    va_list valist;
    
    va_start(valist, pFormatString);
    
    return vsprintf(pStringEnd, pFormatString, valist);
}
#endif

// additions to amx.h:
//
#if defined __ICC8051__
  #define HAVE_STDINT_H 0
  #define AMX_ANSIONLY 1
#endif

// additions to osdefs.h:
#if defined(__ARMCC_VERSION)
    #define AMX_ANSIONLY 1
    #define AMX_NODYNALOAD 1
    // for the io functions putc, getc, etc.
    #include "_amxmbed.h"
#endif