2017-07-27 02:55 AM
Hey guys,
I have a function that parses messages of my own format and splits them into an opcode and (0-3) operands.
With 0 or 1 operand, it works fine; on the second operand, the
msg.substr(start, (pos - start)); causes a hard fault every time without fail on my STM32F4. Stepping into substr() in the debugger it appears to occur inside the constructor for basic_string. I tested the code in an online compiler and it works fine, so I'm guessing it's some kind of memory allocation issue. Just doesn't make sense to me that it works for the first operand and not the second. Any ideas guys?
You'll also notice some commented out use of std::vector. This is another issue with STM32 C++ development in Keil I believe which I could also do with help sorting - currently any call to push_back kills the program (possibly a similar issue to above?).
#include <iostream>
#include <string>#include <stdexcept>void ParseMessage(const std::string msg){ std::string opCode; //std::vector<std::string> operands; std::string operands[3]; uint8_t operandCount = 0; opCode = msg.substr(1, 3); std::cout << 'Opcode: ' << opCode << std::endl; if(msg[4] == '#') { // We have at least one operand size_t pos; size_t start = 5; pos = msg.find('#', start); while(pos != std::string::npos) { operands[operandCount++] = msg.substr(start, (pos - start)); std::cout << 'Operand ' << operandCount << ': ' << operands[operandCount-1] << std::endl; // Store middle operands //operands.push_back(msg.substr(start, pos - 1)); start = pos + 1; pos = msg.find('#', start); } // Store the final operand //operands.push_back(msg.substr(start, msg.length() - 2)); //uint16_t tmp = msg.length(); operands[operandCount++] = msg.substr(start, ((msg.length() - 1) - start)); std::cout << 'Operand ' << operandCount << ': ' << operands[operandCount-1] << std::endl; } }int main()
{ ParseMessage('<SSG#0.7#0.3#0.05>'); return 0;}2017-07-27 04:33 AM
A stack overflow, probably.
I don't expect the C++ stdio and string functions to be more memory-economical than the printf-style clib functions.
2017-07-27 07:04 AM
Use a proper Hard Fault handler and identify exactly what code itis breaking on, these are gross failures and shouldn't be hard to pin down. Look at the assembler code, the faulting instruction, the registers, and those specifically used by the instruction in question.
https://community.st.com/0D50X00009XkeRmSAJ
For Keil the stack size is defined in startup_stm32f4xx.s, C++ likely also expects a sufficiently large heap.
Unaligned LDRD/STRD will fault. Accessing bogus addresses will fail. So bad pointers, strings that aren't NUL terminated, corrupt stack, stack/heap collision.
Most likely a fault in your logic/algorithm. Build some test cases, test them on a PC platform.
2017-07-27 07:25 AM
So is there I can do about it?
Note that the std::cout calls are just there for when i tested it on an online compiler
2017-07-27 08:24 AM
Increase stack size, or do your parsing in a less resource-consuming manner.
But before, I would check SCB registers in the hardfault case.