Part Number: EVMK2G
Tool/software: Code Composer Studio
Hi,
I have the below code to achieve that UART_write should send some data only after acquiring a semaphore from a SWI thread. Below are issues I face.
Issue 1 - The UART_write does not wait for the semaphore instead it prints only once the data on console and exits.
Issue 2 - If the below lines are commented out, then the UART_write happens continuously
1. data_to_send[34] = (0x30+((i++)%9));
2. Semaphore_pend(callbackSem, SemaphoreP_WAIT_FOREVER);
Issue 3 - clockHandler does not get executes
// main.c
/*
* ======== main.c ========
*/
#include "typedefs.h"
#include <stdio.h>
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/clock.h>
#include <ti/sysbios/knl/Idle.h>
#include <ti/sysbios/knl/Task.h>
#include <xdc/cfg/global.h>
/* CSL Header files */
#include <ti/csl/csl_chip.h>
#include <ti/csl/soc.h>
/* OSAL Header files */
#include <ti/osal/osal.h>
/* UART Header files */
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
#include <ti/drv/uart/soc/UART_soc.h>
#include <ti/drv/uart/test/src/UART_board.h>
#include <ti/drv/uart/src/UART_osal.h>
#include <ti/csl/csl_clec.h>
/* Global variable definitions for UART Working*/
Semaphore_Handle callbackSem;
UART_PAR uartParity = UART_PAR_NONE;
uint32_t uartTestInstance;
int16_t verifyLoopback = 0U;
EDMA3_RM_Handle gEdmaHandle = NULL;
uint32_t var=0;
/* Task Functions and Semaphores */
void init_task(UArg arg0, UArg arg1);
void task_uart(UArg arg0, UArg arg1);
void clockHandler(UArg arg);
Semaphore_Handle sem;
/* Function prototypes */
static void UART_test_write(UART_Handle uart, bool dmaMode);
static EDMA3_RM_Handle UartApp_edmaInit(void);
/*
* Initialize the edma driver and get the handle to the edma driver;
*/
static EDMA3_RM_Handle UartApp_edmaInit(void){
EDMA3_DRV_Result edmaResult = EDMA3_DRV_E_INVALID_PARAM;
uint32_t edma3Id;
uint32_t edmaEvent[2], i, chnMapping, chnMappingIdx;
/* For Keystone devices, edm3Id is UART instance and SoC specific */
UART_getEdmaInfo(uartTestInstance, &edma3Id, edmaEvent);
/* Set the RX/TX ownDmaChannels and dmaChannelHwEvtMap */
for (i = 0; i < 2; i++)
{
chnMapping = edmaEvent[i];
if (chnMapping < 32)
chnMappingIdx = 0;
else
{
chnMapping -= 32;
chnMappingIdx = 1;
}
sampleInstInitConfig[edma3Id][0].ownDmaChannels[chnMappingIdx] |= (1 << chnMapping);
sampleInstInitConfig[edma3Id][0].ownTccs[chnMappingIdx] |= (1 << chnMapping);
sampleInstInitConfig[edma3Id][0].ownPaRAMSets[chnMappingIdx] |= (1 << chnMapping);
sampleEdma3GblCfgParams[edma3Id].dmaChannelHwEvtMap[chnMappingIdx] |= (1 << chnMapping);
}
if (gEdmaHandle != NULL)
{
return(gEdmaHandle);
}
gEdmaHandle = (EDMA3_RM_Handle)edma3init(edma3Id, &edmaResult);
if (edmaResult != EDMA3_DRV_SOK) {
/* Report EDMA Error */
System_printf("\nEDMA driver initialization FAIL\n");
} else {
System_printf("\nEDMA driver initialization PASS.\n");
}
return(gEdmaHandle);
}
/*
* ======== UART init config ========
*/
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
static void UART_initConfig(bool dmaMode){
UART_HwAttrs uart_cfg;
/* Get the default UART init configurations */
UART_socGetInitCfg(uartTestInstance, &uart_cfg);
if (dmaMode == true) {
uart_cfg.edmaHandle = UartApp_edmaInit();
uart_cfg.dmaMode = TRUE;
} else {
uart_cfg.edmaHandle = NULL;
uart_cfg.dmaMode = FALSE;
}
if(verifyLoopback) {
uart_cfg.loopback = TRUE;
} else {
uart_cfg.loopback = FALSE;
}
/* Set the DMA enabled UART init configurations */
UART_socSetInitCfg(uartTestInstance, &uart_cfg);
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
void UART_getTestInstNum(uint32_t *instNum, bool *boardAM570x){
*instNum = UART_INSTANCE;
*boardAM570x = false;
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
bool Board_initUART(void){
Board_initCfg boardCfg;
Board_STATUS boardStatus;
bool boardAM570x;
boardCfg = BOARD_INIT_PINMUX_CONFIG | BOARD_INIT_MODULE_CLOCK;
boardStatus = Board_init(boardCfg);
if (boardStatus != BOARD_SOK) {
return (false);
}
UART_getTestInstNum(&uartTestInstance, &boardAM570x);
return (true);
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
static uintptr_t l2_global_address (uintptr_t addr){
uint32_t corenum;
/* Get the core number. */
corenum = CSL_chipReadReg (CSL_CHIP_DNUM);
/* Compute the global address. */
return (addr + (0x10000000 + (corenum * 0x1000000)));
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
void clockHandler(UArg arg) {
static unsigned int i=0;
// post semaphore only after a second. i increments for every 1ms
if (i++>1000)
{
System_printf("Semaphore posted\n");
Semaphore_post(callbackSem);
i=0;
}
}
/*-------------------------------------------------------------------------------------------------------------------*/
/*
* ======== UART write test ========
*
* The test function tests read/write in blocking mode
*/
static void UART_test_write(UART_Handle uart, bool dmaMode)
{
uintptr_t addrDataPrint;
unsigned char data_to_send[] = "New number filled for iteration - \r\n";
static unsigned int i=0;
//Modify the data every time the task executes
data_to_send[34] = (0x30+((i++)%9));
if (uart != NULL) {
if (dmaMode) {
addrDataPrint = l2_global_address((uintptr_t)data_to_send);
} else {
addrDataPrint = (uintptr_t)data_to_send;
}
// wait until someone posts a semaphore to send the data
Semaphore_pend(callbackSem, SemaphoreP_WAIT_FOREVER);
//Write the data packet now
UART_write(uart, (void *)addrDataPrint, sizeof(data_to_send));
} else {
//Semaphore_delete(callbackSem);
callbackSem = NULL;
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
void init_task(UArg arg0, UArg arg1) {
Task_Handle task_uarti;
Task_Params taskParams;
UART_Handle uart = NULL;
UART_Params uartParams;
Error_Block eb;
uint16 taskkey;
uint32 delay=0, i;
System_printf("\nInitialization task begins here");
//Call board init
if (Board_initUART() == false)
{
System_printf("\nBoard_init UART failed!\n");
//return(0);
}
//Call UART init
UART_init();
/* UART SoC init configuration */
UART_initConfig(true);
/* Initialize the default configuration params. */
UART_Params_init(&uartParams);
uartParams.parityType = uartParity;
uart = UART_open(uartTestInstance, &uartParams);
while (1)
{
UART_test_write(uart, true);
}
}
/*
* ======== main ========
*/
/*-------------------------------------------------------------------------------------------------------------------*/
Int main()
{
Task_Params taskParams;
Task_Handle init_taski, dummy_taski;
SemaphoreP_Params semParams;
Clock_Params clkParams;
Clock_Handle myclk;
Error_Block eb;
// Initialization of Error block
Error_init(&eb);
System_printf("enter main()\n");
//Initialize the task parameters
Task_Params_init(&taskParams);
taskParams.stackSize = 1024;
taskParams.priority = 5;
init_taski = Task_create((Task_FuncPtr)init_task, &taskParams, &eb);
if (init_taski == NULL){
System_printf("\n Init Task creation failed\n");
}
Clock_Params_init(&clkParams);
// I believe this gives one msecond period
clkParams.period = 1000;
clkParams.startFlag = TRUE;
myclk = Clock_create((Clock_FuncPtr)clockHandler, clkParams.period, &clkParams, &eb);
/* Create call back semaphore */
callbackSem = Semaphore_create(0, NULL, &eb);
if(callbackSem == NULL){
System_abort("Semaphore create failed!\n");
}
BIOS_start(); /* does not return */
return(0);
}
config file is as below
app.cfg
var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags = xdc.useModule('xdc.runtime.Diags');
var Error = xdc.useModule('xdc.runtime.Error');
var Log = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Main = xdc.useModule('xdc.runtime.Main');
var Memory = xdc.useModule('xdc.runtime.Memory')
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text = xdc.useModule('xdc.runtime.Text');
var BIOS = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Swi = xdc.useModule('ti.sysbios.knl.Swi');
var Task = xdc.useModule('ti.sysbios.knl.Task');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
/*
* Uncomment this line to globally disable Asserts.
* All modules inherit the default from the 'Defaults' module. You
* can override these defaults on a per-module basis using Module.common$.
* Disabling Asserts will save code space and improve runtime performance.
Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
*/
/*
* Uncomment this line to keep module names from being loaded on the target.
* The module name strings are placed in the .const section. Setting this
* parameter to false will save space in the .const section. Error and
* Assert messages will contain an "unknown module" prefix instead
* of the actual module name.
Defaults.common$.namedModule = false;
*/
/*
* Minimize exit handler array in System. The System module includes
* an array of functions that are registered with System_atexit() to be
* called by System_exit().
*/
System.maxAtexitHandlers = 4;
/*
* Uncomment this line to disable the Error print function.
* We lose error information when this is disabled since the errors are
* not printed. Disabling the raiseHook will save some code space if
* your app is not using System_printf() since the Error_print() function
* calls System_printf().
Error.raiseHook = null;
*/
/*
* Uncomment this line to keep Error, Assert, and Log strings from being
* loaded on the target. These strings are placed in the .const section.
* Setting this parameter to false will save space in the .const section.
* Error, Assert and Log message will print raw ids and args instead of
* a formatted message.
Text.isLoaded = false;
*/
/*
* Uncomment this line to disable the output of characters by SysMin
* when the program exits. SysMin writes characters to a circular buffer.
* This buffer can be viewed using the SysMin Output view in ROV.
SysMin.flushAtExit = false;
*/
/*
* The BIOS module will create the default heap for the system.
* Specify the size of this default heap.
*/
BIOS.heapSize = 0x2000;
/*
* Build a custom SYS/BIOS library from sources.
*/
BIOS.libType = BIOS.LibType_Custom;
/* System stack size (used by ISRs and Swis) */
Program.stack = 0x1000;
/* Circular buffer size for System_printf() */
SysMin.bufSize = 0x1000;
/*
* Create and install logger for the whole system
*/
var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 16;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;
System.SupportProxy = SysMin;
/* install a BIOS startup function */
//BIOS.addUserStartupFunction('&myBiosStartup');
Clock.timerId = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
var Edma = xdc.loadPackage ("ti.sdo.edma3.drv.sample");
var drv = xdc.loadPackage ("ti.sdo.edma3.drv");
var rm = xdc.loadPackage ("ti.sdo.edma3.rm");
var CpIntc = xdc.useModule('ti.sysbios.family.c66.tci66xx.CpIntc');
var Hwi = xdc.useModule('ti.sysbios.family.c64p.Hwi');
var ECM = xdc.useModule('ti.sysbios.family.c64p.EventCombiner');
var Cache = xdc.useModule('ti.sysbios.hal.Cache');
var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
var devType = "k2g"
/* Load the OSAL package */
var osType = "tirtos"
var Osal = xdc.useModule('ti.osal.Settings');
Osal.osType = osType;
Osal.socType = devType;
/* Load CSL settings */
var Csl = xdc.loadPackage('ti.csl');
Csl.Settings.deviceType = devType;
/* Create a default system heap using ti.bios.HeapMem. */
var heapMemParams1 = new HeapMem.Params;
heapMemParams1.size = 8192 * 25;
heapMemParams1.sectionName = ".systemHeap";
Program.global.heap0 = HeapMem.create(heapMemParams1);
/* Load the Board package and set the board name */
var Board = xdc.loadPackage('ti.board');
Board.Settings.boardName = "evmK2G";
/* Load Profiling package */
//var Utils = xdc.loadPackage('ti.utils.profiling');
/* Load the uart package */
var Uart = xdc.loadPackage('ti.drv.uart');
//Uart.Settings.enableProfiling = true;
Uart.Settings.socType = devType;
Uart.Settings.useDma = "true";
/* No runtime stack checking is performed */
Task.checkStackFlag = false;
/* Enable BIOS Task Scheduler */
BIOS.taskEnabled = true;
ECM.eventGroupHwiNum[0] = 7;
ECM.eventGroupHwiNum[1] = 8;
ECM.eventGroupHwiNum[2] = 9;
ECM.eventGroupHwiNum[3] = 10;
/*
* Enable Event Groups here and registering of ISR for specific GEM INTC is done
* using EventCombiner_dispatchPlug() and Hwi_eventMap() APIs
*/
var exception = xdc.useModule('ti.sysbios.family.c64p.Exception');
exception.enablePrint = true;