hi NXP team:
After my device is connected to the phone,After testing for a while,Probabilistically, the phone cannot receive data,At the same time, there is an error Log on my device
my code
static void BleApp_GattServerCallback (deviceId_t deviceId, gattServerEvent_t* pServerEvent)
{
uint16_t handle;
uint8_t status;
uint8_t i;
#if DEBUG_BLUETOOTH
PRINTF("BleApp_GattServerCallback=%d\r\n",pServerEvent->eventType);
#endif
switch (pServerEvent->eventType)
{
case gEvtError_c:
{
PRINTF("stephen gEvtError_c:error:0x%x,procedureType:0x%x\r\n",pServerEvent->eventData.procedureError.error,pServerEvent->eventData.procedureError.procedureType);
}
break;
case gEvtAttributeWritten_c:
{
handle = pServerEvent->eventData.attributeWrittenEvent.handle;
status = gAttErrCodeNoError_c;
GattServer_SendAttributeWrittenStatus(deviceId, handle, status);
}
break;
case gEvtHandleValueConfirmation_c:
{
BleApp_HandleValueConfirmation (deviceId);
}
break;
default:
break;
}
}
from the log we got:
BleApp_GattServerCallback=5 ----> gEvtError_c, /*!< An error appeared during a Server-initiated procedure. */
stephen gEvtError_c:error:0x5(gBleOutOfMemory_c = gBleStatusBase_c | 0x05, /*!< An internal memory allocation failed. */),procedureType:0x2( gSendNotification_c, /*!< Procedure initiated by GattServer_SendNotification. */)
I have been stuck with this problem for a long time,i need nxp team help
Hi,
Hope you are doing well. Could you please clarify what device are you using? Are you using one of our Development Boards? What SDK example are you using as a base? What modifications did you make?
Could you add the following definitions in your code?
#define gUsePanic_c 1
#define MEM_TRACKING
#define MEM_STATISTICS
#define MEM_DEBUG
#define MEM_DEBUG_OUT_OF_MEMORY
With this, we might be able to identify the issue you are facing, as the definitions trigger some Panic() and print some memory logs.
Best Regards,
Ricardo
hi nxp team:
To this question,
There is a new discovery
for my code
#define mHeartRateReportInterval_c (10)
BleApp_StartHeartRate(mHeartRateReportInterval_c);
void BleApp_StartHeartRate(uint16_t mtime)
{
TMR_StartLowPowerTimer(mHeartRateMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c,
TmrMilliseconds(mtime), HeartRateMeasurementTimerCallback, NULL);
}
when i change mHeartRateReportInterval_c from 10ms to 20ms,
#define mHeartRateReportInterval_c (10) change to #define mHeartRateReportInterval_c (20)
There's nothing wrong with it,and no error:procedureError gBleOutOfMemory_c
but When mheartrateReportInterval_c is less than 10,there are must be a err:procedureError gBleOutOfMemory_c,and for our need,mheartrateReportInterval_c must set to 10ms,How to solve this problem?
i will do that
#define gUsePanic_c 1 #define MEM_TRACKING #define MEM_STATISTICS #define MEM_DEBUG #define MEM_DEBUG_OUT_OF_MEMORY
and Reply as soon as possible
hi nxp team:
after i add:
#define gUsePanic_c 1 #define MEM_TRACKING #define MEM_STATISTICS #define MEM_DEBUG #define MEM_DEBUG_OUT_OF_MEMORY
framework\memmanager\source\MemManager.c
void* MEM_BufferAllocWithId
(
uint32_t numBytes,
uint8_t poolId,
void *pCaller
){
{
#ifdef MEM_TRACKING
/* Save the Link Register */
volatile uint32_t savedLR = (uint32_t) __get_LR();
#endif
#if defined(MEM_TRACKING) || defined(MEM_DEBUG_OUT_OF_MEMORY)
uint16_t requestedSize = numBytes;
#endif /*MEM_TRACKING*/
#ifdef MEM_STATISTICS
bool_t allocFailure = FALSE;
#endif
pools_t *pPools = memPools;
listHeader_t *pBlock;
OSA_InterruptDisable();
while(numBytes)
{
if( (numBytes <= pPools->blockSize) && (poolId == pPools->poolId) )
{
pBlock = (listHeader_t *)ListRemoveHead((listHandle_t)&pPools->anchor);
if(NULL != pBlock)
{
pBlock++;
gFreeMessagesCount--;
pPools->allocatedBlocks++;
#ifdef MEM_STATISTICS
if(gFreeMessagesCount < gFreeMessagesCountMin)
{
gFreeMessagesCountMin = gFreeMessagesCount;
}
pPools->poolStatistics.allocatedBlocks++;
if ( pPools->poolStatistics.allocatedBlocks > pPools->poolStatistics.allocatedBlocksPeak )
{
pPools->poolStatistics.allocatedBlocksPeak = pPools->poolStatistics.allocatedBlocks;
}
MEM_ASSERT(pPools->poolStatistics.allocatedBlocks <= pPools->poolStatistics.numBlocks);
#endif /*MEM_STATISTICS*/
#ifdef MEM_TRACKING
//PRINTF("stephen panic MEM_BufferAllocWithId MEM_TRACKING_ALLOC_c\r\n");
MEM_Track(pBlock, MEM_TRACKING_ALLOC_c, savedLR, requestedSize, pCaller);
#endif /*MEM_TRACKING*/
OSA_InterruptEnable();
return pBlock;
}
else
{
#ifdef MEM_STATISTICS
if(!allocFailure)
{
pPools->poolStatistics.allocationFailures++;
allocFailure = TRUE;
}
#endif /*MEM_STATISTICS*/
if(numBytes > pPools->nextBlockSize)
{
break;
}
/* No more blocks of that size, try next size. */
numBytes = pPools->nextBlockSize;
}
}
/* Try next pool*/
if(pPools->nextBlockSize)
{
pPools++;
}
else
{
numBytes = 0;
}
}
#ifdef MEM_DEBUG_OUT_OF_MEMORY
if (requestedSize)
{
PRINTF("stephen panic MEM_BufferAllocWithId requestedSize\r\n");
panic( 0, (uint32_t)MEM_BufferAllocWithId, 0, 0);
}
#endif
OSA_InterruptEnable();
return NULL;
}
===
When the problem recurs we got the log:
stephen Hrs_SendNotifications
stephen Hrs result:0x0
stephen Hrs_SendNotifications
stephen Hrs result:0x0
stephen panic MEM_BufferAllocWithId requestedSize
stephen panic id:0x0,location:0x283f1
}
Thank you for your reply
we use the device:MKW31Z512XXX4
base sdk is:SDK_2.X_MKW31Z512XXX4
we modifications:
#define mHeartRateReportInterval_c (10)
static void BleApp_ConnectionCallback (deviceId_t peerDeviceId, gapConnectionEvent_t* pConnectionEvent)
{
---->
switch (pConnectionEvent->eventType)
{
case gConnEvtConnected_c:
{
Hrs_Subscribe(peerDeviceId);
BleApp_StartHeartRate(mHeartRateReportInterval_c);
break;
}
....
}
--->void BleApp_StartHeartRate(uint16_t mtime)
{
TMR_StartLowPowerTimer(mHeartRateMeasurementTimerId, gTmrLowPowerIntervalMillisTimer_c,
TmrMilliseconds(mtime), HeartRateMeasurementTimerCallback, NULL);
}
----->
static hrsUserData_t hrsUserData;
static hrsConfig_t hrsServiceConfig = {service_heart_rate, TRUE, FALSE, TRUE, gHrs_BodySensorLocOther_c, &hrsUserData};
void HeartRateMeasurementTimerCallback(void * pParam)
{
uint16_t hr=0,hs=0,energy = 0;
rtc_datetime_t date;
uint16_t hr_l = 0,hr_c=0,hr_r=0;
hr_l = ADC16_Mic0();
hs = hr_c = ADC16_Mic1();
hr_r = ADC16_Mic2();
hr=(hr_r + hr_l)/2 - hr_c;
if(hr < 0)
hr = 0;
if(hrsUserData.cRrIntervals == gHrs_NumOfRRIntervalsRecorded_c){
if(hs < hs_tmp)
hs = hs_tmp;
hs_tmp = 0;
Hrs_AddExpendedEnergy(&hrsUserData, energy,hs);
Hrs_RecordHeartRateMeasurement(service_heart_rate, hr, &hrsUserData);
}else
{
//PRINTF("stephen not 7 hr=0x%x,hs=0x%x,hs_tmp=0x%x\r\n",hr,hs,hs_tmp);
if(hs > hs_tmp)
hs_tmp = hs;//add stephen
Hrs_RecordRRInterval(&hrsUserData,hr);
}
}
==============
for Hrs_RecordHeartRateMeasurement
typedef struct hrsUserData_tag
{
#if gHrs_EnableRRIntervalMeasurements_d
/*! Heart Rate Service - RR Interval Measurements Buffer*/
uint16_t *pStoredRrIntervals;
/*! Heart Rate Service - RR Interval Count*/
uint8_t cRrIntervals;
/*! Heart Rate Service - Current Position in RR Interval Measurements Vector*/
uint8_t rrCursor;
#endif
/*! Heart Rate Service - Expended Energy Values */
uint16_t expendedEnergy;
uint16_t adc_Hs;
}hrsUserData_t;
void Hrs_AddExpendedEnergy(hrsUserData_t *pHrsUserData, uint16_t energy,uint16_t hs)
{
pHrsUserData->expendedEnergy = energy;// no use
pHrsUserData->adc_Hs = hs;
}
bleResult_t Hrs_RecordHeartRateMeasurement (uint16_t serviceHandle, uint16_t heartRate, hrsUserData_t *pHrsUserData)
{
uint16_t hValueHrMeasurement;
bleResult_t result;
bleUuid_t uuid = Uuid16(gBleSig_HrMeasurement_d);
//PRINTF("Hrs_RecordHeartRateMeasurement\r\n");
/* Get handle of Heart Rate Measurement characteristic */
result = GattDb_FindCharValueHandleInService(serviceHandle,
gBleUuidType16_c, &uuid, &hValueHrMeasurement);
if (result != gBleSuccess_c)
return result;
/* Update characteristic value and send notification */
if (!Hrs_UpdateHrmCharacteristic(hValueHrMeasurement, heartRate, pHrsUserData))
{
Hrs_SendNotifications(hValueHrMeasurement);
}
return gBleSuccess_c;
}
====
for Hrs_UpdateHrmCharacteristic
#define Hrs_MaxNotificationSize 20
static uint8_t characteristic[Hrs_MaxNotificationSize];
static bleResult_t Hrs_UpdateHrmCharacteristic
(
uint16_t handle,
uint16_t heartRate,
hrsUserData_t *pHrsUserData
){
{
uint8_t index = 0;
uint8_t flag = 0;
uint32_t date_s;
#if gHrs_EnableRRIntervalMeasurements_d
uint8_t iRRIntervalsCount;
#endif
/* Add flags */
Hrs_GetHrmFlags(handle, &flag);//add stephen
/* Add HR Value*/
if (Hrs_GetHeartRateFormat(heartRate) & gHrs_16BitHeartRateFormat_c)
{
//PRINTF("stephen HR Value 16 bit\r\n");
//characteristic[0] |= gHrs_16BitHeartRateFormat_c;//modify stephen
flag |= gHrs_16BitHeartRateFormat_c;
FLib_MemCpy(&characteristic[index], &heartRate, sizeof(uint16_t));
index++;
}
else
{
//characteristic[0] &= ~gHrs_16BitHeartRateFormat_c; //modify stephen
flag |= gHrs_16BitHeartRateFormat_c;//add stephen
characteristic[index] = (uint8_t) heartRate;
}
index++;
if (characteristic[0] & gHrs_SensorContactSupported_c)
{
//uint16_t nr = ADC16_Mic1();
uint16_t nr = pHrsUserData->adc_Hs;
FLib_MemCpy(&characteristic[index], &nr, sizeof(uint16_t));
index += sizeof(uint16_t);
}
if (flag & gHrs_EnergyExpendedEnabled_c)//add stephen
{
FLib_MemCpy(&characteristic[index], &pHrsUserData->expendedEnergy, sizeof(uint16_t));
index += sizeof(uint16_t);
}
#if gHrs_EnableRRIntervalMeasurements_d
/* Add RR Intervals */
if (pHrsUserData->cRrIntervals > 0)
{
iRRIntervalsCount = MIN(
(Hrs_MaxNotificationSize - index) / sizeof(uint16_t),
pHrsUserData->cRrIntervals);
//characteristic[0] |= gHrs_RrIntervalsEnabled_c; //modify stephen
flag |= gHrs_RrIntervalsEnabled_c; //add stephen
//PRINTF("stephen indexa=%d,iRRIntervalsCount=%d,cRrIntervals=%d,Hrs_MaxNotificationSize=%d\r\n",index,iRRIntervalsCount,pHrsUserData->cRrIntervals,Hrs_MaxNotificationSize);
if (pHrsUserData->rrCursor + iRRIntervalsCount > gHrs_NumOfRRIntervalsRecorded_c)
{
FLib_MemCpy(&characteristic[index],
&pHrsUserData->pStoredRrIntervals[pHrsUserData->rrCursor],
(gHrs_NumOfRRIntervalsRecorded_c - pHrsUserData->rrCursor)
* sizeof(uint16_t));
index += (gHrs_NumOfRRIntervalsRecorded_c - pHrsUserData->rrCursor) * sizeof(uint16_t);
FLib_MemCpy(&characteristic[index], &pHrsUserData->pStoredRrIntervals[0],
(iRRIntervalsCount + pHrsUserData->rrCursor
- gHrs_NumOfRRIntervalsRecorded_c) * sizeof(uint16_t));
index += (iRRIntervalsCount + pHrsUserData->rrCursor
- gHrs_NumOfRRIntervalsRecorded_c) * sizeof(uint16_t);
//PRINTF("stephen indexb=%d\r\n",index);
}
else
{
FLib_MemCpy(&characteristic[index],
&pHrsUserData->pStoredRrIntervals[0],
iRRIntervalsCount * sizeof(uint16_t));
index += iRRIntervalsCount * sizeof(uint16_t);
//PRINTF("stephen indexc=%d\r\n",index);
}
/* Update circular buffer */
pHrsUserData->rrCursor = (pHrsUserData->rrCursor + iRRIntervalsCount)
% gHrs_NumOfRRIntervalsRecorded_c;
pHrsUserData->cRrIntervals -= iRRIntervalsCount;
}
#endif /* gHrs_EnableRRIntervalMeasurements_d */
return GattDb_WriteAttribute(handle, index, &characteristic[0]);
}
}
===
bluetooth\profiles\heart_rate
PRIMARY_SERVICE(service_heart_rate, gBleSig_HeartRateService_d)
CHARACTERISTIC(char_hr_measurement, gBleSig_HrMeasurement_d, (gGattCharPropNotify_c))
VALUE_VARLEN(value_hr_measurement, gBleSig_HrMeasurement_d, (gPermissionNone_c), 20, 2, 0x00, 0xB4)
CCCD(cccd_hr_measurement)
CHARACTERISTIC(char_body_sensor_location, gBleSig_BodySensorLocation_d, (gGattCharPropRead_c) )
VALUE(value_body_sensor_location, gBleSig_BodySensorLocation_d, (gPermissionFlagReadable_c), 1, 0x01)
CHARACTERISTIC(char_hr_ctrl_point, gBleSig_HrControlPoint_d, (gGattCharPropWrite_c | gGattCharPropRead_c) )
VALUE(value_hr_ctrl_point, gBleSig_HrControlPoint_d, (gPermissionFlagReadable_c | gPermissionFlagWritable_c), 7, 20,19,9,2,14,19,30)