Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Battery Reporting to FindMy #76

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/webhook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ on:
- "Build"
- "Lint"
- "Release"
- "SonarCloud"
- "Submodules"
types:
- "completed"
issues:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@
[submodule "documentation/doxygen/doxygen-awesome-css"]
path = documentation/doxygen/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css.git
[submodule "lib/tlsf"]
path = lib/tlsf
url = https://github.com/espressif/tlsf
2 changes: 1 addition & 1 deletion .pvsoptions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -e lib/tlsf -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/microtar -e lib/mlib -e lib/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e lib/mjs -e */arm-none-eabi/*
262 changes: 258 additions & 4 deletions applications/debug/unit_tests/furi/furi_memmgr_test.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#include "../minunit.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <furi.h>

void test_furi_memmgr(void) {
void* ptr;
Expand Down Expand Up @@ -37,3 +34,260 @@ void test_furi_memmgr(void) {
}
free(ptr);
}

static void test_memmgr_malloc(const size_t allocation_size) {
uint8_t* ptr = NULL;
const char* error_message = NULL;

FURI_CRITICAL_ENTER();

ptr = malloc(allocation_size);

// test that we can allocate memory
if(ptr == NULL) {
error_message = "malloc failed";
}

// test that memory is zero-initialized after allocation
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] != 0) {
error_message = "memory is not zero-initialized after malloc";
break;
}
}
memset(ptr, 0x55, allocation_size);
free(ptr);

// test that memory is zero-initialized after free
// we know that allocator can use this memory for inner purposes
// so we check that memory at least partially zero-initialized

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuse-after-free"

size_t zero_count = 0;
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] == 0) {
zero_count++;
}
}

#pragma GCC diagnostic pop

// check that at least 75% of memory is zero-initialized
if(zero_count < (allocation_size * 0.75)) {
error_message = "seems that memory is not zero-initialized after free (malloc)";
}

FURI_CRITICAL_EXIT();

if(error_message != NULL) {
mu_fail(error_message);
}
}

static void test_memmgr_realloc(const size_t allocation_size) {
uint8_t* ptr = NULL;
const char* error_message = NULL;

FURI_CRITICAL_ENTER();

ptr = realloc(ptr, allocation_size);

// test that we can allocate memory
if(ptr == NULL) {
error_message = "realloc(NULL) failed";
}

// test that memory is zero-initialized after allocation
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] != 0) {
error_message = "memory is not zero-initialized after realloc(NULL)";
break;
}
}

memset(ptr, 0x55, allocation_size);

ptr = realloc(ptr, allocation_size * 2);

// test that we can reallocate memory
if(ptr == NULL) {
error_message = "realloc failed";
}

// test that memory content is preserved
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] != 0x55) {
error_message = "memory is not reallocated after realloc";
break;
}
}

// test that remaining memory is zero-initialized
size_t non_zero_count = 0;
for(size_t i = allocation_size; i < allocation_size * 2; i++) {
if(ptr[i] != 0) {
non_zero_count += 1;
}
}

// check that at most of memory is zero-initialized
// we know that allocator not always can restore content size from a pointer
// so we check against small threshold
if(non_zero_count > 4) {
error_message = "seems that memory is not zero-initialized after realloc";
}

uint8_t* null_ptr = realloc(ptr, 0);

// test that we can free memory
if(null_ptr != NULL) {
error_message = "realloc(0) failed";
}

// test that memory is zero-initialized after realloc(0)
// we know that allocator can use this memory for inner purposes
// so we check that memory at least partially zero-initialized

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuse-after-free"

size_t zero_count = 0;
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] == 0) {
zero_count++;
}
}

#pragma GCC diagnostic pop

// check that at least 75% of memory is zero-initialized
if(zero_count < (allocation_size * 0.75)) {
error_message = "seems that memory is not zero-initialized after realloc(0)";
}

FURI_CRITICAL_EXIT();

if(error_message != NULL) {
mu_fail(error_message);
}
}

static void test_memmgr_alloc_aligned(const size_t allocation_size, const size_t alignment) {
uint8_t* ptr = NULL;
const char* error_message = NULL;

FURI_CRITICAL_ENTER();

ptr = aligned_alloc(alignment, allocation_size);

// test that we can allocate memory
if(ptr == NULL) {
error_message = "aligned_alloc failed";
}

// test that memory is aligned
if(((uintptr_t)ptr % alignment) != 0) {
error_message = "memory is not aligned after aligned_alloc";
}

// test that memory is zero-initialized after allocation
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] != 0) {
error_message = "memory is not zero-initialized after aligned_alloc";
break;
}
}
memset(ptr, 0x55, allocation_size);
free(ptr);

// test that memory is zero-initialized after free
// we know that allocator can use this memory for inner purposes
// so we check that memory at least partially zero-initialized

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuse-after-free"

size_t zero_count = 0;
for(size_t i = 0; i < allocation_size; i++) {
if(ptr[i] == 0) {
zero_count++;
}
}

#pragma GCC diagnostic pop

// check that at least 75% of memory is zero-initialized
if(zero_count < (allocation_size * 0.75)) {
error_message = "seems that memory is not zero-initialized after free (aligned_alloc)";
}

FURI_CRITICAL_EXIT();

if(error_message != NULL) {
mu_fail(error_message);
}
}

void test_furi_memmgr_advanced(void) {
const size_t sizes[] = {50, 100, 500, 1000, 5000, 10000};
const size_t sizes_count = sizeof(sizes) / sizeof(sizes[0]);
const size_t alignments[] = {4, 8, 16, 32, 64, 128, 256, 512, 1024};
const size_t alignments_count = sizeof(alignments) / sizeof(alignments[0]);

// do test without memory fragmentation
{
for(size_t i = 0; i < sizes_count; i++) {
test_memmgr_malloc(sizes[i]);
}

for(size_t i = 0; i < sizes_count; i++) {
test_memmgr_realloc(sizes[i]);
}

for(size_t i = 0; i < sizes_count; i++) {
for(size_t j = 0; j < alignments_count; j++) {
test_memmgr_alloc_aligned(sizes[i], alignments[j]);
}
}
}

// do test with memory fragmentation
{
void* blocks[sizes_count];
void* guards[sizes_count - 1];

// setup guards
for(size_t i = 0; i < sizes_count; i++) {
blocks[i] = malloc(sizes[i]);
if(i < sizes_count - 1) {
guards[i] = malloc(sizes[i]);
}
}

for(size_t i = 0; i < sizes_count; i++) {
free(blocks[i]);
}

// do test
for(size_t i = 0; i < sizes_count; i++) {
test_memmgr_malloc(sizes[i]);
}

for(size_t i = 0; i < sizes_count; i++) {
test_memmgr_realloc(sizes[i]);
}

for(size_t i = 0; i < sizes_count; i++) {
for(size_t j = 0; j < alignments_count; j++) {
test_memmgr_alloc_aligned(sizes[i], alignments[j]);
}
}

// cleanup guards
for(size_t i = 0; i < sizes_count - 1; i++) {
free(guards[i]);
}
}
}
2 changes: 2 additions & 0 deletions applications/debug/unit_tests/furi/furi_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ void test_furi_concurrent_access(void);
void test_furi_pubsub(void);

void test_furi_memmgr(void);
void test_furi_memmgr_advanced(void);

static int foo = 0;

Expand Down Expand Up @@ -37,6 +38,7 @@ MU_TEST(mu_test_furi_memmgr) {
// this test is not accurate, but gives a basic understanding
// that memory management is working fine
test_furi_memmgr();
test_furi_memmgr_advanced();
}

MU_TEST_SUITE(test_suite) {
Expand Down
Loading
Loading