Typical controller demo program based on Seeed Arch Max. Features: - Multi-thread architecture - Inter-thread message communication - Independent command shell using thread - HTTPD with CGI, WS, RPC - Key & value pair configuration load/save

Dependencies:   CMDB EthernetInterface HTTPD dconfig mbed-rpc mbed-rtos mbed storage_on_flash

main.cpp

Committer:
hillkim7
Date:
2015-07-03
Revision:
3:df8a882e33a6
Parent:
0:2ffd10976643

File content as of revision 3:df8a882e33a6:

/**
Typical controller demo program based on Seeed Arch Max.
The mbed has potential power by combining variable library, this program unveils that kind of thing.
Features:
- Multi-thread architecture
- Inter-thread message communication
- Independent command shell using thread
- HTTPD with CGI, WS, RPC
- Key & value pair configuration load/save
*/

#include "mbed.h"
#include "rtos.h"
#include "console.h"
#include "httpd_service.h"
#include "util.h"
#include "EthernetInterface.h"
#include "main.h"

#define SUPPORT_CONSOLE			1
#define SUPPORT_ETH				1
#define SUPPORT_HTTPD			1

const unsigned connect_timeout_ms = 2000;

static Mail<MainMessage_t, 5> _mainq;

static DigitalOut _alive_led(LED1);

EthernetInterface _eth;
MainConfig _config;

static void eth_up_dhcp()
{

    printf("eth_up_dhcp: init()\r\n");
    _eth.init();
    _eth.connect(connect_timeout_ms);
}

static void eth_up_static(const char *ip, const char *netmask, const char *gateway)
{
    const unsigned static_connect_timeout_ms = 3;

    printf("eth_up_static: init('%s', '%s', '%s')\r\n", ip, netmask, gateway);
    _eth.init(ip, netmask, gateway);
    _eth.connect(static_connect_timeout_ms);
}

static void eth_up()
{
    _config.lock_config();
    if (_config.lookup("eth") == "dhcp")
        eth_up_dhcp();
    else
        eth_up_static(_config.lookup_as_cstr("ip", ""), _config.lookup_as_cstr("mask", ""), _config.lookup_as_cstr("gw", ""));
    _config.unlock_config();
}

static void eth_stat()
{
    printf("eth '%s', '%s', '%s'\r\n", _eth.getIPAddress(), _eth.getNetworkMask(), _eth.getGateway());
}


bool send_main_message(MainMessageId msg_id, uint32_t msg_p1, uint32_t msg_p2)
{
    MainMessage_t *msg = (MainMessage_t*)_mainq.alloc();

    if (msg) {
        msg->msg_id = msg_id;
        msg->msg_p1 = msg_p1;
        msg->msg_p2 = msg_p2;
        _mainq.put(msg);
        return true;
    } else {
        printf("_mainq.alloc fail\r\n");
        return false;
    }
}

static void on_main_message(MainMessageId msg_id, uint32_t msg_p1, uint32_t msg_p2)
{
    switch (msg_id) {
        case MSG_IFUP:
            printf("eth connect: %d\r\n", _eth.connect(1000));
            break;
        case MSG_IFDOWN:
            printf("eth disconnect\r\n");
            _eth.disconnect();
            break;
        case MSG_IFSTAT:
            eth_stat();
            break;
    }
}

int main()
{
    Serial pc(USBTX, USBRX);

    pc.baud(115200);
    pc.printf("built at " __DATE__ " " __TIME__ "\r\n");
    pc.printf("memory stat:\r\n");
    print_memstat();

    if (!_config.load_config()) {
        printf("load_config fail: reset_default()\r\n");
        _config.reset_default();
    }

#if SUPPORT_CONSOLE
    printf("SUPPORT_CONSOLE\r\n");
    Thread console(console_thread, &pc, osPriorityNormal, CONSOLE_STACK_SIZE);
#endif

#if SUPPORT_ETH
    printf("SUPPORT_ETH\r\n");
    eth_up();

#if SUPPORT_HTTPD
    httpd_start(80);
#endif
#endif

    while (1) {
        const uint32_t wait_ms = 100;
        osEvent evt = _mainq.get(wait_ms);

        if (evt.status == osEventMail) {
            MainMessage_t *msg = (MainMessage_t*)evt.value.p;

            on_main_message(msg->msg_id, msg->msg_p1, msg->msg_p2);
            _mainq.free(msg);
        }

        _alive_led = !_alive_led;
    }

    return 0;
}

/**
 * Overriding MAC address
 */
void mbed_mac_address(char *mac)
{
    // Change ethernet mac address of device.
    mac[0] = 0x00;
    mac[1] = 0x80;
    mac[2] = 0xE1;
    mac[3] = 0x00;
    mac[4] = 0x02;
    mac[5] = 0x01;
}