Part Number: CC2650
Tool/software: TI-RTOS
Hello,
I have been attempting an issue for so long now I am ready to throw my keyboard at the wall. In hopes of actually completing this job, I have come to reach out for help. The code below defines two tasks. Task 1 is executed first due to its higher priority and then reaches a Semaphore_pend(), at which point the entire program halts (I checked this with a breakpoint).I would like control to be sent over to Task 2 (w/ lower priority here). If I comment out the defining lines of task 2 (where params is set and Task_construct() is called), then the code executes fine (only I need task 2 to be running!)
My goal: Start executing task 1, pend() the task, enter task 2, an alert()/interrupt is called form Sensor controller whose callback calls a post(), control returns to Task 1 until the next pend()... repeat.
Note: if I do not use a breakpoint and run the code, I get the error below... Thank you to the kind soul who will toil to figure this out!
/*
* 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 <ti/sysbios/heaps/HeapBuf.h>
#include <xdc/runtime/Memory.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/IHeap.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 2048
#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 scCtrlReadyCallback(void) {
} // scCtrlReadyCallback
void scTaskAlertCallback(void) {
// 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)
{
static uint16_t dist1 = 0;
// 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();
}
uint8_t fast_counter=0;
// Main loop
while (1) {
// Wait for an ALERT callback
Semaphore_pend(semHandle, BIOS_WAIT_FOREVER);
// Clear the ALERT interrupt source
scifClearAlertIntSource();
UInt32 t = Clock_getTicks();
add_1(t, scifTaskData.i2cLightSensor.output.value[0]);
add_2(t, scifTaskData.i2cLightSensor.output.value[1]);
scifAckAlertEvents();
}
}
Void cyc_algo(UArg arg0, UArg arg1)
{
/* ***Setup for algorithm*** */
// Applies initial data for sensor 1
toggle = 0;
wl[toggle] = 1;
// Waits for data to be available
while(!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
// Applies initial data for sensor 2
toggle = 1;
wl[toggle] = 1;
// Waits for data to be available
while(!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
while (1) {
if (bool_cond[toggle][4]) // Can shift
{
toggle = (toggle == 0) ? 1:0;
// Waits for appropriate data
if (toggle == 0)
{
while(!rm_1(&py_time, &py_dist)){};
}
else
{
while(!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
}
bool_cond[toggle][4] = 1; // Sets can shift to 1
// Multiplexer like functionality
if (wl[toggle] == 1)
{
if (while_loop1())
{
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';
System_flush();
clear_output();
output_ready = 0; // Data has been written to python
}
continue;
}
}
if (wl[toggle] == 2)
{
if (while_loop2())
{
continue;
}
}
if (wl[toggle] == 3)
{
if (while_loop3())
{
continue;
}
}
}
}
//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 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 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 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(¶ms);
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(¶ms, &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);
}