Hello!
When reading objects of the Generic Profile type, a memory leak of about 1 kB occurs as a result of the "com_readProfileGenericColumns" function. This leak is not fixed after calling the functions "com_readValues" and "com_readProfileGenerics". How and where can I free up occupied memory?
This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.
If you have created profile generic object you must call obj_clear after you don't need it anymore.
This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.
If you have created profile generic object you must call obj_clear after you don't need it anymore.
Hi!
what does the function "com_readProfileGenericColumns" do and where does it store the data?
command "obj_clear(BASE(pg));" does not clear the memory that was occupied by this function
Hi,
com_readProfileGenericColumns reads capture objects from the meter.
I believe I know the reason for your problem. You haven't read the association view. If this is true, objects are not released automatically and you must release them by yourself.
I'll think if there is a generic, easier solution for this. In the meantime, you need to release objects using this method.
int obj_clearProfileGenericCaptureObjects2(gxArray* captureObjects)
{
int ret = DLMS_ERROR_CODE_OK;
int pos;
gxKey* kv;
//Objects are not cleared because client owns them and clears them later.
for (pos = 0; pos != captureObjects->size; ++pos)
{
ret = arr_getByIndex(captureObjects, pos, (void**)&kv);
if (ret != DLMS_ERROR_CODE_OK)
{
break;
}
gxfree(kv->key);
gxfree(kv->value);
}
arr_clear(captureObjects);
return ret;
}
Thank you!
i add at the end of function "com_readProfileGenerics" this code:
for (int i = 0; i < objects.size; ++i)
{
if (oa_getByIndex(&objects, i, &obj) == DLMS_ERROR_CODE_OK) {
obj_clearProfileGenericCaptureObjects2(&((gxProfileGeneric*)obj)->captureObjects);
}
}
Hi!
I have a similar problem. I don't read association view. My code:
void MeterRead() {
uint32_t serverAddress = cl_getServerAddress(1, 1, 2);
DLMS_ERROR_CODE ret;
Hi,
Hi,
This is no happening with our meters. Can you paste trace from received data here?
BR,
Mikko
Hi!
Hi!
debug output from meter (two asks cosem - {0, 0, 99, 98, 13 , 255}; // (gxProfileGeneric) Time correction log)
00> [COMMUNICATION]: sync_bytes {new: 35, total: 35}
00> [COMMUNICATION]: Received buf:
00> 7E A0 21 41 02 21 73 DB D8 81
00> 80 14 05 02 00 80 06 02 00 80
00> 07 04 00 00 00 01 08 04 00 00
00> 00 01 CE 6A 7E
00> [COMMUNICATION]: sync_bytes {new: 58, total: 93}
00> [COMMUNICATION]: Received buf:
00> 7E A0 38 41 02 21 30 60 4D E6
00> E7 00 61 29 A1 09 06 07 60 85
00> 74 05 08 01 01 A2 03 02 01 00
00> A3 05 A1 03 02 01 00 BE 10 04
00> 0E 08 00 06 5F 1F 04 00 00 14
00> 11 00 80 00 07 DE 86 7E
00> [COMMUNICATION]: com_initializeConnection free_ram= 16197
00> [COMMUNICATION]: com_readScalerAndUnits free_ram= 16197
00> [COMMUNICATION]: sync_bytes {new: 75, total: 168}
00> [COMMUNICATION]: Received buf:
00> 7E A0 49 41 02 21 52 C3 13 E6
00> E7 00 C4 01 81 00 01 03 02 04
00> 12 00 08 09 06 00 00 01 00 00
00> FF 0F 02 12 00 00 02 04 12 00
00> 08 09 06 00 00 01 00 01 FF 0F
00> 02 12 00 00 02 04 12 00 03 09
00> 06 00 00 60 08 00 FF 0F 02 12
00> 00 00 FB 0A 7E
00> [COMMUNICATION]: com_readProfileGenericColumns free_ram= 15173
00> [COMMUNICATION]: com_readValues free_ram= 15173
00> [COMMUNICATION]: sync_bytes {new: 24, total: 192}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 74 69 48 E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 06 4D BA 7E
00> [COMMUNICATION]: sync_bytes {new: 24, total: 216}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 96 75 8C E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 80 73 5B 7E
00> [COMMUNICATION]: sync_bytes {new: 54, total: 270}
00> [COMMUNICATION]: Received buf:
00> 7E A0 34 41 02 21 B8 10 32 E6
00> E7 00 C4 01 81 00 01 01 02 03
00> 19 07 D0 01 02 FF 17 36 3B FF
00> 80 00 00 19 07 D0 01 02 FF 17
00> 36 25 FF 80 00 00 06 00 02 B7
00> BB 9B 60 7E
00> [COMMUNICATION]: sync_bytes {new: 133, total: 403}
00> [COMMUNICATION]: Received buf:
00> 7E A0 83 41 02 21 DA 5C 1C E6
00> E7 00 C4 02 81 00 00 00 00 01
00> 00 6C 01 06 02 03 19 07 D0 01
00> 02 FF 17 36 3B FF 80 00 00 19
00> 07 D0 01 02 FF 17 36 25 FF 80
00> 00 00 06 00 02 B7 BB 02 03 19
00> 07 D0 01 04 FF 01 1B 00 FF 80
00> 00 00 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 06 00 04 1E CD
00> 02 03 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 19 07 D0 01 04
00> FF 01 1B 02 FF 80 00 00 06 00
00> 04 1E CF 02 03 19 07 D0 01 04
00> 27 FB 7E
00> [COMMUNICATION]: sync_bytes {new: 117, total: 520}
00> [COMMUNICATION]: Received buf:
00> 7E A0 73 41 02 21 FC CE C7 E6
00> E7 00 C4 02 81 FF 00 00 00 02
00> 00 5C FF 01 1B 00 FF 80 00 00
00> 19 07 D0 01 04 FF 01 1B 00 FF
00> 80 00 00 06 00 04 1E CF 02 03
00> 19 07 E4 03 17 FF 10 27 18 FF
00> 80 00 00 19 07 D0 01 06 FF 0D
00> 15 25 FF 80 00 00 06 00 07 69
00> 53 02 03 19 07 E4 04 14 FF 10
00> 0B 07 FF 80 00 00 19 07 D0 01
00> 01 FF 00 3A 2B FF 80 00 00 06
00> 00 26 4E 01 EC F8 7E
00> [COMMUNICATION]: com_readProfileGenerics free_ram= 14053
00> [COMMUNICATION]: sync_bytes {new: 35, total: 555}
00> [COMMUNICATION]: Received buf:
00> 7E A0 21 41 02 21 73 DB D8 81
00> 80 14 05 02 00 80 06 02 00 80
00> 07 04 00 00 00 01 08 04 00 00
00> 00 01 CE 6A 7E
00> [COMMUNICATION]: sync_bytes {new: 58, total: 613}
00> [COMMUNICATION]: Received buf:
00> 7E A0 38 41 02 21 30 60 4D E6
00> E7 00 61 29 A1 09 06 07 60 85
00> 74 05 08 01 01 A2 03 02 01 00
00> A3 05 A1 03 02 01 00 BE 10 04
00> 0E 08 00 06 5F 1F 04 00 00 14
00> 11 00 80 00 07 DE 86 7E
00> [COMMUNICATION]: com_initializeConnection free_ram= 15205
00> [COMMUNICATION]: com_readScalerAndUnits free_ram= 15205
00> [COMMUNICATION]: sync_bytes {new: 75, total: 688}
00> [COMMUNICATION]: Received buf:
00> 7E A0 49 41 02 21 52 C3 13 E6
00> E7 00 C4 01 81 00 01 03 02 04
00> 12 00 08 09 06 00 00 01 00 00
00> FF 0F 02 12 00 00 02 04 12 00
00> 08 09 06 00 00 01 00 01 FF 0F
00> 02 12 00 00 02 04 12 00 03 09
00> 06 00 00 60 08 00 FF 0F 02 12
00> 00 00 FB 0A 7E
00> [COMMUNICATION]: com_readProfileGenericColumns free_ram= 14693
00> [COMMUNICATION]: com_readValues free_ram= 14693
00> [COMMUNICATION]: sync_bytes {new: 24, total: 712}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 74 69 48 E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 06 4D BA 7E
00> [COMMUNICATION]: sync_bytes {new: 24, total: 736}
00> [COMMUNICATION]: Received buf:
00> 7E A0 16 41 02 21 96 75 8C E6
00> E7 00 C4 01 81 00 06 00 00 00
00> 80 73 5B 7E
00> [COMMUNICATION]: sync_bytes {new: 54, total: 790}
00> [COMMUNICATION]: Received buf:
00> 7E A0 34 41 02 21 B8 10 32 E6
00> E7 00 C4 01 81 00 01 01 02 03
00> 19 07 D0 01 02 FF 17 36 3B FF
00> 80 00 00 19 07 D0 01 02 FF 17
00> 36 25 FF 80 00 00 06 00 02 B7
00> BB 9B 60 7E
00> [COMMUNICATION]: sync_bytes {new: 133, total: 923}
00> [COMMUNICATION]: Received buf:
00> 7E A0 83 41 02 21 DA 5C 1C E6
00> E7 00 C4 02 81 00 00 00 00 01
00> 00 6C 01 06 02 03 19 07 D0 01
00> 02 FF 17 36 3B FF 80 00 00 19
00> 07 D0 01 02 FF 17 36 25 FF 80
00> 00 00 06 00 02 B7 BB 02 03 19
00> 07 D0 01 04 FF 01 1B 00 FF 80
00> 00 00 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 06 00 04 1E CD
00> 02 03 19 07 D0 01 04 FF 01 1B
00> 00 FF 80 00 00 19 07 D0 01 04
00> FF 01 1B 02 FF 80 00 00 06 00
00> 04 1E CF 02 03 19 07 D0 01 04
00> 27 FB 7E
00> [COMMUNICATION]: sync_bytes {new: 117, total: 1040}
00> [COMMUNICATION]: Received buf:
00> 7E A0 73 41 02 21 FC CE C7 E6
00> E7 00 C4 02 81 FF 00 00 00 02
00> 00 5C FF 01 1B 00 FF 80 00 00
00> 19 07 D0 01 04 FF 01 1B 00 FF
00> 80 00 00 06 00 04 1E CF 02 03
00> 19 07 E4 03 17 FF 10 27 18 FF
00> 80 00 00 19 07 D0 01 06 FF 0D
00> 15 25 FF 80 00 00 06 00 07 69
00> 53 02 03 19 07 E4 04 14 FF 10
00> 0B 07 FF 80 00 00 19 07 D0 01
00> 01 FF 00 3A 2B FF 80 00 00 06
00> 00 26 4E 01 EC F8 7E
00> [COMMUNICATION]: com_readProfileGenerics free_ram= 13581
after work com_readProfileGenericColumns free_ram is decrease and never free!
Hi,
Hi,
This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.
If you have created profile generic object you must call obj_clear after you don't need it anymore.
Something like:
gxProfileGeneric pg;
const unsigned char ln[6] = { 0, 0, 99, 98, 13 , 255 };
cosem_init2(BASE(pg), DLMS_OBJECT_TYPE_PROFILE_GENERIC, ln);
//Read data...
//Clear the data.
obj_clear(BASE(pg));
BR,
Mikko
Hi,
Hi,
This is checked and there are no memory leaks.
Can you check your source code. In the example, client calls cl_clear after all the data is collected. cl_clear calls oa_clear and it clears all COSEM objects data calling obj_clear. So all the data is clear.
If you have created profile generic object you must call obj_clear after you don't need it anymore.
Something like:
gxProfileGeneric pg;
const unsigned char ln[6] = { 0, 0, 99, 98, 13 , 255 };
cosem_init2(BASE(pg), DLMS_OBJECT_TYPE_PROFILE_GENERIC, ln);
//Read data...
//Clear the data.
obj_clear(BASE(pg));
BR,
Mikko
Hi!
Hi!
what does the function "com_readProfileGenericColumns" do and where does it store the data?
command "obj_clear(BASE(pg));" does not clear the memory that was occupied by this function
Hi,
Hi,
com_readProfileGenericColumns reads capture objects from the meter.
I believe I know the reason for your problem. You haven't read the association view. If this is true, objects are not released automatically and you must release them by yourself.
I'll think if there is a generic, easier solution for this. In the meantime, you need to release objects using this method.
int obj_clearProfileGenericCaptureObjects2(gxArray* captureObjects)
{
int ret = DLMS_ERROR_CODE_OK;
int pos;
gxKey* kv;
//Objects are not cleared because client owns them and clears them later.
for (pos = 0; pos != captureObjects->size; ++pos)
{
ret = arr_getByIndex(captureObjects, pos, (void**)&kv);
if (ret != DLMS_ERROR_CODE_OK)
{
break;
}
gxfree(kv->key);
gxfree(kv->value);
}
arr_clear(captureObjects);
return ret;
}
BR,
Mikko
Thank you!
Thank you!
i add at the end of function "com_readProfileGenerics" this code:
for (int i = 0; i < objects.size; ++i)
{
if (oa_getByIndex(&objects, i, &obj) == DLMS_ERROR_CODE_OK) {
obj_clearProfileGenericCaptureObjects2(&((gxProfileGeneric*)obj)->captureObjects);
}
}
and memory clean!
Hi,
Hi,
This is now changed. All dynamically created objects are added to dlmsSettings.releasedObjects.
You don't need to do this anymore.
BR,
Mikko
Hi!
Hi!
I have a similar problem. I don't read association view. My code:
void MeterRead() {
uint32_t serverAddress = cl_getServerAddress(1, 1, 2);
DLMS_ERROR_CODE ret;
cl_init(&GxCon.settings, 1, 0x30, serverAddress, DLMS_AUTHENTICATION_HIGH, ADMIN_PASSWORD, DLMS_INTERFACE_TYPE_HDLC);
if (com_initializeConnection(&GxCon) == DLMS_ERROR_CODE_OK) {
gxProfileGeneric Profile;
uint32_t endTime = 1624966136; // Tue Jun 29 2021 11:28:56 GMT+0000
uint32_t startTime = endTime - 12 * 3600; // 12 hours
if (((ret = cosem_init(&Profile.base, DLMS_OBJECT_TYPE_PROFILE_GENERIC, "1.0.99.1.0.255")) == DLMS_ERROR_CODE_OK) &&
((ret = com_read(&GxCon, &Profile.base, 3)) == DLMS_ERROR_CODE_OK) &&
((ret = com_readRowsByRange(&GxCon, &Profile, startTime, endTime)) == DLMS_ERROR_CODE_OK))
{
//
arr_clear(&Profile.captureObjects);
arr_clear(&Profile.buffer);
}
}
if (ret != DLMS_ERROR_CODE_OK) {
PRINT("ERROR %d", ret);
while(1);
}
com_close(&GxCon);
cl_clear(&GxCon.settings);
}
I get "Not enough memory available" at the 15th iteration. What should I free?
Hi,
Hi,
Change this line:
arr_clear(&Profile.buffer);
to:
obj_clearProfileGenericBuffer(&Profile.buffer);
arr_clear doesn't clear the content of the array.
BR,
Mikko
Thanks! It works.
Thanks! It works.