Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 */ +