this is using the mbed os version 5-13-1
Revision 92:ec9550034276, committed 2019-04-13
- Comitter:
- ocomeni
- Date:
- Sat Apr 13 14:17:29 2019 +0000
- Parent:
- 91:d6b6319ad681
- Child:
- 93:06e755a80187
- Commit message:
- implemented DEFINE switch to resolve mbed memory pool allocation failure
Changed in this revision
--- a/mbed_app.json Sun Apr 07 17:31:56 2019 +0000
+++ b/mbed_app.json Sat Apr 13 14:17:29 2019 +0000
@@ -36,7 +36,7 @@
"MBED_MEM_TRACING_ENABLED=1",
"MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=0",
"MBEDTLS_SSL_MAX_CONTENT_LEN=16384",
- "DEBUG_ISR_STACK_USAGE=1",
+ "DEBUG_ISR_STACK_USAGE=0",
"MBED_CONF_APP_ERROR_FILENAME_CAPTURE_ENABLED=1"
],
"target_overrides": {
--- a/source/ATCmdManager.cpp Sun Apr 07 17:31:56 2019 +0000
+++ b/source/ATCmdManager.cpp Sat Apr 13 14:17:29 2019 +0000
@@ -2,6 +2,7 @@
#include "common_config.h"
#include "common_types.h"
#include "http_request.h"
+#include "mbed_memory_status.h"
//#include "mbed_memory_status.h"
ATCmdManager::ATCmdManager(PinName tx, PinName rx, SMDevicePeripheral *blePeripheral,
@@ -64,6 +65,7 @@
printf("\n --- ATCmdManager constructor completed ---\n");
at_resp = AT_RESP_NONE;
dataMode = AT_CMD_DATA_MODE;
+ print_heap_and_isr_stack_info();
event_queue.call_every(3600000,&print_memory_info);
}
@@ -89,7 +91,7 @@
// AT_SCAN_RESP response state
printf("\n [ATCMD MAN] WIFI SCAN RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -97,7 +99,7 @@
// AT_DETAILED_SCAN_RESP response state
printf("\n [ATCMD MAN] WIFI DETAILED SCAN RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -105,7 +107,7 @@
// AT_CONNECT_RESP response state
printf("\n [ATCMD MAN] WIFI CONNECT RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -114,7 +116,7 @@
//////_smutex.lock();
printf("\n [ATCMD MAN] WIFI DISCONNECT RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -123,7 +125,7 @@
//////_smutex.lock();
printf("\n [ATCMD MAN] WIFI CONFIG RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -131,7 +133,7 @@
// AT_CONFIG_RESP response state
printf("\n [ATCMD MAN] WIFI INTERNET_CONFIG RESPONSE RECEIVED!!\n");
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -140,7 +142,7 @@
printf("\n [ATCMD MAN] WIFI HTTPS RESPONSE RECEIVED!!\n");
return_response();
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -149,7 +151,7 @@
printf("\n [ATCMD MAN] WIFI HTTPS DOWNLOAD RESPONSE RECEIVED!!\n");
return_response(true); // set download paramter to true
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -158,7 +160,7 @@
printf("\n [ATCMD MAN] WIFI HTTP RESPONSE RECEIVED!!\n");
return_response();
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -167,7 +169,7 @@
printf("\n [ATCMD MAN] WIFI HTTP RESPONSE RECEIVED!!\n");
return_response(true); // set download paramter to true
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -175,7 +177,7 @@
// UNKNOWN response state
_smutex.lock();
printf("\n [ATCMD MAN] UNKNOWN RESPONSE RECEIVED!!\n");
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
at_resp = AT_RESP_NONE;
break;
@@ -329,7 +331,7 @@
// OOB processing
void ATCmdManager::_process_oob(uint32_t timeout, bool all){
set_timeout(timeout);
- static int cnt = 0;
+ int cnt = 0;
int start;
//channel_id_t chan_id;
if(dataMode == AT_EXT_DATA_MODE)
@@ -337,32 +339,48 @@
int n;
//if(cnt++ % 10 == 0)printf("In EDM mode\n");
uint8_t edm[EDM_HDR_LEN];
-
+ char cmdType[16];
// Poll for edm packets
do{
- n = _parser.read((char *)edm, EDM_HDR_LEN);
+ n = _parser.read((char *)edm, EDM_HDR_LEN-1);
edm_hdr.startByte = edm[0];
edm_hdr.payloadLen = edm[1]*256 + edm[2];
edm_hdr.payloadID = edm[3]*256 + edm[4];
- edm_hdr.channel_id = (channel_id_t) edm[5];
+ edm_hdr.channel_id = (channel_id_t) 0;
start = Kernel::get_ms_count();
if(n == -1) break; // break if it times out
- printf("%d bytes read!\n", n);
- if(n==EDM_HDR_LEN)
+ int pT;
+ if(edm_hdr.payloadID < AT_REQUEST) //
+ {
+ n += _parser.read((char *)edm, 1);
+ edm_hdr.channel_id = (channel_id_t) edm[0];
+ pT = 0;
+ strcpy(cmdType, "DATA COMMAND");
+ }
+ else
+ {
+ pT = 1;
+ strcpy(cmdType, "AT REQUEST");
+ }
+ //printf("%d bytes read! : type = %s\n", n, cmdType2str(edm_hdr.payloadID));
+ printf("%d bytes read! : CMD type = %s\n", n, cmdType);
+ if(n==(EDM_HDR_LEN-pT))
printf("Start = %d, payloadID = %d len = %d chan_id = %d\n", edm_hdr.startByte,
edm_hdr.payloadID,
edm_hdr.payloadLen,
edm_hdr.channel_id);
- if(n == EDM_HDR_LEN && validate(edm_hdr)) // if AT command use process oob to decode
+ if(n == (EDM_HDR_LEN-pT) && validate(edm_hdr)) // if AT command use process oob to decode
{
if(edm_hdr.payloadID == AT_REQUEST)
{
- _parser.process_oob();
+ //_parser.process_oob();
+ while (_parser.process_oob() && all) {
+ }
break;
}
else
{
- int pLen = edm_hdr.payloadLen-2;
+ int pLen = edm_hdr.payloadLen-2-pT;
rx_buf_ptr = (uint8_t *) malloc (pLen); // we already read 2 bytes from payload but expect 1 stop byte
rx_buf_ptr[pLen-1] = 0x00; // clear last byte so the readback value is as expected
n = _parser.read((char *)rx_buf_ptr, pLen);
@@ -391,7 +409,7 @@
printf("DATA_COMMAND received!\n");
if(createHttpRequest() == true){
_smutex.lock();
- _parser.send("OK");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
else{
@@ -399,6 +417,7 @@
_parser.send("NACK");
_smutex.unlock();
}
+ free(rx_buf_ptr);
int stop = Kernel::get_ms_count();
printf("\n Time Elapsed = %d\n", stop-start);
break;
@@ -440,7 +459,7 @@
void ATCmdManager::_oob_ok_hdlr(){
_smutex.lock();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
@@ -473,7 +492,10 @@
//AT+UMRS=230400,2,8,1,1,1
printf("\n Changing Baud Rate to %d\n", uOpts[0]);
+ _parser.send(OK_RESP);
+ wait(0.1);
_serial.set_baud(uOpts[0]);
+ wait(0.1);
printf("\n Baud Rate now %d\n", uOpts[0]);
} else {
@@ -493,7 +515,7 @@
printf("\n Received ATEO OOB command!!\n");
printf("\n turning echo OFF!!\n");
_parser.debug_on(false);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
@@ -504,7 +526,7 @@
printf("\n Received ATE1 OOB command!!\n");
printf("\n turning echo ON!!\n");
_parser.debug_on(true);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
@@ -527,6 +549,7 @@
case 2:
printf("\nATCmdParser: Extended data Mode request received\n");
dataMode = AT_EXT_DATA_MODE;
+ print_heap_and_isr_stack_info();
break;
default:
printf("\nATCmdParser: ERROR - UNKNOWN DATA MODE RECEIVED!!! \n");
@@ -535,7 +558,7 @@
} else {
printf("\nATCmdParser: Retrieving Uart Options failed\n");
}
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
@@ -558,28 +581,28 @@
} else {
printf("\nATCmdParser: Retrieving Uart Options failed");
}
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
void ATCmdManager::_oob_get_ble_role(){
_smutex.lock();
printf("\n Received get BLE role command!!\n");
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
void ATCmdManager::_oob_ena_ble_peri(){
_smutex.lock();
printf("\n Received enable BLE Peripheral command!!\n");
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
}
void ATCmdManager::_oob_reboot(){
_smutex.lock();
printf("\n Received reboot command!!\n");
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_parser.send("System Resetting....\n");
system_reset();
_smutex.unlock();
@@ -617,7 +640,7 @@
void ATCmdManager::_oob_scanWiFiNetworks(){
_smutex.lock();
printf("\n Received scanWiFiNetworks command!!\n");
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
_smutex.unlock();
wifi_cmd_t cmd = WIFI_CMD_SCAN;
// queue next command
@@ -627,7 +650,12 @@
void ATCmdManager::_oob_connect2WiFiNetwork()
{
+ //_smutex.lock();
+ printf("\n Received WiFi Connect command!!\n");
+ _parser.send(OK_RESP);
wifi_cmd_t cmd = WIFI_CMD_CONNECT;
+ printf("\n About to Queue wifi cmd = %d!!\n", cmd);
+ //_smutex.unlock();
// queue next command
queueWiFiCommand(cmd);
return;
@@ -636,7 +664,11 @@
void ATCmdManager::_oob_disconnectWiFiNetwork()
{
+ _smutex.lock();
+ printf("\n Received WiFi Disconnect command!!\n");
+ _parser.send(OK_RESP);
wifi_cmd_t cmd = WIFI_CMD_DISCONNECT;
+ _smutex.unlock();
// queue next command
queueWiFiCommand(cmd);
return;
@@ -655,9 +687,19 @@
printf("\n read string = %s , n = %d\n", str, n);
//n = sscanf(str, "=%1d,%199[^,],%1d", &(uint8_t)internet_config.peer_id,
n = sscanf(str, "=%1d,%99[^,],%1d", &internet_config.peer_id,
- url, //internet_config.url,
- &internet_config.connectionScheme);
- strncpy(internet_config.url, url, strlen(url)+1);
+ url, //internet_config.url,
+ &internet_config.connectionScheme);
+ char *p = strstr(url,"\"");
+ if(p!=NULL)
+ {
+ strncpy(internet_config.url, &p[1], strlen(url));
+ p = strstr(internet_config.url,"\"");
+ *p = NULL;
+ }
+ else
+ {
+ strncpy(internet_config.url, url, strlen(url)+1);
+ }
printf("\n read string = %s , n = %d -- strlen(url) = %d\n", internet_config.url, n, strlen(internet_config.url));
if(n>0)
{
@@ -673,7 +715,7 @@
// queue next data request
queueWiFiDataRequest(data_msg);
print_memory_info();
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
} else {
printf("\n[ATCMD MAN]: internet configuration failed %d fields parsed \n", n);
_parser.send("NAK\n");
@@ -737,7 +779,7 @@
data_msg.dataLen = sizeof(wifi_config_t);
memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
queueWiFiDataRequest(data_msg);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
} else {
printf("\n[ATCMD MAN]: wifi configuration failed \n");
_parser.send("NAK\n");
@@ -754,14 +796,14 @@
n = readStringBytes((uint8_t *)wifi_cfg.pass, 32);
if(n>0)
{
- printf("ATCMD MAN]: wifi_cfg.pass = %s\n", wifi_cfg.pass);
+ printf("ATCMD MAN]: wifi_cfg.pass = %s\n", "****************");
// package and send on wifi data queue
wifi_data_msg_t data_msg;
data_msg.wifi_cmd = WIFI_CMD_CONFIG;
data_msg.dataLen = sizeof(wifi_config_t);
memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
queueWiFiDataRequest(data_msg);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
} else {
printf("\n[ATCMD MAN]: wifi configuration failed \n");
_parser.send("NAK\n");
@@ -785,7 +827,7 @@
data_msg.dataLen = sizeof(wifi_config_t);
memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
queueWiFiDataRequest(data_msg);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
} else {
printf("\n[ATCMD MAN]: wifi configuration failed \n");
_smutex.lock();
@@ -812,7 +854,7 @@
data_msg.dataLen = sizeof(wifi_config_t);
memcpy(data_msg.buffer,&wifi_cfg, data_msg.dataLen);
queueWiFiDataRequest(data_msg);
- _parser.send("OK\n");
+ _parser.send(OK_RESP);
} else {
printf("\n[ATCMD MAN]: wifi configuration failed \n");
_parser.send("NAK\n");
@@ -823,9 +865,27 @@
}
bool ATCmdManager::queueWiFiCommand(wifi_cmd_t cmd){
+ printf("[ATCMD MAN] about to be queued with wifi_cmd = %d\n", cmd);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
wifi_cmd_message_t *wifiCmd = _aT2WiFimPool->alloc();
+ if(wifiCmd == NULL){
+ printf("[ATCMD MAN] queued memory allocation failed\n");
+ print_memory_info();
+ print_heap_and_isr_stack_info();
+ return false;
+ }
+#else
+ wifi_cmd_message_t *wifiCmd = (wifi_cmd_message_t *) malloc(sizeof(wifi_cmd_message_t));
+ if(wifiCmd == NULL){
+ printf("[ATCMD MAN] tr malloc() : queued memory allocation failed\n");
+ print_memory_info();
+ print_heap_and_isr_stack_info();
+ return false;
+ }
+#endif
wifiCmd->wifi_cmd = cmd;
_aT2WiFiCmdQueue->put(wifiCmd);
+ printf("[ATCMD MAN] queued wifi_cmd = %d\n", wifiCmd->wifi_cmd);
return true;
}
@@ -835,7 +895,11 @@
if(evt.status == osEventMessage){
at_resp_message_t *resp = (at_resp_message_t*)evt.value.p;
setNextResponse(resp->at_resp);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
_wiFi2ATmPool->free(resp);
+#else
+ free(resp);
+#endif
}
return true;
}
--- a/source/ATCmdManager.h Sun Apr 07 17:31:56 2019 +0000
+++ b/source/ATCmdManager.h Sat Apr 13 14:17:29 2019 +0000
@@ -13,6 +13,7 @@
#define UBLOX_ODIN_W2_MISC_TIMEOUT 2000
#endif
+#define OK_RESP "OK\n\r"
extern void print_memory_info();
class ATCmdManager {
public:
--- a/source/WiFiManager.cpp Sun Apr 07 17:31:56 2019 +0000
+++ b/source/WiFiManager.cpp Sat Apr 13 14:17:29 2019 +0000
@@ -41,7 +41,11 @@
}
bool WiFiManager::queueATresponse(at_cmd_resp_t resp){
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
at_resp_message_t *atResp = _wiFi2ATmPool->alloc();
+#else
+ at_resp_message_t *atResp = (at_resp_message_t *) malloc(sizeof(at_resp_message_t));
+#endif
if(atResp == NULL) return false; // queue full;
atResp->at_resp = resp;
_wiFi2ATCmdQueue->put(atResp);
@@ -154,7 +158,11 @@
if(evt.status == osEventMessage){
wifi_cmd_message_t *cmd = (wifi_cmd_message_t*)evt.value.p;
setNextCommand(cmd->wifi_cmd);
+#ifndef USE_MALLOC_FOR_COMMAND_MEMORY_POOL
_aT2WiFimPool->free(cmd);
+#else
+ free(cmd);
+#endif
}
return true;
}
@@ -174,11 +182,12 @@
bool WiFiManager::setNextCommand(wifi_cmd_t cmd)
{
- printf("\n [WIFI-MAN] About to set next WiFi manager command \n");
+ printf("\n [WIFI-MAN] About to set next WiFi manager command to %d\n", cmd);
if(wifiCmd == WIFI_CMD_NONE){
wifiCmd = cmd;
return true; // success
}
+ printf("\n [WIFI-MAN] Busy : current state = %d \n", wifiCmd);
return false; // wiFiManager busy
}
@@ -268,7 +277,7 @@
void WiFiManager::set_WIFI_PASSWORD(char * wifi_pass)
{
strcpy(wifi_config.pass, wifi_pass);
- printf("[WIFI-MAN] wifi_pass set to %s\n", wifi_config.pass);
+ printf("[WIFI-MAN] wifi_pass set to %s\n", "****************");
https_connection_active = false; // reset whenever any of the security credentials change
delete socket;
}
--- a/source/common_config.h Sun Apr 07 17:31:56 2019 +0000
+++ b/source/common_config.h Sat Apr 13 14:17:29 2019 +0000
@@ -11,7 +11,7 @@
#ifndef UBLOX_ODIN_W2_RECV_TIMEOUT
#define UBLOX_ODIN_W2_RECV_TIMEOUT 100
#endif
-
+#define USE_MALLOC_FOR_COMMAND_MEMORY_POOL
#define PQDSZ 2 // size of Pool/Queue data structures
const uint8_t hello_msg[] = {0xaa,0x00,0x96,0x00,0x36,0x00,0x50,0x4f
,0x53,0x54,0x20,0x2f,0x6e,0x75,0x64,0x67
--- a/source/common_types.h Sun Apr 07 17:31:56 2019 +0000
+++ b/source/common_types.h Sat Apr 13 14:17:29 2019 +0000
@@ -19,7 +19,7 @@
/** ble configuration structure
*/
-typedef struct ble_config {
+typedef struct {
char deviceName[BLE_MAX_DEVICE_NAME_LEN]; /* BLE Device Name */
uint16_t advInterval; /* advertising interval in msecs */
uint16_t advTimeout; /* advertising timeout in secs */
@@ -29,7 +29,7 @@
/** ble configuration structure
*/
-typedef struct wifi_config {
+typedef struct {
char ssid[MAX_SSID_LEN]; /* WiFi SSID */
char pass[MAX_PASSKEY_LEN]; /* WiFi Passkey */
nsapi_security_t security; /* WiFi security */
@@ -37,13 +37,13 @@
/** ble configuration structure
*/
-typedef struct app_config {
+typedef struct {
wifi_config_t wifi_config; /* wifi configuration */
ble_config_t ble_config; /* ble configuration */
} app_config_t;
-typedef enum wifi_cmd
+typedef enum
{
WIFI_CMD_NONE,
WIFI_CMD_CONFIG,
@@ -56,7 +56,7 @@
WIFI_CMD_SEND_HTTP_REQ
}wifi_cmd_t;
-typedef enum at_cmd_resp
+typedef enum
{
AT_RESP_NONE,
AT_SCAN_RESP,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/compiler_abstraction.h Sat Apr 13 14:17:29 2019 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) Nordic Semiconductor ASA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
+ * contributors to this software may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef _COMPILER_ABSTRACTION_H
+#define _COMPILER_ABSTRACTION_H
+
+/*lint ++flb "Enter library region" */
+
+#if defined ( __CC_ARM )
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+
+ #ifndef __INLINE
+ #define __INLINE __inline
+ #endif
+
+ #ifndef __WEAK
+ #define __WEAK __weak
+ #endif
+
+ #ifndef __ALIGN
+ #define __ALIGN(n) __align(n)
+ #endif
+
+ #define GET_SP() __current_sp()
+
+#elif defined ( __ICCARM__ )
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+
+ #ifndef __WEAK
+ #define __WEAK __weak
+ #endif
+
+ /* Not defined for IAR since it requires a new line to work, and C preprocessor does not allow that. */
+ #ifndef __ALIGN
+ #define __ALIGN(n)
+ #endif
+
+ #define GET_SP() __get_SP()
+
+#elif defined ( __GNUC__ )
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+
+ #ifndef __ALIGN
+ #define __ALIGN(n) __attribute__((aligned(n)))
+ #endif
+
+ #define GET_SP() gcc_current_sp()
+
+ static inline unsigned int gcc_current_sp(void)
+ {
+ register unsigned sp __ASM("sp");
+ return sp;
+ }
+
+#elif defined ( __TASKING__ )
+
+ #ifndef __ASM
+ #define __ASM __asm
+ #endif
+
+ #ifndef __INLINE
+ #define __INLINE inline
+ #endif
+
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+
+ #ifndef __ALIGN
+ #define __ALIGN(n) __align(n)
+ #endif
+
+ #define GET_SP() __get_MSP()
+
+#endif
+
+/*lint --flb "Leave library region" */
+
+#endif
+
--- a/source/main-https.cpp Sun Apr 07 17:31:56 2019 +0000 +++ b/source/main-https.cpp Sat Apr 13 14:17:29 2019 +0000 @@ -20,6 +20,7 @@ #include "ATCmdManager.h" #include "BleManager.h" #include "WiFiManager.h" +#include "mbed_memory_status.h" UARTService *uart; DigitalOut alivenessLED(LED1, 0); @@ -56,21 +57,21 @@ LEDService *ledServicePtr; /* Queue and memory pool for AT to Wifi commands */ -MemoryPool<wifi_cmd_message_t, 16> aT2WiFimPool; -Queue<wifi_cmd_message_t, 16> aT2WiFiCmdQueue; +static MemoryPool<wifi_cmd_message_t, 16> aT2WiFimPool; +static Queue<wifi_cmd_message_t, 16> aT2WiFiCmdQueue; /* Queue and memory pool for WiFi to AT commands */ -MemoryPool<at_resp_message_t, 16> wiFi2ATmPool; -Queue<at_resp_message_t, 16> wiFi2ATCmdQueue; +static MemoryPool<at_resp_message_t, 16> wiFi2ATmPool; +static Queue<at_resp_message_t, 16> wiFi2ATCmdQueue; /* Queue and memory pool for AT to WiFi data */ -MemoryPool<wifi_data_msg_t, PQDSZ> aT2WiFiDatamPool; -Queue<wifi_data_msg_t, PQDSZ> aT2WiFiDataQueue; +static MemoryPool<wifi_data_msg_t, PQDSZ> aT2WiFiDatamPool; +static Queue<wifi_data_msg_t, PQDSZ> aT2WiFiDataQueue; /* Queue and memory pool for WiFi to AT data */ -MemoryPool<at_data_msg_t, PQDSZ> wiFi2ATDatamPool; -Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue; +static MemoryPool<at_data_msg_t, PQDSZ> wiFi2ATDatamPool; +static Queue<at_data_msg_t, PQDSZ> wiFi2ATDataQueue;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/mbed_memory_status.cpp Sat Apr 13 14:17:29 2019 +0000
@@ -0,0 +1,488 @@
+/*
+ mbed Memory Status Helper
+ Copyright (c) 2017 Max Vilimpoc
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/**
+ * Purpose: Print out thread info and other useful details using
+ * only raw serial access.
+ *
+ * Based on mbed_board.c's error printing functionality, minus
+ * pulling in all the printf() code.
+ */
+
+// Not great having to pull in all of mbed.h just to get the MBED_VERSION macro,
+// but it's the only way to do it for both pre- and post-5.4 releases
+//
+// If you're only supporting something newer than 5.4, you could use this alone:
+// #include "platform/mbed_version.h"
+//
+// platform/mbed_version.h says:
+// 999999 is default value for development version (master branch)
+
+#include "mbed.h"
+
+// Critical sections header file renamed in mbed OS 5.4 release
+// See: https://github.com/ARMmbed/mbed-os/commit/aff49d8d1e3b5d4dc18286b0510336c36ae9603c
+
+#ifndef MBED_VERSION
+#warning "You're probably using an unsupported version of mbed older than 5.2."
+#endif
+
+#if MBED_VERSION >= 50400
+#include "platform/mbed_critical.h"
+#elif MBED_VERSION >= 50200
+#include "platform/critical.h"
+#endif
+
+#include "platform/mbed_stats.h"
+
+#if !MBED_STACK_STATS_ENABLED
+#warning MBED_STACK_STATS_ENABLED != 1, so there will be no stack usage measurements.
+#endif
+
+#ifndef DEBUG_ISR_STACK_USAGE
+#define DEBUG_ISR_STACK_USAGE 0
+#endif
+
+#ifndef DEBUG_MEMORY_CONTENTS
+#define DEBUG_MEMORY_CONTENTS 0
+#endif
+
+#define OUTPUT_SERIAL 1
+#define OUTPUT_RTT 0
+#define OUTPUT_SWO 0
+
+#if DEBUG_ISR_STACK_USAGE
+#include "compiler_abstraction.h"
+
+// Value is sprayed into all of the ISR stack at boot time.
+static const uint32_t ISR_STACK_CANARY = 0xAFFEC7ED; // AFFECTED
+
+// Refers to linker script defined symbol, may not be available
+// on all platforms.
+extern uint32_t __StackLimit;
+extern uint32_t __StackTop;
+
+void fill_isr_stack_with_canary(void)
+{
+ uint32_t * bottom = &__StackLimit;
+ uint32_t * top = (uint32_t *) GET_SP();
+
+ for (; bottom < top; bottom++)
+ {
+ *bottom = ISR_STACK_CANARY;
+ }
+}
+#endif // DEBUG_ISR_STACK_USAGE
+
+#if OUTPUT_SERIAL && DEVICE_SERIAL
+#include "hal/serial_api.h"
+
+extern int stdio_uart_inited;
+extern serial_t stdio_uart;
+
+static void output_serial_init(void)
+{
+ if (!stdio_uart_inited)
+ {
+ serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
+ serial_baud(&stdio_uart, 115200); // This is hard coded.
+ }
+}
+
+static void output_serial_print_label(const char * label)
+{
+#if MBED_VERSION < 50902
+ // After mbed OS 5.9.2, this locks up the system.
+ core_util_critical_section_enter();
+#endif
+
+ output_serial_init();
+
+ while (*label) serial_putc(&stdio_uart, *label++);
+
+#if MBED_VERSION < 50902
+ core_util_critical_section_exit();
+#endif
+}
+#endif // OUTPUT_SERIAL && DEVICE_SERIAL
+
+#if OUTPUT_RTT
+#include "RTT/SEGGER_RTT.h"
+
+enum
+{
+ DEFAULT_RTT_UP_BUFFER = 0
+};
+
+static void output_rtt_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized)
+ {
+ SEGGER_RTT_ConfigUpBuffer(DEFAULT_RTT_UP_BUFFER, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_TRIM);
+
+ initialized = 1;
+ }
+}
+
+static void output_rtt_print_label(const char * label)
+{
+ output_rtt_init();
+ SEGGER_RTT_WriteString(DEFAULT_RTT_UP_BUFFER, label);
+}
+#endif // OUTPUT_RTT
+
+#if OUTPUT_SWO
+#if defined (NRF52) && !defined (ENABLE_SWO)
+ #error "You need to enable SWO using `-D ENABLE_SWO` on the mbed compile command line."
+#endif
+
+#ifdef NRF52
+#include "nrf.h"
+#endif
+
+static void output_swo_init(void)
+{
+ static int initialized = 0;
+
+ if (!initialized)
+ {
+ NRF_CLOCK->TRACECONFIG = (NRF_CLOCK->TRACECONFIG & ~CLOCK_TRACECONFIG_TRACEPORTSPEED_Msk) |
+ (CLOCK_TRACECONFIG_TRACEPORTSPEED_4MHz << CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos);
+
+ ITM->TCR |= 1;
+ ITM->TER |= 1;
+
+ initialized = 1;
+ }
+}
+
+static void output_swo_print_label(const char * label)
+{
+ output_swo_init();
+ while (*label) ITM_SendChar(*label++);
+}
+#endif // OUTPUT_SWO
+
+static void nway_print_label(const char * label)
+{
+#if OUTPUT_SERIAL
+ output_serial_print_label(label);
+#endif
+
+#if OUTPUT_RTT
+ output_rtt_print_label(label);
+#endif
+
+#if OUTPUT_SWO
+ output_swo_print_label(label);
+#endif
+}
+
+static const char HEX[] = "0123456789ABCDEF";
+
+static void debug_print_u32(uint32_t u32)
+{
+ char output[9] = {0};
+
+ // Always printed as big endian.
+ output[0] = HEX[(((uint32_t) u32 & 0xf0000000) >> 28)];
+ output[1] = HEX[(((uint32_t) u32 & 0x0f000000) >> 24)];
+ output[2] = HEX[(((uint32_t) u32 & 0x00f00000) >> 20)];
+ output[3] = HEX[(((uint32_t) u32 & 0x000f0000) >> 16)];
+ output[4] = HEX[(((uint32_t) u32 & 0x0000f000) >> 12)];
+ output[5] = HEX[(((uint32_t) u32 & 0x00000f00) >> 8)];
+ output[6] = HEX[(((uint32_t) u32 & 0x000000f0) >> 4)];
+ output[7] = HEX[(((uint32_t) u32 & 0x0000000f) >> 0)];
+
+ nway_print_label(output);
+}
+
+static void debug_print_pointer(const void * pointer)
+{
+ debug_print_u32((uint32_t) pointer);
+}
+
+#define DPL(X) nway_print_label((X))
+
+#if (defined (MBED_CONF_RTOS_PRESENT) && (MBED_CONF_RTOS_PRESENT != 0))
+#include "cmsis_os.h"
+
+// cmsis_os.h provides some useful defines:
+//
+// For mbed OS 5.4 and lower, osCMSIS == 0x10002U (see: rtos/rtx/TARGET_CORTEX_M)
+// For mbed OS 5.5 and higher, osCMSIS == 0x20001U (see: rtos/TARGET_CORTEX/rtx{4|5})
+//
+// Starting in mbed OS 5.5, a new RTOS layer was introduced with a different API.
+
+#if (osCMSIS < 0x20000U)
+ // Temporarily #undef NULL or the compiler complains about previous def.
+ #undef NULL
+ #include "rt_TypeDef.h"
+#else
+ #include "rtx_lib.h"
+ // #include <stdlib.h> // Include if you need malloc() / free() below. (probably better for non-C99 compilers)
+#endif
+
+#if (osCMSIS < 0x20000U)
+
+// No public forward declaration for this.
+extern "C" P_TCB rt_tid2ptcb (osThreadId thread_id);
+
+static void print_thread_info(osThreadId threadId)
+{
+ if (!threadId) return;
+
+ osEvent event;
+
+ P_TCB tcb = rt_tid2ptcb(threadId);
+
+ DPL(" stack ( start: ");
+ debug_print_pointer(tcb->stack);
+
+ event = _osThreadGetInfo(threadId, osThreadInfoStackSize);
+
+ DPL(" end: ");
+ debug_print_pointer(((uint8_t *) tcb->stack + event.value.v)); // (tcb->priv_stack)));
+
+ DPL(" size: ");
+ debug_print_u32(event.value.v);
+
+ event = _osThreadGetInfo(threadId, osThreadInfoStackMax);
+ DPL(" used: ");
+ debug_print_u32(event.value.v);
+
+
+ DPL(" ) ");
+
+ DPL("thread ( id: ");
+ debug_print_pointer(threadId);
+
+ event = _osThreadGetInfo(threadId, osThreadInfoEntry);
+ DPL(" entry: ");
+ debug_print_pointer(event.value.p);
+
+ DPL(" )\r\n");
+}
+
+void print_all_thread_info(void)
+{
+ osThreadEnumId enumId = _osThreadsEnumStart();
+ osThreadId threadId = (osThreadId) NULL; // Can't use nullptr yet because mbed doesn't support C++11.
+
+ while ((threadId = _osThreadEnumNext(enumId)))
+ {
+ print_thread_info(threadId);
+ }
+
+ _osThreadEnumFree(enumId);
+}
+
+#else
+
+static void print_thread_info(osThreadId threadId)
+{
+ // Refs: rtx_lib.h - #define os_thread_t osRtxThread_t
+ // rtx_os.h - typedef struct osRtxThread_s { } osRtxThread_t
+
+ if (!threadId) return;
+
+ os_thread_t * tcb = (os_thread_t *) threadId;
+
+ uint32_t stackSize = osThreadGetStackSize(threadId);
+ uint32_t stackUsed = osThreadGetStackSpace(threadId);
+
+ DPL(" stack ( start: ");
+ debug_print_pointer(tcb->stack_mem);
+
+ DPL(" end: ");
+ debug_print_pointer((uint8_t *) tcb->stack_mem + stackSize);
+
+ DPL(" size: ");
+ debug_print_u32(stackSize);
+
+ DPL(" used: ");
+ debug_print_u32(stackSize - stackUsed);
+
+ DPL(" ) ");
+
+ DPL("thread ( id: ");
+ debug_print_pointer(threadId);
+
+ DPL(" entry: ");
+ debug_print_u32(tcb->thread_addr);
+
+ DPL(" name: ");
+ DPL(osThreadGetName(threadId) ? osThreadGetName(threadId) : "unknown");
+
+ DPL(" )\r\n");
+}
+
+void print_all_thread_info(void)
+{
+ // Refs: mbed_stats.c - mbed_stats_stack_get_each()
+
+ uint32_t threadCount = osThreadGetCount();
+ osThreadId_t threads[threadCount]; // g++ will throw a -Wvla on this, but it is likely ok.
+
+ // osThreadId_t * threads = malloc(sizeof(osThreadId_t) * threadCount);
+ // MBED_ASSERT(NULL != threads);
+
+ memset(threads, 0, threadCount * sizeof(osThreadId_t));
+
+ // This will probably only work if the number of threads remains constant
+ // (i.e. the number of thread control blocks remains constant)
+ //
+ // This is probably the case on a deterministic realtime embedded system
+ // with limited SRAM.
+
+ osKernelLock();
+
+ threadCount = osThreadEnumerate(threads, threadCount);
+
+ for (uint32_t i = 0; i < threadCount; i++)
+ {
+ // There seems to be a Heisenbug when calling print_thread_info()
+ // inside of osKernelLock()!
+
+ // This error may appear on the serial console:
+ // mbed assertation failed: os_timer->get_tick() == svcRtxKernelGetTickCount(), file: .\mbed-os\rtos\TARGET_CORTEX\mbed_rtx_idle.c
+
+ // The RTOS seems to be asserting an idle constraint violation due
+ // to the slowness of sending data through the serial port, but it
+ // does not happen consistently.
+ print_thread_info(threads[i]);
+ }
+
+ osKernelUnlock();
+
+ // free(threads);
+}
+
+#endif
+
+void print_current_thread_id(void)
+{
+ DPL("Current thread: ");
+ debug_print_pointer(osThreadGetId());
+ DPL("\r\n");
+}
+#endif // MBED_CONF_RTOS_PRESENT
+
+#if DEBUG_MEMORY_CONTENTS
+static void print_memory_contents(const uint32_t * start, const uint32_t * end)
+{
+ uint8_t line = 0;
+
+ for (; start < end; start++)
+ {
+ if (0 == line)
+ {
+ debug_print_pointer(start);
+ DPL(": ");
+ }
+
+ debug_print_u32(*start);
+
+ line++;
+
+ if (16 == line)
+ {
+ DPL("\r\n");
+ line = 0;
+ }
+ }
+}
+#endif
+
+extern uint32_t mbed_stack_isr_size;
+
+#if DEBUG_ISR_STACK_USAGE
+uint32_t calculate_isr_stack_usage(void)
+{
+ for (const uint32_t * stack = &__StackLimit; stack < &__StackTop; stack++)
+ {
+ if (*stack != ISR_STACK_CANARY)
+ {
+ return (uint32_t) &__StackTop - (uint32_t) stack;
+ }
+ }
+
+ return mbed_stack_isr_size;
+}
+#endif
+
+void print_heap_and_isr_stack_info(void)
+{
+ extern unsigned char * mbed_heap_start;
+ extern uint32_t mbed_heap_size;
+
+ extern unsigned char * mbed_stack_isr_start;
+
+ mbed_stats_heap_t heap_stats;
+
+ mbed_stats_heap_get(&heap_stats);
+
+ DPL(" heap ( start: ");
+ debug_print_pointer(mbed_heap_start);
+
+ DPL(" end: ");
+ debug_print_pointer(mbed_heap_start + mbed_heap_size);
+
+ DPL(" size: ");
+ debug_print_u32(mbed_heap_size);
+
+ DPL(" used: ");
+ debug_print_u32(heap_stats.max_size);
+
+ DPL(" ) alloc ( ok: ");
+ debug_print_u32(heap_stats.alloc_cnt);
+
+ DPL(" fail: ");
+ debug_print_u32(heap_stats.alloc_fail_cnt);
+
+ DPL(" )\r\n");
+
+ DPL("isr_stack ( start: ");
+ debug_print_pointer(mbed_stack_isr_start);
+
+ DPL(" end: ");
+ debug_print_pointer(mbed_stack_isr_start + mbed_stack_isr_size);
+
+ DPL(" size: ");
+ debug_print_u32(mbed_stack_isr_size);
+
+#if DEBUG_ISR_STACK_USAGE
+ DPL(" used: ");
+ debug_print_u32(calculate_isr_stack_usage());
+#endif
+
+ DPL(" )\r\n");
+
+#if DEBUG_MEMORY_CONTENTS
+ // Print ISR stack contents.
+ print_memory_contents(&__StackLimit, &__StackTop);
+#endif
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/mbed_memory_status.h Sat Apr 13 14:17:29 2019 +0000 @@ -0,0 +1,32 @@ +/* + mbed Memory Status Helper + Copyright (c) 2017 Max Vilimpoc + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef MEMORY_STATUS_H +#define MEMORY_STATUS_H + +void print_current_thread_id(void); +void print_all_thread_info(void); +void print_heap_and_isr_stack_info(void); + +#endif /* MEMORY_STATUS_H */ +