/**
 * Creates a new ring buffer.
 * @param cap The capacity of the ring buffer.  Note that this method
 * will always allocate 1 extra byte due to limits of ring buffers.
 * @return An opaque pointer to the ring buffer struct.
 */
struct ring_buff* ring_buffer_create(const size_t cap)
{
        struct ring_buff *rb = portMalloc(sizeof(struct ring_buff));
        if (!rb)
                return NULL;

        rb->size = cap + 1;
        rb->buff = portMalloc(rb->size);
        if (!rb->buff) {
                ring_buffer_destroy(rb);
                return NULL;
        }

        ring_buffer_clear(rb);
        return rb;
}
void ShowTaskInfo(Serial *serial, unsigned int argc, char **argv)
{
    putHeader(serial, "Task Info");

    serial->put_s("Status\tPri\tStackHR\tTask#\tName");
    put_crlf(serial);

    /*
     * Memory info from vTaskList can be misleading.  See
     * http://www.freertos.org/uxTaskGetSystemState.html for
     * more detail about how it works and value meanings.
     */
    char *taskList = (char *) portMalloc(1024);
    if (NULL != taskList) {
        vTaskList(taskList);
        serial->put_s(taskList);
        portFree(taskList);
    } else {
        serial->put_s("Out of Memory!");
    }
    put_crlf(serial);

    put_crlf(serial);
    serial->put_s("[Note] StackHR: If StackHR < 0; then stack smash");
    put_crlf(serial);
}
enum script_add_result flashScriptPage(const unsigned int page,
                                       const char *data,
                                       const enum script_add_mode mode)
{
        if (page >= MAX_SCRIPT_PAGES) {
                pr_error("lua: invalid script index\r\n");
                return SCRIPT_ADD_RESULT_FAIL;
        }

        switch (mode) {
        case SCRIPT_ADD_MODE_IN_PROGRESS:
        case SCRIPT_ADD_MODE_COMPLETE:
                /* Valid cases.  Carry on */
                break;
        default:
                pr_error_int_msg("lua: Unknown script_add_mode: ", mode);
                return SCRIPT_ADD_RESULT_FAIL;
        }

        static ScriptConfig *g_scriptBuffer;
        if (NULL == g_scriptBuffer) {
                terminate_lua();

                pr_debug("lua: Allocating new script buffer\r\n");
                g_scriptBuffer =
                        (ScriptConfig *) portMalloc(sizeof(ScriptConfig));
                memcpy((void *)g_scriptBuffer, (void *)&g_scriptConfig,
                       sizeof(ScriptConfig));
        }

        if (NULL == g_scriptBuffer) {
                pr_error("lua: Failed to allocate memory for script "
                         "buffer.\r\n");
                return SCRIPT_ADD_RESULT_FAIL;
        }

        char *pageToAdd = g_scriptBuffer->script + page * SCRIPT_PAGE_SIZE;
        strncpy(pageToAdd, data, SCRIPT_PAGE_SIZE);

        if (SCRIPT_ADD_MODE_IN_PROGRESS == mode)
                return SCRIPT_ADD_RESULT_OK;

        pr_info("lua: Completed updating LUA. Flashing... ");
        const int rc = memory_flash_region((void*) &g_scriptConfig,
                                           (void*) g_scriptBuffer,
                                           sizeof(ScriptConfig));
        portFree(g_scriptBuffer);
        g_scriptBuffer = NULL;

        if (0 != rc) {
                pr_info_int_msg("failed with code ", rc);
                return SCRIPT_ADD_RESULT_FAIL;
        }

        pr_info("win!\r\n");
        initialize_lua();
        return SCRIPT_ADD_RESULT_OK;
}
Ejemplo n.º 4
0
int api_getMeta(Serial *serial, const jsmntok_t *json){
	json_messageStart(serial);
	SampleRecord * sr = (SampleRecord *)portMalloc(sizeof(SampleRecord));
	if (sr == 0) return API_ERROR_SEVERE;

	initSampleRecord(getWorkingLoggerConfig(), sr);
	writeSampleMeta(serial, sr, getConnectivitySampleRateLimit(), 0);

	portFree(sr);
	json_blockEnd(serial, 0);
	return API_SUCCESS_NO_RETURN;
}
static void createTelemetryConnectionTask(int16_t priority, xQueueHandle sampleQueue, uint8_t isPrimary)
{
    ConnParams * params = (ConnParams *)portMalloc(sizeof(ConnParams));
    params->isPrimary = isPrimary;
    params->connectionName = "Telemetry";
    params->periodicMeta = 0;
    params->connection_timeout = TELEMETRY_DISCONNECT_TIMEOUT;
    params->disconnect = &sim900_disconnect;
    params->check_connection_status = &sim900_check_connection_status;
    params->init_connection = &sim900_init_connection;
    params->serial = SERIAL_TELEMETRY;
    params->sampleQueue = sampleQueue;
    params->always_streaming = false;
    xTaskCreate(connectivityTask, (signed portCHAR *) "connTelemetry", TELEMETRY_STACK_SIZE, params, priority, NULL );
}
static void createWirelessConnectionTask(int16_t priority, xQueueHandle sampleQueue, uint8_t isPrimary)
{
    ConnParams * params = (ConnParams *)portMalloc(sizeof(ConnParams));
    params->isPrimary = isPrimary;
    params->connectionName = "Wireless";
    params->periodicMeta = 0;
    params->connection_timeout = 0;
    params->check_connection_status = &bt_check_connection_status;
    params->disconnect = &bt_disconnect;
    params->init_connection = &bt_init_connection;
    params->serial = SERIAL_WIRELESS;
    params->sampleQueue = sampleQueue;
    params->always_streaming = true;
    xTaskCreate(connectivityTask, (signed portCHAR *) "connWireless", TELEMETRY_STACK_SIZE, params, priority, NULL );
}
size_t init_sample_buffer(struct sample *s, const size_t count)
{
        if (s->channel_samples)
                free_sample_buffer(s);

        const size_t size = sizeof(ChannelSample[count]);
        s->channel_samples = (ChannelSample *) portMalloc(size);

        if (NULL == s->channel_samples)
                return 0;

        s->ticks = 0;
        s->channel_count = count;
        init_channel_sample_buffer(getWorkingLoggerConfig(), s);

        return size;
}
Ejemplo n.º 8
0
void ShowTaskInfo(Serial *serial, unsigned int argc, char **argv){

	serial->put_s("Task Info");
	put_crlf(serial);
	serial->put_s("Status\tPri\tStack\tTask#\tName");
	put_crlf(serial);
	char *taskList = (char *)portMalloc(1024);
	if (NULL != taskList){
		vTaskList(taskList);
		serial->put_s(taskList);
		portFree(taskList);
	}
	else{
		serial->put_s("Out of Memory!");
	}
	put_crlf(serial);
}
int flash_default_script()
{
    int result = -1;
    pr_info("flashing default script...");

    /*
     * Stop LUA if we are flashing its data.  This is mainly done to recover
     * RAM since our flashing operation is a heavy bugger
     */
    terminate_lua();

    ScriptConfig *defaultScriptConfig = (ScriptConfig *)portMalloc(sizeof(ScriptConfig));
    if (defaultScriptConfig != NULL) {
        defaultScriptConfig->magicInit = MAGIC_NUMBER_SCRIPT_INIT;
        strncpy(defaultScriptConfig->script, DEFAULT_SCRIPT, sizeof(DEFAULT_SCRIPT));
        result = memory_flash_region((void *)&g_scriptConfig, (void *)defaultScriptConfig, sizeof (ScriptConfig));
        portFree(defaultScriptConfig);
    }
    if (result == 0) pr_info("win\r\n");
    else pr_info("fail\r\n");
    return result;
}
bool serial_buffer_create(struct serial_buffer *sb,
                          Serial *serial,
                          const size_t size,
                          char *buffer)
{
        if (NULL == sb || NULL == serial)
                return false;

        sb->serial = serial;
        sb->length = size;
        sb->buffer = buffer;
        serial_buffer_clear(sb);

        if (NULL == sb->buffer)
                sb->buffer = (char*) portMalloc(size);

        if (NULL != sb->buffer)
                return true;

        /* Failure case if here */
        sb->length = 0;
        sb->buffer = NULL;
        return false;
}
/*combined telemetry - for when there's only one telemetry / wireless port available on system
//e.g. "Y-adapter" scenario */
static void createCombinedTelemetryTask(int16_t priority, xQueueHandle sampleQueue)
{
    ConnectivityConfig *connConfig = &getWorkingLoggerConfig()->ConnectivityConfigs;
    size_t btEnabled = connConfig->bluetoothConfig.btEnabled;
    size_t cellEnabled = connConfig->cellularConfig.cellEnabled;

    if (btEnabled || cellEnabled) {
        ConnParams * params = (ConnParams *)portMalloc(sizeof(ConnParams));

        params->periodicMeta = btEnabled && cellEnabled;

        /*defaults*/
        params->check_connection_status = &null_device_check_connection_status;
        params->init_connection = &null_device_init_connection;
        params->serial = SERIAL_TELEMETRY;
        params->sampleQueue = sampleQueue;
        params->connection_timeout = 0;
        params->always_streaming = false;

        if (btEnabled) {
            params->check_connection_status = &bt_check_connection_status;
            params->init_connection = &bt_init_connection;
            params->disconnect = &bt_disconnect;
            params->always_streaming = true;
        }

        /*cell overrides wireless*/
        if (cellEnabled) {
            params->check_connection_status = &sim900_check_connection_status;
            params->init_connection = &sim900_init_connection;
            params->disconnect = &sim900_disconnect;
            params->always_streaming = false;
        }
        xTaskCreate(connectivityTask, (signed portCHAR *) "connTask", TELEMETRY_STACK_SIZE, params, priority, NULL );
    }
}
Ejemplo n.º 12
0
int api_sampleData(Serial *serial, const jsmntok_t *json){

	int sendMeta = 0;
	if (json->type == JSMN_OBJECT && json->size == 2){
		const jsmntok_t * meta = json + 1;
		const jsmntok_t * value = json + 2;

		jsmn_trimData(meta);
		jsmn_trimData(value);

		if (NAME_EQU("meta",meta->data)){
			sendMeta = modp_atoi(value->data);
		}
	}
	SampleRecord * sr = (SampleRecord *)portMalloc(sizeof(SampleRecord));
	if (sr == 0) return API_ERROR_SEVERE;

	LoggerConfig * config = getWorkingLoggerConfig();
	initSampleRecord(config, sr);
	populateSampleRecord(sr,0, config);
	api_sendSampleRecord(serial, sr, 0, sendMeta);
	portFree(sr);
	return API_SUCCESS_NO_RETURN;
}
void connectivityTask(void *params)
{

    char * buffer = (char *)portMalloc(BUFFER_SIZE);
    size_t rxCount = 0;

    ConnParams *connParams = (ConnParams*)params;
    LoggerMessage msg;

    Serial *serial = get_serial(connParams->serial);

    xQueueHandle sampleQueue = connParams->sampleQueue;
    uint32_t connection_timeout = connParams->connection_timeout;

    DeviceConfig deviceConfig;
    deviceConfig.serial = serial;
    deviceConfig.buffer = buffer;
    deviceConfig.length = BUFFER_SIZE;

    const LoggerConfig *logger_config = getWorkingLoggerConfig();

    bool logging_enabled = false;

    while (1) {
        bool should_stream = logging_enabled ||
                             logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming ||
                             connParams->always_streaming;

        while (should_stream && connParams->init_connection(&deviceConfig) != DEVICE_INIT_SUCCESS) {
            pr_info("conn: not connected. retrying\r\n");
            vTaskDelay(INIT_DELAY);
        }

        serial->flush();
        rxCount = 0;
        size_t badMsgCount = 0;
        size_t tick = 0;
        size_t last_message_time = getUptimeAsInt();
        bool should_reconnect = false;

        while (1) {
            if ( should_reconnect )
                break; /*break out and trigger the re-connection if needed */

            should_stream =
                    logging_enabled ||
                    connParams->always_streaming ||
                    logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming;

            const char res = receive_logger_message(sampleQueue, &msg,
                                                    IDLE_TIMEOUT);

            /*///////////////////////////////////////////////////////////
            // Process a pending message from logger task, if exists
            ////////////////////////////////////////////////////////////*/
            if (pdFALSE != res) {
                switch(msg.type) {
                case LoggerMessageType_Start: {
                    api_sendLogStart(serial);
                    put_crlf(serial);
                    tick = 0;
                    logging_enabled = true;
                    /* If we're not already streaming trigger a re-connect */
                    if (!should_stream)
                        should_reconnect = true;
                    break;
                }
                case LoggerMessageType_Stop: {
                    api_sendLogEnd(serial);
                    put_crlf(serial);
                    if (! (logger_config->ConnectivityConfigs.telemetryConfig.backgroundStreaming ||
                           connParams->always_streaming))
                        should_reconnect = true;
                    logging_enabled = false;
                    break;
                }
                case LoggerMessageType_Sample: {
                        if (!should_stream)
                                break;

                        const int send_meta = tick == 0 ||
                                (connParams->periodicMeta &&
                                 (tick % METADATA_SAMPLE_INTERVAL == 0));
                        api_send_sample_record(serial, msg.sample, tick, send_meta);

                        if (connParams->isPrimary)
                                toggle_connectivity_indicator();

                        put_crlf(serial);
                        tick++;
                        break;
                }
                default:
                    break;
                }
            }

            /*//////////////////////////////////////////////////////////
            // Process incoming message, if available
            ////////////////////////////////////////////////////////////
            //read in available characters, process message as necessary*/
            int msgReceived = processRxBuffer(serial, buffer, &rxCount);
            /*check the latest contents of the buffer for something that might indicate an error condition*/
            if (connParams->check_connection_status(&deviceConfig) != DEVICE_STATUS_NO_ERROR) {
                pr_info("conn: disconnected\r\n");
                break;
            }
            /*now process a complete message if available*/
            if (msgReceived) {
                last_message_time = getUptimeAsInt();
                pr_debug(connParams->connectionName);
                pr_debug_str_msg(": rx: ", buffer);
                int msgRes = process_api(serial, buffer, BUFFER_SIZE);

                int msgError = (msgRes == API_ERROR_MALFORMED);
                if (msgError) {
                    pr_debug("(failed)\r\n");
                }
                if (msgError) {
                    badMsgCount++;
                } else {
                    badMsgCount = 0;
                }
                if (badMsgCount >= BAD_MESSAGE_THRESHOLD) {
                    pr_warning_int_msg("re-connecting- empty/bad msgs :", badMsgCount );
                    break;
                }
                rxCount = 0;
            }

            /*disconnect if a timeout is configured and
            // we haven't heard from the other side for a while */
            const size_t timeout = getUptimeAsInt() - last_message_time;
            if (connection_timeout && timeout > connection_timeout ) {
                pr_info_str_msg(connParams->connectionName, ": timeout");
                should_reconnect = true;
            }
        }
        clear_connectivity_indicator();
        connParams->disconnect(&deviceConfig);
    }
}
//******************************************************************************
int ADC_device_init(void)
{
    /* TODO: Ditch malloc here, this can be done statically */
    size_t adcBufferSize = sizeof(uint16_t) * TOTAL_ADC_CHANNELS;
    ADCConvertedValues = portMalloc(adcBufferSize);
    memset(ADCConvertedValues, 0, adcBufferSize);

    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    DMA_InitTypeDef DMA_InitStructure;

    ADC_DeInit();
    ADC_GPIO_Configuration();

    /* Enable peripheral clocks ************************************************ */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

    /* DMA2_Stream0 channel0 configuration ************************************* */
    DMA_DeInit(DMA2_Stream2);
    DMA_InitStructure.DMA_Channel = DMA_Channel_1;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = 9;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream2, &DMA_InitStructure);
    /* DMA2_Stream0 enable */
    DMA_Cmd(DMA2_Stream2, ENABLE);

    /* ADC Common Init ********************************************************* */
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    /* ADC2 Init *************************************************************** */
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 9;
    ADC_Init(ADC2, &ADC_InitStructure);

    /* ADC2 regular channel configuration ***************************** */
    ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 1,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 2,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 3,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 4,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 5,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 6,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 7,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 8,
                             ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 9,
                             ADC_SampleTime_480Cycles);

    /* Enable DMA request after last transfer (Single-ADC mode) */
    ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);

    /* Enable ADC2 DMA */
    ADC_DMACmd(ADC2, ENABLE);

    /* Enable ADC2 ************************************************************* */
    ADC_Cmd(ADC2, ENABLE);

    /* Start ADC2 Software Conversion */
    ADC_SoftwareStartConv(ADC2);

    return 1;
}
size_t create_ring_buffer(struct ring_buff *rb, size_t size)
{
        char *buff = (char *) portMalloc(size);
        return NULL == buff ? 0 : init_ring_buffer(rb, buff, size);
}
Ejemplo n.º 16
0
enum track_add_result add_track(const Track *track, const size_t index,
                                const enum track_add_mode mode)
{
        if (index >= MAX_TRACK_COUNT) {
                pr_error("tracks: Invalid track index\r\n");
                return TRACK_ADD_RESULT_FAIL;
        }

        switch (mode) {
        case TRACK_ADD_MODE_IN_PROGRESS:
        case TRACK_ADD_MODE_COMPLETE:
                /* Valid cases.  Carry on */
                break;
        default:
                pr_error_int_msg("tracks: Unknown track_add_mode: ", mode);
                return TRACK_ADD_RESULT_FAIL;
        }

        static Tracks *g_tracksBuffer;
        if (NULL == g_tracksBuffer) {

#if LUA_SUPPORT
                lua_task_stop();
#endif /* LUA_SUPPORT */

                pr_debug("tracks: Allocating new tracks buffer\r\n");
                g_tracksBuffer = (Tracks *) portMalloc(sizeof(Tracks));
                memcpy(g_tracksBuffer, (void*) &g_tracks, sizeof(Tracks));
        }

        if (NULL == g_tracksBuffer) {
                pr_error("tracks: Failed to allocate memory for track buffer.\r\n");
                return TRACK_ADD_RESULT_FAIL;
        }

        Track *trackToAdd = g_tracksBuffer->tracks + index;
        memcpy(trackToAdd, track, sizeof(Track));
        g_tracksBuffer->count = index + 1;

        /* If we made it here and are still in progress, then we are done */
        if (TRACK_ADD_MODE_IN_PROGRESS == mode)
                return TRACK_ADD_RESULT_OK;

        /* If here, time to flash and tidy up */
        pr_info("tracks: Completed updating tracks. Flashing... ");
        const int rc = flash_tracks(g_tracksBuffer, sizeof(Tracks));
        portFree(g_tracksBuffer);
        g_tracksBuffer = NULL;

        if (0 != rc) {
                pr_info_int_msg("failed with code ", rc);
                return TRACK_ADD_RESULT_FAIL;
        }

        pr_info("win!\r\n");

#if LUA_SUPPORT
        lua_task_start();
#endif /* LUA_SUPPORT */

        return TRACK_ADD_RESULT_OK;
}