zz

Dependencies:   WS2812 PixelArray final_project

Files at this revision

API Documentation at this revision

Comitter:
kimhyunjun
Date:
Sun Jun 16 17:35:35 2019 +0000
Commit message:
aaa

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
Adafruit_GFX.lib Show annotated file Show diff for this revision Revisions of this file
CONTRIBUTING.md Show annotated file Show diff for this revision Revisions of this file
PixelArray.lib Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
WS2812.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
stats_report.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r c96221a59771 .gitignore
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
diff -r 000000000000 -r c96221a59771 Adafruit_GFX.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adafruit_GFX.lib	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/teams/final_project/code/final_project/#bd4bee2283a2
diff -r 000000000000 -r c96221a59771 CONTRIBUTING.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CONTRIBUTING.md	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,5 @@
+# Contributing to Mbed OS
+
+Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor.
+
+To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/mbed-os/latest/contributing/index.html).
diff -r 000000000000 -r c96221a59771 PixelArray.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PixelArray.lib	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/chris/code/PixelArray/#b45a70faaa83
diff -r 000000000000 -r c96221a59771 README.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,152 @@
+# Getting started example for Mbed OS
+
+This guide reviews the steps required to get Blinky with the addition of dynamic OS statistics working on an Mbed OS platform. (Note: To see a rendered example you can import into the Arm Online Compiler, please see our [quick start](https://os.mbed.com/docs/mbed-os/latest/quick-start/online-with-the-online-compiler.html#importing-the-code).)
+
+Please install [Mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli).
+
+## Import the example application
+
+From the command-line, import the example:
+
+```
+mbed import mbed-os-example-blinky
+cd mbed-os-example-blinky
+```
+
+### Now compile
+
+Invoke `mbed compile`, and specify the name of your platform and your favorite toolchain (`GCC_ARM`, `ARM`, `IAR`). For example, for the Arm Compiler:
+
+```
+mbed compile -m K64F -t ARM
+```
+
+Your PC may take a few minutes to compile your code. At the end, you see the following result:
+
+```
+[snip]
+
+Image: ./BUILD/K64F/GCC_ARM/mbed-os-example-blinky.bin
+```
+
+### Program your board
+
+1. Connect your Mbed device to the computer over USB.
+1. Copy the binary file to the Mbed device.
+1. Press the reset button to start the program.
+
+The LED on your platform turns on and off. The main thread will additionally take a snapshot of the device's runtime statistics and display it over serial to your PC. The snapshot includes:
+
+* System Information:
+    * Mbed OS Version: Will currently default to 999999
+    * Compiler ID
+        * ARM = 1
+        * GCC_ARM = 2
+        * IAR = 3
+    * [CPUID Register Information](#cpuid-register-information)
+    * [Compiler Version](#compiler-version)
+* CPU Statistics
+    * Percentage of runtime that the device has spent awake versus in sleep
+* Heap Statistics
+    * Current heap size
+    * Max heap size which refers to the largest the heap has grown to
+* Thread Statistics
+    * Provides information on all running threads in the OS including
+        * Thread ID
+        * Thread Name
+        * Thread State
+        * Thread Priority
+        * Thread Stack Size
+        * Thread Stack Space
+
+#### Compiler Version
+
+| Compiler | Version Layout |
+| -------- | -------------- |
+| ARM      | PVVbbbb (P = Major; VV = Minor; bbbb = build number) |
+| GCC      | VVRRPP  (VV = Version; RR = Revision; PP = Patch)    |
+| IAR      | VRRRPPP (V = Version; RRR = Revision; PPP = Patch)   |
+
+#### CPUID Register Information
+
+| Bit Field | Field Description | Values |
+| --------- | ----------------- | ------ |
+|[31:24]    | Implementer       | 0x41 = ARM |
+|[23:20]    | Variant           | Major revision 0x0  =  Revision 0 |
+|[19:16]    | Architecture      | 0xC  = Baseline Architecture |
+|           |                   | 0xF  = Constant (Mainline Architecture) |
+|[15:4]     | Part Number       | 0xC20 =  Cortex-M0 |
+|           |                   | 0xC60 = Cortex-M0+ |
+|           |                   | 0xC23 = Cortex-M3  |
+|           |                   | 0xC24 = Cortex-M4  |
+|           |                   | 0xC27 = Cortex-M7  |
+|           |                   | 0xD20 = Cortex-M23 |
+|           |                   | 0xD21 = Cortex-M33 |
+|[3:0]      | Revision          | Minor revision: 0x1 = Patch 1 |
+
+
+
+You can view individual examples and additional API information of the statistics collection tools at the bottom of the page in the [related links section](#related-links).
+
+
+### Output
+
+To view the serial output you can use any terminal client of your choosing such as [PuTTY](http://www.putty.org/) or [CoolTerm](http://freeware.the-meiers.org/). Unless otherwise specified, printf defaults to a baud rate of 9600 on Mbed OS.
+
+You can find more information on the Mbed OS configuration tools and serial communication in Mbed OS in the related [related links section](#related-links).
+
+The output should contain the following block transmitted at the blinking LED frequency (actual values may vary depending on your target, build profile, and toolchain):
+
+```
+=============================== SYSTEM INFO  ================================
+Mbed OS Version: 999999
+CPU ID: 0x410fc241
+Compiler ID: 2
+Compiler Version: 60300
+RAM0: Start 0x20000000 Size: 0x30000
+RAM1: Start 0x1fff0000 Size: 0x10000
+ROM0: Start 0x0 Size: 0x100000
+================= CPU STATS =================
+Idle: 98% Usage: 2%
+================ HEAP STATS =================
+Current heap: 1096
+Max heap size: 1096
+================ THREAD STATS ===============
+ID: 0x20001eac
+Name: main_thread
+State: 2
+Priority: 24
+Stack Size: 4096
+Stack Space: 3296
+
+ID: 0x20000f5c
+Name: idle_thread
+State: 1
+Priority: 1
+Stack Size: 512
+Stack Space: 352
+
+ID: 0x20000f18
+Name: timer_thread
+State: 3
+Priority: 40
+Stack Size: 768
+Stack Space: 664
+
+```
+
+## Troubleshooting
+
+If you have problems, you can review the [documentation](https://os.mbed.com/docs/latest/tutorials/debugging.html) for suggestions on what could be wrong and how to fix it.
+
+## Related Links
+
+* [Mbed OS Stats API](https://os.mbed.com/docs/latest/apis/mbed-statistics.html)
+* [Mbed OS Configuration](https://os.mbed.com/docs/latest/reference/configuration.html)
+* [Mbed OS Serial Communication](https://os.mbed.com/docs/latest/tutorials/serial-communication.html)
+
+### License and contributions
+
+The software is provided under Apache-2.0 license. Contributions to this project are accepted under the same license. Please see contributing.md for more info.
+
+This project contains code from other projects. The original license text is included in those source files. They must comply with our license guide.
diff -r 000000000000 -r c96221a59771 WS2812.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WS2812.lib	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/bridadan/code/WS2812/#6e647820f587
diff -r 000000000000 -r c96221a59771 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,464 @@
+#include "mbed.h"
+#include "WS2812.h"
+#include "PixelArray.h"
+#include "Adafruit_SSD1306.h"
+
+#include "time.h"
+
+#define LOW 0
+#define HIGH 1
+#define KEY2 0x18                 //Key:2 
+#define KEY7 0x42                 //Key:2 
+#define KEY9 0x4A                 //Key:2 
+#define KEY8 0x52                 //Key:8 
+#define KEY4 0x08                 //Key:4 
+#define KEY6 0x5A                 //Key:6 
+#define KEY1 0x0C                 //Key:1 
+#define KEY3 0x5E                 //Key:3 
+#define KEY5 0x1C                 //Key:5
+#define Repeat 0xFF               //press and hold the key
+#define Minus 0x07;
+#define Plus 0x15;
+#define PIN 7
+
+
+#define WS2812_BUF 77   //number of LEDs in the array
+#define NUM_COLORS 6    //number of colors to store in the array
+#define NUM_STEPS 8    //number of steps between colors
+#define I2C_ADDR (0x20)
+
+//사용 중인 핀 : D4, D5, D6, D7, D9, D10, D11, D12, D13, D14, D15
+// A0, A1, A2, A3
+PixelArray px(WS2812_BUF);
+//WS2812 ws(D7, WS2812_BUF, 0, 5, 5, 0);
+WS2812 ws(D7, WS2812_BUF, 6,17,9,14);   //nucleo-f411re
+
+//HCSR04 sensor(D3, D2,pc,0.5);
+DigitalIn IR(D4);
+InterruptIn remote(D4);
+SPI spi(D11, D12, D13);
+DigitalOut spi_cs(D10,1);
+I2C i2c(I2C_SDA, I2C_SCL);
+Adafruit_SSD1306_I2c myOled(i2c, D9, 0x78, 64, 128);
+
+
+PwmOut PWMA(D6);    //left motor speed
+PwmOut PWMB(D5);    //right motor speed
+DigitalOut AIN1(A1);    //Mortor-L backward
+DigitalOut AIN2(A0);    //Motor-L forward
+DigitalOut BIN1(A2);    //Mortor-R forward
+DigitalOut BIN2(A3);    //Mortor-R backward
+
+
+int printflag = 0;
+int value=0;
+int index=0;
+int lspeed = 2000;
+int rspeed = 2000;
+int speed=2000;
+int leftcnt = 0;
+int oledflag=0;
+int values[] = {0,0,0,0,0};
+int whiteMin[]={1000,1000,1000,1000,1000};
+int blackMax[]={0,0,0,0,0};
+int distancecnt=0;
+int stopcnt = 0;
+int exitcnt =0;
+
+int driveflag=0;
+volatile int flag;
+volatile int TRflag=0;
+
+char IR_decode(unsigned char * code, unsigned char * result1,unsigned char * result2,unsigned char * result3);
+
+unsigned char results;
+unsigned char results1;
+unsigned char results2;
+unsigned char results3;
+
+void IR_interrupt();
+void translateIR();
+
+
+int s=1000;
+void forward(int s);
+void backward(int s);
+void right(int s);
+void left(int s);
+
+void stop();
+void setting();
+void rx_ISR(void);
+void whiteTR();
+void blackTR();
+
+
+unsigned long n = 0;
+
+int color_set(uint8_t red,uint8_t green, uint8_t blue)
+{
+  return ((red<<16) + (green<<8) + blue);   
+}
+
+// 0 <= stepNumber <= lastStepNumber
+int interpolate(int startValue, int endValue, int stepNumber, int lastStepNumber)//
+{
+    return (endValue - startValue) * stepNumber / lastStepNumber + startValue;
+}
+
+
+int main(void)
+{
+    
+    int colorIdx = 0;
+    int colorTo = 0;
+    int colorFrom = 0;
+    
+    uint8_t ir = 0;
+    uint8_t ig = 0;
+    uint8_t ib = 0;
+    
+    clock_t start, end;
+    //LED제어/////////////////////////////////////////////////////////////////////////////////////
+    ws.useII(WS2812::PER_PIXEL); // use per-pixel intensity scaling
+    int colorbuf[NUM_COLORS] = {0x2f0000,0x2f2f00,0x002f00,0x002f2f};
+ 
+
+
+    
+//    sensor.setMode(true);
+    remote.fall(&IR_interrupt);
+    setting(); 
+    spi.format(16,0);
+    spi.frequency(2000000);
+    while(driveflag<2)
+    {
+        if(results == KEY7 && TRflag ==1)       
+        {
+            whiteTR();
+            printf("=======================================================\r\n");
+            wait_us(21);
+            driveflag++;
+
+        }
+            
+        if(results == KEY9 && TRflag ==1) 
+        {
+            blackTR();
+            printf("=======================================================\r\n");
+            wait_us(21);
+            driveflag++;
+
+        }
+    }
+    while(driveflag<3){ wait(1);}                   
+    start=clock();
+    myOled.printf("\n\n\nRun!");
+    myOled.display();
+
+    while(1)
+    {
+        for(int i=0; i<6; i++)           
+        {
+            spi_cs=0;
+            wait_us(2);
+            value=spi.write(i<<12);
+            spi_cs=1;
+            wait_us(21);
+            value=value>>6;
+            if(i>0 && i<6)
+            {
+                values[5-i]=value;
+            }
+            
+        }
+        
+
+        if(values[0]*0.8<blackMax[0] &&values[1]*0.8<blackMax[1] &&values[2]*0.8<blackMax[2] &&values[3]*0.8<blackMax[3] && values[4]*0.8<blackMax[4])       
+        {
+            backward(1800);          
+            forward(2300);       
+            stopcnt++;
+            if(stopcnt>20)                
+            {
+                stop();
+                wait(3);                 
+                end=clock();               
+                if(oledflag==0)              
+                {
+                    myOled.printf("\rDriving time: %.2f",((float)(end-start)/CLOCKS_PER_SEC));
+                    myOled.display();
+                    oledflag=1;
+                }
+                break;
+            }
+        }
+        else if(values[4]*0.7<blackMax[4] && values[0]*1.2>whiteMin[0])            
+        {
+            stopcnt=0;
+            forward(2300);
+            left(2300);
+        }
+        else if(values[0]*0.7<blackMax[0]&& values[4]*1.2>whiteMin[4])         
+        {
+            stopcnt=0;
+            forward(2300);
+            right(2300);
+
+        }
+
+        else{                                 
+            stopcnt=0;
+            forward(2300);
+        }
+            
+        
+    }
+    while(1)      
+    {
+    std::size_t c1 = colorbuf[colorFrom];
+    std::size_t r1 = (c1 & 0xff0000) >> 16;
+    std::size_t g1 = (c1 & 0x00ff00) >> 8;
+    std::size_t b1 = (c1 & 0x0000ff);
+        
+    //get ending RGB components for interpolation
+    std::size_t c2 = colorbuf[colorTo];
+    std::size_t r2 = (c2 & 0xff0000) >> 16;
+    std::size_t g2 = (c2 & 0x00ff00) >> 8;
+    std::size_t b2 = (c2 & 0x0000ff);
+    
+    for (int i = 0; i <= NUM_STEPS; i++)
+    {       
+        ir = interpolate(r1, r2, i, NUM_STEPS);
+        ig = interpolate(g1, g2, i, NUM_STEPS);
+        ib = interpolate(b1, b2, i, NUM_STEPS);
+            
+                    //write the color value for each pixel
+        px.SetAll(color_set(ir,ig,ib));
+            
+                    //write the II value for each pixel
+        px.SetAllI(32);
+            
+        for (int i = WS2812_BUF; i >= 0; i--) 
+        {
+            ws.write(px.getBuf());
+        }
+    }
+//        
+    colorFrom = colorIdx;
+    colorIdx++;
+        
+    if (colorIdx >= NUM_COLORS)
+    {
+        colorIdx = 0;
+    }
+            
+    colorTo = colorIdx;
+    wait(1);
+    }
+}
+
+void whiteTR()      
+{
+    whiteMin[0]=1000;
+    whiteMin[1]=1000;
+    whiteMin[2]=1000;
+    whiteMin[3]=1000;
+    whiteMin[4]=1000;
+    for(int j=0; j<100;j++)
+    {
+        for(int i=0; i<7; i++)
+        {
+            spi_cs=0;
+            wait_us(2);
+            value=spi.write(i<<12);
+            spi_cs=1;
+            wait_us(21);
+            value=value>>6;
+            if(i>0 && i<6)
+            {
+                if(value<whiteMin[5-i]) whiteMin[5-i]=value/1.4;
+                
+            }
+        }
+    }
+    TRflag=0;
+}
+
+void blackTR()
+{
+    blackMax[0]=0;
+    blackMax[1]=0;
+    blackMax[2]=0;
+    blackMax[3]=0;
+    blackMax[4]=0;
+    for(int j=0; j<100;j++)
+    {
+        for(int i=0; i<7; i++)
+        {
+            spi_cs=0;
+            wait_us(2);
+            value=spi.write(i<<12);
+            spi_cs=1;
+            wait_us(21);
+            value=value>>6;
+            if(i>0 && i<6)
+            {
+                if(value>blackMax[5-i]) blackMax[5-i]=value*1.7;
+                
+            }
+        }
+    }
+    TRflag=0;
+}
+
+void translateIR() 
+{  
+  switch(results)
+  {
+    case KEY1:
+      driveflag++;
+      return;
+    case KEY2: 
+      forward(1500);
+      return;
+    case KEY3: 
+      lspeed-=50;
+      rspeed-=50;
+      PWMA.pulsewidth_us(lspeed);
+      PWMB.pulsewidth_us(rspeed);
+      return;
+    case KEY4: 
+      left(1000);
+      return;
+    case KEY5: 
+      stop();
+      return;
+    case KEY6: 
+      right(1000);
+      return;
+    case KEY7: 
+      TRflag=1;
+      return;
+    case KEY8: 
+      backward(1500);
+      return;
+    case KEY9: 
+      TRflag = 1;
+      return;
+
+    }// End Case
+}
+
+char IR_decode(unsigned char * code, unsigned char * result1,unsigned char * result2,unsigned char * result3)
+{
+  char flag = 0;
+  unsigned int count = 0;
+  unsigned char i, index, cnt = 0, data[4] = {0, 0, 0, 0};
+  if (IR.read() == LOW)
+  {
+    count = 0;
+    while (IR.read() == LOW && count++ < 200)  //9ms
+      wait_us(60);
+    count = 0;
+    while (IR.read() == HIGH && count++ < 80)   //4.5ms
+      wait_us(60);
+    for (i = 0; i < 32; i++)
+    {
+      count = 0;
+      while (IR.read() == LOW && count++ < 15) //0.56ms
+        wait_us(60);
+      count = 0;
+      while (IR.read() == HIGH && count++ < 40) //0: 0.56ms; 1: 1.69ms
+        wait_us(60);
+      if (count > 20)data[index] |= (1 << cnt);
+      if (cnt == 7)
+      {
+        cnt = 0;
+        index++;
+      }
+      else cnt++;
+    }
+    if (data[0] + data[1] == Repeat && data[2] + data[3] == Repeat) //check
+    {
+      code[0] = data[2];
+      result1[0] = data[3];
+      result2[0] = data[0];
+      result3[0] = data[1];
+      printflag=1;
+      flag = 1;
+      translateIR();
+      return flag;
+    }
+    if (data[0] == Repeat && data[1] == Repeat && data[2] == Repeat && data[3] == Repeat)
+    {
+      code[0] = Repeat;
+      flag = 1;
+      return flag;
+    }
+  }
+  return flag;
+}
+
+void forward(int speed)
+{
+  PWMA.pulsewidth_us(speed);
+  PWMB.pulsewidth_us(speed);
+  AIN1.write(0);
+  AIN2.write(1);
+  BIN1.write(0);
+  BIN2.write(1);
+}
+
+void backward(int s)
+{
+  PWMA.pulsewidth_us(s);
+  PWMB.pulsewidth_us(s);
+  AIN1.write(1);
+  AIN2.write(0);
+  BIN1.write(1);
+  BIN2.write(0);
+}
+
+void right(int s)
+{
+
+  PWMA.pulsewidth_us(s);
+  PWMB.pulsewidth_us(s);
+  AIN1.write(0);
+  AIN2.write(1);
+  BIN1.write(1);
+  BIN2.write(0);
+}
+
+void left(int s)
+{
+  PWMA.pulsewidth_us(s);
+  PWMB.pulsewidth_us(s);
+  AIN1.write(1);
+  AIN2.write(0);
+  BIN1.write(0);
+  BIN2.write(1);
+}
+
+
+
+void stop()
+{
+  PWMA.pulsewidth_us(0);
+  PWMB.pulsewidth_us(0);
+  AIN1.write(0);
+  AIN2.write(0);
+  BIN1.write(0);
+  BIN2.write(0);
+}
+
+void setting(){
+  PWMA.period_ms(10);
+  PWMB.period_ms(10);
+}
+
+void IR_interrupt()
+{
+    IR_decode(&results, &results1,&results2, &results3);
+}
\ No newline at end of file
diff -r 000000000000 -r c96221a59771 mbed-os.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#2fd0c5cfbd83fce62da6308f9d64c0ab64e1f0d6
diff -r 000000000000 -r c96221a59771 stats_report.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stats_report.h	Sun Jun 16 17:35:35 2019 +0000
@@ -0,0 +1,132 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 ARM Limited
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef STATS_REPORT_H
+#define STATS_REPORT
+
+#include "mbed.h"
+
+/**
+ *  System Reporting library. Provides runtime information on device:
+ *      - CPU sleep, idle, and wake times
+ *      - Heap and stack usage
+ *      - Thread information
+ *      - Static system information
+ */
+class SystemReport {
+    mbed_stats_heap_t   heap_stats;
+    mbed_stats_cpu_t    cpu_stats;
+    mbed_stats_sys_t    sys_stats;
+
+    mbed_stats_thread_t *thread_stats;
+    uint8_t   thread_count;
+    uint8_t   max_thread_count;
+    uint32_t  sample_time_ms;
+
+public:
+    /**
+     *  SystemReport - Sample rate in ms is required to handle the CPU percent awake logic
+     */
+    SystemReport(uint32_t sample_rate) : max_thread_count(8), sample_time_ms(sample_rate)
+    {
+        thread_stats = new mbed_stats_thread_t[max_thread_count];
+
+        // Collect the static system information
+        mbed_stats_sys_get(&sys_stats);
+
+        printf("=============================== SYSTEM INFO  ================================\r\n");
+        printf("Mbed OS Version: %ld \r\n", sys_stats.os_version);
+        printf("CPU ID: 0x%lx \r\n", sys_stats.cpu_id);
+        printf("Compiler ID: %d \r\n", sys_stats.compiler_id);
+        printf("Compiler Version: %ld \r\n", sys_stats.compiler_version);
+
+        for (int i = 0; i < MBED_MAX_MEM_REGIONS; i++) {
+            if (sys_stats.ram_size[i] != 0) {
+                printf("RAM%d: Start 0x%lx Size: 0x%lx \r\n", i, sys_stats.ram_start[i], sys_stats.ram_size[i]);
+            }
+        }
+        for (int i = 0; i < MBED_MAX_MEM_REGIONS; i++) {
+            if (sys_stats.rom_size[i] != 0) {
+                printf("ROM%d: Start 0x%lx Size: 0x%lx \r\n", i, sys_stats.rom_start[i], sys_stats.rom_size[i]);
+            }
+        }
+    }
+
+    ~SystemReport(void)
+    {
+        free(thread_stats);
+    }
+
+    /**
+     *  Report on each Mbed OS Platform stats API
+     */
+    void report_state(void)
+    {
+        report_cpu_stats();
+        report_heap_stats();
+        report_thread_stats();
+
+        // Clear next line to separate subsequent report logs
+        printf("\r\n");
+    }
+
+    /**
+     *  Report CPU idle and awake time in terms of percentage
+     */
+    void report_cpu_stats(void)
+    {
+        static uint64_t prev_idle_time = 0;
+
+        printf("================= CPU STATS =================\r\n");
+
+        // Collect and print cpu stats
+        mbed_stats_cpu_get(&cpu_stats);
+
+        uint64_t diff = (cpu_stats.idle_time - prev_idle_time);
+        uint8_t idle = (diff * 100) / (sample_time_ms * 1000);  // usec;
+        uint8_t usage = 100 - ((diff * 100) / (sample_time_ms * 1000));  // usec;;
+        prev_idle_time = cpu_stats.idle_time;
+
+        printf("Idle: %d%% Usage: %d%% \r\n", idle, usage);
+    }
+
+    /**
+     *  Report current heap stats. Current heap refers to the current amount of
+     *  allocated heap. Max heap refers to the highest amount of heap allocated
+     *  since reset.
+     */
+    void report_heap_stats(void)
+    {
+        printf("================ HEAP STATS =================\r\n");
+
+        // Collect and print heap stats
+        mbed_stats_heap_get(&heap_stats);
+
+        printf("Current heap: %lu\r\n", heap_stats.current_size);
+        printf("Max heap size: %lu\r\n", heap_stats.max_size);
+    }
+
+    /**
+     *  Report active thread stats
+     */
+    void report_thread_stats(void)
+    {
+        printf("================ THREAD STATS ===============\r\n");
+
+        // Collect and print running thread stats
+        int count = mbed_stats_thread_get_each(thread_stats, max_thread_count);
+
+        for (int i = 0; i < count; i++) {
+            printf("ID: 0x%lx \r\n",        thread_stats[i].id);
+            printf("Name: %s \r\n",         thread_stats[i].name);
+            printf("State: %ld \r\n",       thread_stats[i].state);
+            printf("Priority: %ld \r\n",    thread_stats[i].priority);
+            printf("Stack Size: %ld \r\n",  thread_stats[i].stack_size);
+            printf("Stack Space: %ld \r\n", thread_stats[i].stack_space);
+        }
+    }
+};
+
+#endif // STATS_REPORT_H