This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/CC2650: HWI Exception - possible overrun

Part Number: CC2650

Tool/software: TI-RTOS

Hello

I have a single HWI and it simply uses System_printf() and a Semaphore_post(); Somehow, I am getting an exception. There are photos below including my code that should help identify the issue. What doesn't make sense is that I increased the HWI buffer from 768 to 4096 and the stack still raises an exception. I'm not sure how a HWI stack is allocated within the context of a Task (does the HWI stack get used up when a HWI is called)? Please note that there is an external .c file "cyc_counterR1.h" containing an algorithm with about 2 kbytes of data and several functions. These functions are exposed to the entirety of the code running on the CC2650, but the functions are only called from within the scope of Task2 (cyc_algo). Could it be that when a HWI occurs while executing one of these functions, much of the data is being put onto the HWI stack for holding purposes? I have run out of options and cannot find a solution. Thank you for your help ahead of time

/*
 * Copyright (c) 2015-2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 *  ======== empty.c ========
 */
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <xdc/runtime/Types.h>
#include <xdc/runtime/Timestamp.h>

#include <ti/sysbios/heaps/HeapBuf.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/Log.h>
#include <ti/uia/events/UIAEvt.h>
#include <ti/uia/events/UIAErr.h>
#include <ti/uia/events/UIAStatistic.h>

#include "cyc_counterR1.h"
/* TI-RTOS Header files */
// #include <ti/drivers/I2C.h>
#include <ti/drivers/PIN.h>
// #include <ti/drivers/SPI.h>
#include <ti/drivers/UART.h>
// #include <ti/drivers/Watchdog.h>


#include "scif.h"
#include "ex_include_tirtos.h"
#define BV(n)               (1 << (n))
// Display error message if the SCIF driver has been generated with incorrect operating system setting
#ifndef SCIF_OSAL_TIRTOS_H
    #error "SCIF driver has incorrect operating system configuration for this example. Please change to 'TI-RTOS' in the Sensor Controller Studio project panel and re-generate the driver."
#endif

// Display error message if the SCIF driver has been generated with incorrect target chip package
#ifndef SCIF_TARGET_CHIP_PACKAGE_QFN48_7X7_RGZ
    #error "SCIF driver has incorrect target chip package configuration for this example. Please change to 'QFN48 7x7 RGZ' in the Sensor Controller Studio project panel and re-generate the driver."
#endif

/* Board Header files */
#include "Board.h"
#include "l_list.h"

//#define SERIALSTACK 2048
#define CYCSTACK 4096
#define LIDARSTACK 2048

char msg[64]; // To hold the message
char out[64]; // to hold output message
_Bool read_again = 0;
_Bool start_readings = 1;
_Bool first_char = 1;
int ext = 0; // can remove
long serial_time = 0;
long serial_dist = 0;
long serial_sensor = 0;
//
//// For reading / writing via serial
//Task_Struct serial_task_Struct;
//Char serial_task_0[SERIALSTACK];

Task_Struct algo_task_Struct;
Char algo_task_1[CYCSTACK];

Task_Struct lidar_task_Struct;
Char lidar_task_2[LIDARSTACK];

Semaphore_Struct semStruct;
Semaphore_Handle semHandle;

UART_Handle comm_handle; // comm handle
UART_Params comm_params; // comm parameters

HeapBuf_Params params;
HeapBuf_Handle heap_buff;
extern IHeap_Handle heap;
extern Memory_Stats heapStats;
extern Error_Block eb;

void HWI_ERROR()
{
	System_printf("HWI ERROR\n");
	System_flush();
}

void scCtrlReadyCallback(void) {

//	System_printf("rdycallback\n");
} // scCtrlReadyCallback

void scTaskAlertCallback(void) {

	System_printf("alertcallback\n");
//	System_flush();
	// Wake up the OS task
    Semaphore_post(semHandle);


} // scTaskAlertCallback

Void format_msg()
{
	static char *token = NULL;
	token = strtok(msg, ","); // Gets time
	serial_time = atol(token); // Stores time via pointer
	token = strtok(NULL, ","); // Gets distance
	serial_dist= atol(token); // Stores distance via pointer
	token = strtok(NULL, "!"); // Gets sensor
	serial_sensor = atol(token); // Stores sensor via pointer
	token = NULL;

}

void format_count_data()
{
	int size = sizeof(DATA_OUT)/sizeof(int);

	static char longbuff[15];

	sprintf(longbuff, "%d", time_out);

	strcat(out, longbuff); // Converts time to char array, stores it in msg
	strcat(out, ","); // Adds a comma
	static int k = 0; // Used for iteration, is only declarted/created once

	for(k=0; k<size; k++)
	{
		sprintf(longbuff, "%i", DATA_OUT[k]);
		strcat(out, longbuff); // Stores all data in char array
		if (k != (size - 1))
			strcat(out, ","); // Delimiter
	}
	k = 0;
	strcat(out, "!"); // Final delimiter
}

Void lidar_task(UArg arg0, UArg arg1)
{
	Types_FreqHz fhz;
	Timestamp_getFreq(&fhz);
	Log_info0("Testing");
//	System_printf("TIMESTAMP FREQ: %d - %d", fhz.hi, fhz.lo);
//	System_flush();

	// Initialize the Sensor Controller
	scifOsalInit();
	scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
	scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
	scifInit(&scifDriverSetup);

	// Set the Sensor Controller task tick interval to 1 millisecond
	//scifStartRtcTicksNow(0x00010000);
	scifStartRtcTicksNow(65);

	// Configure to trigger interrupt at first result, and start the Sensor Controller's I2C Light
	// Sensor task (not to be confused with OS tasks)
	scifStartTasksNbl(BV(SCIF_I2C_LIGHT_SENSOR_TASK_ID));

	uint16_t status = scifTaskData.i2cLightSensor.state.i2cStatus;
	if (status!=0x00) {
	System_printf("I2C Error!!!!\n");
	System_flush();
	}

	// Main loop
	while (1) {

		// Wait for an ALERT callback
//		System_printf("pending...\n");
//		System_flush();
		Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);

		// Clear the ALERT interrupt source
		scifClearAlertIntSource();

		UInt32 t = Clock_getTicks()/100;
		System_printf("Writing data\n");
		add_1(t, scifTaskData.i2cLightSensor.output.value[0]*10);
		add_2(t, scifTaskData.i2cLightSensor.output.value[1]*10);

		scifAckAlertEvents();
	}

}

Void cyc_algo(UArg arg0, UArg arg1)
{

	System_printf("cycalgo\n");

	/* ***Setup for algorithm*** */
	// Applies initial data for sensor 1
	toggle = 0;
	wl[toggle] = 1;

	System_printf("toggle\n");

	// Waits for data to be available
	while(!s1_rdy)
	{
		System_printf("while1\n");
	}
	rm_1(&py_time, &py_dist);

	// Stores data in appropriate variables
	dist_data[toggle][0] = dist_data[toggle][1]; // buff_dist = current_dist
	dist_data[toggle][1] = py_dist; // curr_dist = next dist
	time_data[toggle][7] = time_data[toggle][4]; // buffer_time = temp time
	time_data[toggle][4] = py_time; // temp_time = new time

//	System_printf("s1 t, d: %d %d\n", py_time, py_dist);
//	System_flush();

	// Applies initial data for sensor 2
	toggle = 1;
	wl[toggle] = 1;

	// Waits for data to be available
	while(!s2_rdy)
	{
	}
	rm_2(&py_time, &py_dist);

	// Stores data in appropriate variables
	dist_data[toggle][0] = dist_data[toggle][1]; // buff_dist = current_dist
	dist_data[toggle][1] = py_dist; // curr_dist = next dist
	time_data[toggle][7] = time_data[toggle][4]; // buffer_time = temp time
	time_data[toggle][4] = py_time; // temp_time = new time

//	System_printf("s2 t, d: %d %d\n", py_time, py_dist);
//	System_flush();

	while (1) {
		if (bool_cond[toggle][4]) // Can shift
		{
			toggle = (toggle == 0) ? 1:0;
			// Waits for appropriate data
			if (toggle == 0)
			{
				while(!s1_rdy){
					;
				}

//				System_flush();
				rm_1(&py_time, &py_dist);
//				Log_write5( UIAEvt_intWithKey, py_dist, 0, 0,(IArg)"py_dist");
				if (py_dist<1500)
				{
					System_printf("s1 t, d: %d %d\n", py_time, py_dist);
					System_flush();
				}
			}
			else
			{
				while(!s2_rdy){System_printf("Waiting in s2\n");}
//				System_flush();
				rm_2(&py_time, &py_dist);
				if (py_dist<1500)
				{
					System_printf("s1 t, d: %d %d\n", py_time, py_dist);
					System_flush();
				}
			}


			// Stores data in appropriate variables
			dist_data[toggle][0] = dist_data[toggle][1]; // buff_dist = current_dist
			dist_data[toggle][1] = py_dist; // curr_dist = next dist
			time_data[toggle][7] = time_data[toggle][4]; // buffer_time = temp time
			time_data[toggle][4] = py_time; // temp_time = new time

		}


		bool_cond[toggle][4] = 1; // Sets can shift to 1

		// Multiplexer like functionality
		if (wl[toggle] == 1)
		{

			if (while_loop1())
			{
				System_printf("Wl1\n");
				if (output_ready)
				{
					// Sends data to python
					format_count_data();
////					UART_write(comm_handle, out, strlen(out));
					System_printf("OUTPUT: %s\n", out);
					out[0]='\0';
					clear_output();
					output_ready = 0; // Data has been written to python

//					System_flush();
//					BIOS_exit(1);
				}
				continue;
			}
		}
		if (wl[toggle] == 2)
		{
			System_printf("Wl1\n");
			if (while_loop2())
			{
				continue;
			}
		}
		if (wl[toggle] == 3)
		{
			System_printf("Wl1\n");
			if (while_loop3())
			{
				continue;
			}
		}
		System_flush();
	}

}

//Void read_write(UArg arg0, UArg arg1)
//{
//	msg[0] = '\0'; // Initializes array to have no contents (VERY IMPORTANT!)
//
//	char *read_val; // Holds read value
//	char rdy[] = "r!"; // Holds ready string
//	char next[] = "^d!"; // Holds "done reading" string
//
//	System_printf("Variables set up\n");
//	System_flush();
//
//	// Create a UART with data processing off. //
//	UART_Params_init(&comm_params);
//	comm_params.writeDataMode = UART_DATA_BINARY;
//	comm_params.readDataMode = UART_DATA_BINARY;
//	comm_params.readReturnMode = UART_RETURN_FULL;
//	comm_params.readEcho = UART_ECHO_OFF;
//	comm_params.baudRate = 115200;
//	comm_handle = UART_open(Board_UART0, &comm_params);
//
//	System_printf("COMM set-up\n");
//	System_flush();
//
//
//}

int main(void)
{
    Task_Params serial_params;
    Task_Params algo_params;
    Task_Params lidar_params;

	Semaphore_Params semParams;

    /* Call board init functions */
    Board_initGeneral();
    Board_initUART();

//    /* Construct read/write Task thread */
//    Task_Params_init(&serial_params);
//    serial_params.stackSize = SERIALSTACK;
//    serial_params.stack = &serial_task_0;
//    serial_params.priority = 1;
//    Task_construct(&serial_task_Struct, (Task_FuncPtr)read_write, &serial_params, NULL);

    /* Construct lidar Task thread */
    Task_Params_init(&lidar_params);
    lidar_params.stackSize = LIDARSTACK;
    lidar_params.stack = &lidar_task_2;
    lidar_params.priority = 2;
    Task_construct(&lidar_task_Struct, (Task_FuncPtr)lidar_task, &lidar_params, NULL);

    /* Construct test Task thread */
    Task_Params_init(&algo_params);
    algo_params.stackSize = CYCSTACK;
    algo_params.stack = &algo_task_1;
    algo_params.priority = 1;
    Task_construct(&algo_task_Struct, (Task_FuncPtr)cyc_algo, &algo_params, NULL);

	/* Construct a Semaphore object to be use as a resource lock, inital count 1 */
	Semaphore_Params_init(&semParams);
	semParams.mode = Semaphore_Mode_BINARY;
	Semaphore_construct(&semStruct, 0, &semParams);

	/* Obtain instance handle */
	semHandle = Semaphore_handle(&semStruct);

	/* Declare and define the heap */
	char buf[2560]; // IN MAU, in CC2650 this is in BYTES

	Error_init(&eb);
	HeapBuf_Params_init(&params);
	params.blockSize = 16; // 16 MAUs = 16 bytes per block
	params.numBlocks = 160; // 160 blocks (16 bytes/block * 160 blocks= 2560 bytes)
	params.buf = (Ptr)buf; // Stores buffer as a character array of bytes
	params.bufSize = 2560; // Number of bytes contained within buffer
	heap_buff = HeapBuf_create(&params, &eb); // Sets all properties for the heap handle
	heap = HeapBuf_Handle_upCast(heap_buff);

    System_printf("Starting BIOS\n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    init_sens_structs();

    /* Start BIOS */
    BIOS_start();

    return (0);
}