Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
# Conflicts:
#	CMakeLists.txt
  • Loading branch information
JF002 committed Jul 11, 2020
2 parents 0bcaf9c + 6309719 commit 64c1427
Show file tree
Hide file tree
Showing 43 changed files with 562 additions and 9,346 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
project(pinetime VERSION 0.6.2 LANGUAGES C CXX ASM)
project(pinetime VERSION 0.7.0 LANGUAGES C CXX ASM)

set(NRF_TARGET "nrf52")

Expand Down
75 changes: 75 additions & 0 deletions doc/MemoryAnalysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Memory analysis
## FreeRTOS heap and task stack
FreeRTOS statically allocate its own heap buffer in a global variable named `ucHeap`. This is an aray of *uint8_t*. Its size is specified by the definition `configTOTAL_HEAP_SIZE` in *FreeRTOSConfig.h*
FreeRTOS uses this buffer to allocate memory for tasks stack and all the RTOS object created during runtime (timers, mutexes,...).

The function `xPortGetFreeHeapSize()` returns the amount of memory available in this *ucHeap* buffer. If this value reaches 0, FreeRTOS runs out of memory.

```
NRF_LOG_INFO("Free heap : %d", xPortGetFreeHeapSize());
```


The function `uxTaskGetSystemState()` fetches some information about the running tasks like its name and the minimum amount of stack space that has remained for the task since the task was created:

```
TaskStatus_t tasksStatus[10]
auto nb = uxTaskGetSystemState(tasksStatus, 10, NULL);
for (int i = 0; i < nb; i++) {
NRF_LOG_INFO("Task [%s] - %d", tasksStatus[i].pcTaskName, tasksStatus[i].usStackHighWaterMark);
```


## Global heap
Heap is used for **dynamic memory allocation (malloc() / new)**. NRF SDK defaults the heap size to 8KB. The size of the heap can be specified by defining `__HEAP_SIZE=8192` in *src/CMakeLists.txt*:

```
add_definitions(-D__HEAP_SIZE=8192)
```

You can trace the dynamic memory allocation by using the flag `--wrap` of the linker. When this flag is enabled, the linker will replace the calls to a specific function by a call to __wrap_the_function(). For example, if you specify `-Wl,-wrap,malloc` in the linker flags, the linker will replace all calls to `void* malloc(size_t)` by calls to `void* __wrap_malloc(size_t)`. This is a function you'll have to define in your code. In this function, you can call `__real_malloc()` to call the actual `malloc()' function.

This technic allows you to wrap all calls to malloc() with you own code.

In *src/CMakeLists.txt*:

```
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
...
LINK_FLAGS "-Wl,-wrap,malloc ..."
...
)
```

In *main.cpp*:

```
uint32_t totalMalloc = 0;
extern "C" {
extern void* __real_malloc(size_t s);
void *__wrap_malloc(size_t s) {
totalMalloc += s;
return __real_malloc(s);
}
}
```
This function sums all the memory that is allocated during the runtime. You can monitor or log this value. You can also place breakpoints in this function to determine where the dynamic memory allocation occurs in your code.


# Global stack
The stack is used to allocate memory used by functions : **parameters and local variables**. NRF SDK defaults the heap size to 8KB. The size of the heap can be specified by defining `__STACK_SIZE=8192` in *src/CMakeLists.txt*:

```
add_definitions(-D__STACK_SIZE=8192)
```

*NOTE*: FreeRTOS uses its own stack buffer. Thus, the global stack is only used for main() and IRQ handlers. It should be possible to reduce its size to a much lower value.

**NOTE**: [?] How to track the global stack usage?

#LittleVGL buffer
*TODO*

#NimBLE buffers
*TODO*
8 changes: 6 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ set(SDK_SOURCE_FILES
# FreeRTOS
${NRF5_SDK_PATH}/external/freertos/source/croutine.c
${NRF5_SDK_PATH}/external/freertos/source/event_groups.c
${NRF5_SDK_PATH}/external/freertos/source/portable/MemMang/heap_1.c
${NRF5_SDK_PATH}/external/freertos/source/portable/MemMang/heap_4.c
${NRF5_SDK_PATH}/external/freertos/source/list.c
${NRF5_SDK_PATH}/external/freertos/source/queue.c
${NRF5_SDK_PATH}/external/freertos/source/stream_buffer.c
Expand Down Expand Up @@ -363,7 +363,7 @@ list(APPEND SOURCE_FILES
${TINYCRYPT_SRC}
${NIMBLE_SRC}
${LVGL_SRC}
${IMAGE_FILES}
#${IMAGE_FILES}
${SDK_SOURCE_FILES}

DisplayApp/LittleVgl.cpp
Expand Down Expand Up @@ -442,6 +442,8 @@ set(INCLUDE_FILES
libs/date/includes/date/tz_private.h
DisplayApp/LittleVgl.h
SystemTask/SystemTask.h
SystemTask/SystemMonitor.h
DisplayApp/Screens/Symbols.h
)

include_directories(
Expand Down Expand Up @@ -547,6 +549,8 @@ add_definitions(-DOS_CPUTIME_FREQ)
add_definitions(-DNRF52 -DNRF52832 -DNRF52832_XXAA -DNRF52_PAN_74 -DNRF52_PAN_64 -DNRF52_PAN_12 -DNRF52_PAN_58 -DNRF52_PAN_54 -DNRF52_PAN_31 -DNRF52_PAN_51 -DNRF52_PAN_36 -DNRF52_PAN_15 -DNRF52_PAN_20 -DNRF52_PAN_55 -DBOARD_PCA10040)
add_definitions(-DFREERTOS)
add_definitions(-DDEBUG_NRF_USER)
add_definitions(-D__STACK_SIZE=8192)
add_definitions(-D__HEAP_SIZE=8192)

if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
Expand Down
27 changes: 19 additions & 8 deletions src/Components/Ble/AlertNotificationClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,25 @@ int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connect

void AlertNotificationClient::OnNotification(ble_gap_event *event) {
if(event->notify_rx.attr_handle == newAlertHandle) {
size_t notifSize = OS_MBUF_PKTLEN(event->notify_rx.om);
uint8_t data[notifSize + 1];
data[notifSize] = '\0';
os_mbuf_copydata(event->notify_rx.om, 0, notifSize, data);
char *s = (char *) &data[2];
NRF_LOG_INFO("DATA : %s", s);

notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, notifSize + 1);
// TODO implement this with more memory safety (and constexpr)
static const size_t maxBufferSize{21};
static const size_t maxMessageSize{18};
size_t bufferSize = min(OS_MBUF_PKTLEN(event->notify_rx.om), maxBufferSize);

uint8_t data[bufferSize];
os_mbuf_copydata(event->notify_rx.om, 0, bufferSize, data);

char *s = (char *) &data[3];
auto messageSize = min(maxMessageSize, (bufferSize-3));

for (int i = 0; i < messageSize-1; i++) {
if (s[i] == 0x00) {
s[i] = 0x0A;
}
}
s[messageSize-1] = '\0';

notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize);
systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
}
}
Expand Down
34 changes: 19 additions & 15 deletions src/Components/Ble/AlertNotificationService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <SystemTask/SystemTask.h>

#include "AlertNotificationService.h"
#include <cstring>

using namespace Pinetime::Controllers;

Expand Down Expand Up @@ -55,23 +56,26 @@ int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle
struct ble_gatt_access_ctxt *ctxt) {

if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
uint8_t data[notifSize + 1];
data[notifSize] = '\0';
os_mbuf_copydata(ctxt->om, 0, notifSize, data);
char *s = (char *) &data[3];
NRF_LOG_INFO("DATA : %s", s);
// TODO implement this with more memory safety (and constexpr)
static const size_t maxBufferSize{21};
static const size_t maxMessageSize{18};
size_t bufferSize = min(OS_MBUF_PKTLEN(ctxt->om), maxBufferSize);

for(int i = 0; i <= notifSize; i++)
{
if(s[i] == 0x00)
{
s[i] = 0x0A;
}
}
uint8_t data[bufferSize];
os_mbuf_copydata(ctxt->om, 0, bufferSize, data);

char *s = (char *) &data[3];
auto messageSize = min(maxMessageSize, (bufferSize-3));

for (int i = 0; i < messageSize-1; i++) {
if (s[i] == 0x00) {
s[i] = 0x0A;
}
}
s[messageSize-1] = '\0';

m_notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, notifSize + 1);
m_systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
m_notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize);
m_systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
}
return 0;
}
2 changes: 1 addition & 1 deletion src/Components/Ble/DeviceInformationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Pinetime {
static constexpr char* manufacturerName = "Codingfield";
static constexpr char* modelNumber = "1";
static constexpr char* serialNumber = "9.8.7.6.5.4";
static constexpr char* fwRevision = "0.5.0";
static constexpr char* fwRevision = "0.7.0";
static constexpr char* hwRevision = "1.0.0";

static constexpr ble_uuid16_t deviceInfoUuid {
Expand Down
7 changes: 4 additions & 3 deletions src/Components/Ble/NotificationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
using namespace Pinetime::Controllers;

void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category,
const char *message, uint8_t messageSize) {
const char *message, uint8_t currentMessageSize) {
// TODO handle edge cases on read/write index
auto checkedSize = std::min(currentMessageSize, uint8_t{18});
auto& notif = notifications[writeIndex];
std::memcpy(notif.message.data(), message, messageSize);
notif.message[messageSize] = '\0';
std::memcpy(notif.message.data(), message, checkedSize);
notif.message[checkedSize] = '\0';
notif.category = category;

writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
Expand Down
4 changes: 2 additions & 2 deletions src/Components/Ble/NotificationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ namespace Pinetime {
class NotificationManager {
public:
enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage };
static constexpr uint8_t MessageSize = 18;
static constexpr uint8_t MessageSize{18};

struct Notification {
std::array<char, MessageSize> message;
std::array<char, MessageSize+1> message;
Categories category = Categories::Unknown;
};

Expand Down
1 change: 0 additions & 1 deletion src/DisplayApp/DisplayApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <Components/Brightness/BrightnessController.h>
#include <Components/Ble/BleController.h>
#include <Components/DateTime/DateTimeController.h>
#include "Fonts/lcdfont14.h"
#include "../drivers/Cst816s.h"
#include "LittleVgl.h"
#include <date/date.h>
Expand Down
23 changes: 23 additions & 0 deletions src/DisplayApp/Fonts/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#Fonts
* [Jetbrains Mono](https://www.jetbrains.com/fr-fr/lp/mono/)
* [Awesome font from LVGL](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff)

## Generate the fonts:

* Open the [LVGL font converter](https://lvgl.io/tools/fontconverter)
* Name : jetbrains_mono_bold_20
* Size : 20
* Bpp : 1 bit-per-pixel
* Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.woff` and specify the following range : `0x20-0x7f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`

Add new symbols:
* Browse the [cheatsheet](https://fontawesome.com/cheatsheet/free/solid) and find your new symbols
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list
* Convert this hex value into a UTF-8 code using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex)
* Define the new symbols in `src/DisplayApp/Screens/Symbols.h`:
```
static constex char* newSymbol = "\xEF\x86\x85";
```
Loading

0 comments on commit 64c1427

Please sign in to comment.