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.

Implementing a semaphore in tirtos_01_basic tutorial

Other Parts Discussed in Thread: SYSBIOS

Hi ,   I am going through the simple link academy tutorial, and at the end of the tirtos_01_basic.  I am stuck trying to get a semaphore to work ( please see the attached file lab1-main.c ).  When I depress the switch, the debugger shows that I am reaching the Semaphore_post() statement on line 112.  What I can't figure out is how to have my function doUrgentWork()running so it will execute the Semaphore_pend() function.  My semaphore urgentWorkSem was declared in the cfg gui.

The code runs as shown, and executes the task of blinking LED1. If I uncomment the statement on line 158, build / load into my sensortag, the code seems to just crash and exit.    

Thank you for any help.

Roy

2158.lab1-main.c
/*
 * Copyright (c) 2015, 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.
 */

/*
 *  ======== lab1-main.c ========
 */

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>   // added 2/8/16

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include <ti/drivers/pin/PINCC26XX.h>   // added 2/4/16



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

/* Driverlib CPU functions, used here for CPUdelay*/
#include <driverlib/cpu.h>

/* Could be anything, like computing primes */
#define FakeBlockingSlowWork()   CPUdelay(12e6)
#define FakeBlockingFastWork()   CPUdelay(3e6)


/* Pin driver handles */
static PIN_Handle pinHandle;

/* Global memory storage for a PIN_Config table */
static PIN_State pinState;

Task_Struct workTask;
Task_Struct urgentTask;
static uint8_t workTaskStack[256];

/*
 * Initial pin configuration table
 *   - LEDs Board_LED1 & Board_LED2 are off after the pin table is initialized.
 *   - Button is set to input with pull-up.
 */
PIN_Config pinTable[] = {
    Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_KEY_RIGHT | PIN_INPUT_EN | PIN_PULLUP,
    PIN_TERMINATE
};

void doWork(void)
{
	PIN_setOutputValue(pinHandle, Board_LED1, 1);
    FakeBlockingSlowWork(); /* Pretend to do something useful but time-consuming */
	PIN_setOutputValue(pinHandle, Board_LED1, 0);
}

Void workTaskFunc(UArg arg0, UArg arg1)
{
    while (1)
    {

    	/* Do work */
    	doWork();

    	/* Wait a while, because doWork should be a periodic thing, not continuous.*/
    	// CPUdelay(24e6);
    	Task_sleep(  (1000E-3) / (Clock_tickPeriod * (1E-6) )  );
    }
}

void pinInterruptHandler(PIN_Handle handle, PIN_Id pinId)
{

    // see the semaphore declared by the cfg file
    Semaphore_post( urgentWorkSem );
}

void doUrgentWork()
{
    while( 1)
    {
        Semaphore_pend( urgentWorkSem, BIOS_WAIT_FOREVER );

        PIN_setOutputValue(pinHandle, Board_LED2, 1);
        FakeBlockingSlowWork(); /* Pretend to do something useful but time-consuming */
        PIN_setOutputValue(pinHandle, Board_LED2, 0);
    }
}

/*
 *  ======== main ========
 *
 */
int main(void)
{


    /* Call board init functions */
    PIN_init(BoardGpioInitTable);

    /* Open LED pins */
    pinHandle = PIN_open(&pinState, pinTable);
    if(!pinHandle) {
        System_abort("Error initializing board pins\n");
    }

    PIN_registerIntCb(pinHandle, pinInterruptHandler);
    PIN_setInterrupt(pinHandle, Board_KEY_RIGHT | PIN_IRQ_NEGEDGE);


    /* Set up the led1 task */
	Task_Params workTaskParams;
	Task_Params_init(&workTaskParams);
	workTaskParams.stackSize = 256;
	workTaskParams.priority = 1;
	workTaskParams.stack = &workTaskStack;

	Task_construct(&workTask, workTaskFunc, &workTaskParams, NULL);

	// the debugger exits on first launch after adding this statement
	//doUrgentWork();

    /* Start kernel. */
    BIOS_start();

    return (0);
}





  • Hi Roy,

    The reason it crashes is likely that you run the doUrgentWork from main() context. In TI-RTOS you are not allowed to pend on semaphores in main- and Hwi/Swi contexts if the timeout for the pend is > 0. Which it is here in your doUrgentWork.

    In the documentation for semaphores (c:\ti\tirtos_xxx_latest\docs\Documentation_Overview....html -> Kernel Runtime API (etc) -> ti -> sysbios -> knl -> semaphore - note how the package path is identical to the include path for the header file) you will find a table telling you about the calling contexts.

    In short you need to run the urgentwork function from a Task that you create. Note that the solution is included in the project, but greyed out. lab1-main-solution.c.

    Best regards,
    Aslak