Part Number: CC1352P
I have successfully loaded and operated Project Zero on the LaunchXL-CC1352P4 Evaluation Board. I am now tying to load it onto my own target hardware (with a CC1352P1F3 micro). The code is getting stuck in a while(1); loop in the Icall_abort() routine. The call stack is as follows:
ICall_abort() at icall.c:2,927 0x0001D874
icall_directAPI() at icall.c:0 0x00014C02
ProjectZero_init() at project_zero.c:569 0x0000015A
ProjectZero_taskFxn() at project_zero.c:687 0x000000D2
When single-stepping, I get to line marked with <<<<<<<< below
/*******************************************************************************
* @fn icall_directAPI
* see headers for details.
*/
uint32_t icall_directAPI( uint8_t service , icall_lite_id_t id, ... )
{
va_list argp;
uint32_t res;
icallLiteMsg_t liteMsg;
// The following will push all parameter in the runtime stack.
// This need to be call before any other local declaration of variable....
va_start(argp, id);
// Test that the API is not called in a Hwi or Swi context
{
BIOS_ThreadType threadtype = BIOS_getThreadType();
if (threadtype == BIOS_ThreadType_Hwi ||
threadtype == BIOS_ThreadType_Swi)
{
#ifdef HALNODEBUG
#else /* ! HALNODEBUG */
ICall_abort();
#endif /* HALNODEBUG */
}
}
// Todo - add string for every icall API function, instead of printing function address
BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : icall_directAPI to BLE func=0x%x, status=%d\n", id, 0);
// Create the message that will be send to the requested service..
liteMsg.hdr.len = sizeof(icallLiteMsg_t);
liteMsg.hdr.next = NULL;
liteMsg.hdr.dest_id = ICALL_UNDEF_DEST_ID;
liteMsg.msg.directAPI = id;
liteMsg.msg.pointerStack = (uint32_t*)(*((uint32_t*)(&argp)));
ICall_sendServiceMsg(ICall_getEntityId(), service,
ICALL_MSG_FORMAT_DIRECT_API_ID, &(liteMsg.msg));
// Since stack needs to always have a higher priority than the thread calling
// the API, when we reach this point the API has been executed by the stack.
// This implies the following:
// - API are not called in critical section or in section where task
// switching is disabled
// It is possible that the stack is blocking on this API, in this case a
// sync object needs to be used in order for this call to resume only when
// the API has been process in full.
{
ICall_Errno errno;
void *pCmdStatus = NULL;
errno = ICall_waitMatch(ICALL_TIMEOUT_PREDEFINE, matchLiteCS, NULL, NULL, <<<<<<<<<<<<<<<< routine times out inside the ICall_waitMatch() routine
(void **)&pCmdStatus);
if (errno == ICALL_ERRNO_TIMEOUT)
{
#ifdef HALNODEBUG
#elif defined(EXT_HAL_ASSERT)
HAL_ASSERT(HAL_ASSERT_CAUSE_ICALL_TIMEOUT);
#else /* !EXT_HAL_ASSERT */
ICall_abort();
#endif /* EXT_HAL_ASSERT */
}
else if (errno == ICALL_ERRNO_SUCCESS)
{
if (pCmdStatus)
{
ICall_freeMsg(pCmdStatus);
}
}
else
{
#ifdef HALNODEBUG
#else /* ! HALNODEBUG */
ICall_abort();
#endif /* HALNODEBUG */
}
}
// The return parameter is set in the runtime stack, at the location of the
// first parameter.
res = liteMsg.msg.pointerStack[0];
va_end(argp);
return (res);
}
ICall_waitMatch(uint_least32_t milliseconds,
ICall_MsgMatchFn matchFn,
ICall_ServiceEnum *src,
ICall_EntityID *dest,
void **msg)
{
Task_Handle taskhandle = Task_self();
ICall_TaskEntry *taskentry = ICall_searchTask(taskhandle);
ICall_MsgQueue prependQueue = NULL;
#ifndef ICALL_EVENTS
uint_fast16_t consumedCount = 0;
#endif
UInt timeout;
uint_fast32_t timeoutStamp;
ICall_Errno errno;
{
BIOS_ThreadType threadtype = BIOS_getThreadType();
if (threadtype == BIOS_ThreadType_Hwi ||
threadtype == BIOS_ThreadType_Swi)
{
/* Blocking call is not allowed from Hwi or Swi.
* Note that though theoretically, Swi or lower priority Hwi may block
* on an event to be generated by a higher priority Hwi, it is not a
* safe practice and hence it is disabled.
*/
return (ICALL_ERRNO_UNKNOWN_THREAD);
}
}
if (!taskentry)
{
return (ICALL_ERRNO_UNKNOWN_THREAD);
}
/* Successful */
if (milliseconds == 0)
{
timeout = BIOS_NO_WAIT;
}
else if (milliseconds == ICALL_TIMEOUT_FOREVER)
{
timeout = BIOS_WAIT_FOREVER;
}
else
{
/* Convert milliseconds to number of ticks */
errno = ICall_msecs2Ticks(milliseconds, &timeout);
if (errno != ICALL_ERRNO_SUCCESS)
{
return (errno);
}
}
errno = ICALL_ERRNO_TIMEOUT;
timeoutStamp = Clock_getTicks() + timeout;
#ifdef ICALL_LITE
while(ICALL_SYNC_HANDLE_PEND_WM(taskentry->syncHandle, timeout))
#else /* !ICALL_LITE */
while (ICALL_SYNC_HANDLE_PEND(taskentry->syncHandle, timeout))
#endif /* ICALL_LITE */
{
ICall_EntityID fetchSrc;
ICall_EntityID fetchDst;
ICall_ServiceEnum servId;
void *fetchMsg;
errno = ICall_fetchMsg(&fetchSrc, &fetchDst, &fetchMsg);
if (errno == ICALL_ERRNO_SUCCESS)
{
if (ICall_primEntityId2ServiceId(fetchSrc, &servId) ==
ICALL_ERRNO_SUCCESS)
{
if (matchFn(servId, fetchDst, fetchMsg))
{
/* Matching message found*/
if (src != NULL)
{
*src = servId;
}
if (dest != NULL)
{
*dest = fetchDst;
}
*msg = fetchMsg;
errno = ICALL_ERRNO_SUCCESS;
break;
}
}
/* Message was received but it wasn't expected one.
* Add to the prepend queue */
ICall_msgEnqueue(&prependQueue, fetchMsg);
#ifdef ICALL_EVENTS
/* Event are binary semaphore, so if several messsages are posted while
* we are processing one, it's possible that some of them are 'missed' and
* not processed. Sending a event to ourself force this loop to run until
* all the messages in the queue are processed.
*/
#ifdef ICALL_LITE
ICALL_SYNC_HANDLE_POST_WM(taskentry->syncHandle);
#else /* !ICALL_LITE */
ICALL_SYNC_HANDLE_POST(taskentry->syncHandle);
#endif /* ICALL_LITE*/
#endif /* ICALL_EVENTS */
}
/* Prepare for timeout exit */
errno = ICALL_ERRNO_TIMEOUT;
#ifndef ICALL_EVENTS
/* Keep the decremented semaphore count */
consumedCount++;
#endif /* ICALL_EVENTS */
if (timeout != BIOS_WAIT_FOREVER &&
timeout != BIOS_NO_WAIT)
{
/* Readjust timeout */
UInt newTimeout = timeoutStamp - Clock_getTicks();
if (newTimeout == 0 || newTimeout > timeout)
{
break;
}
timeout = newTimeout;
}
}
#ifdef ICALL_EVENTS
/*
* Because Events are binary semaphores, the task's queue must be checked for
* any remaining messages. If there are, the ICall event flag must be
* re-posted due to it being cleared on the last pend.
*/
ICall_primRepostSync();
#endif //ICALL_EVENTS
/* Prepend retrieved irrelevant messages */
ICall_msgPrepend(&taskentry->queue, prependQueue);
#ifndef ICALL_EVENTS
/* Re-increment the consumed semaphores */
for (; consumedCount > 0; consumedCount--)
{
Semaphore_post(taskentry->syncHandle);
}
#endif /* ICALL_EVENTS */
return (errno);
}
Looking for a message showing up when it's NOT supposed to is a lot easier to debug than looking for a message that's not showing up that IS supposed to.
Can anyone help?