-1

I am working on my own implementation to read AT commands from a Modem using a microcontroller and c/c++

but!! always a BUT!! after I have two "threads" on my program, the first one were I am comparing the possible reply from the Moden using strcmp which I believe is terrible slow

comparing function

if (strcmp(reply, m_buffer) == 0)
        {
            memset(buffer, 0, buffer_size); 
            buffer_size = 0;
            memset(m_buffer, 0, m_buffer_size); 
            m_buffer_size = 0;  
            return 0;
        }
else
       return 1;

this one works fine for me with AT commands like AT or AT+CPIN? where the last response from the Modem is "OK" and nothing in the middle, but it is not working with commands like AT+CREG?, wheres it responses:

+REG: n,n 
OK

and I am specting for "+REG: n,n" but I believe strncpy is very slow and my buffer data is replaced for "OK"

2nd "thread" where it enables a UART RX interruption and replaces my buffer data every time it receives new data

Interruption handle:

m_buffer_size = buffer_size;
strncpy(m_buffer, buffer, buffer_size + m_buffer_size);

Do you know any out there faster than strcmp? or something to improve the AT command responses reading?

jou
  • 1
  • 4
  • 1
    Which language, C **or** C++? They are distinct languages. For example, C++ has `std::string` and C doesn't. C++ has an associative array or `std::map`, C doesn't. In C++ you can use *functors* in a `std::map` to help parse. Also, C++ has the `bool` type, so you can return `true` or `false` instead of 1 or 0. – Thomas Matthews Aug 21 '18 at 23:18
  • I prefer to use pure C, My issue is the strcmp is not comparing as fast as I want, and it is being overwritten with new data – jou Aug 21 '18 at 23:43
  • Why do you use "thread" in quotes? What's the actual implementation? Also, you are going to need some form of mutual exclusion to avoid stomping on old data. – Rich Aug 22 '18 at 04:12
  • 1
    You should remove the language tag you are not using. Mixing C and C++ is an added headache, which I don't recommend. – Thomas Matthews Aug 22 '18 at 13:58

2 Answers2

0

This has the scent of an XY Problem

If you have seen the buffer contents being over written, you might want to look into a thread safe queue to deliver messages from the RX thread to the parsing thread. That way even if a second message arrives while you're processing the first, you won't run into "buffer overwrite" problems.

dgnuff
  • 3,195
  • 2
  • 18
  • 32
0

Move the data out of the receive buffer and place it in another buffer. Two buffers is rarely enough, so create a pool of buffers. In the past I have used linked lists of pre-allocated buffers to keep fragmentation down, but depending on the memory management and caching smarts in your microcontroller, and the language you elect to use, something along the lines of std::deque may be a better choice.

So

Make a list of free buffers.

When a the UART handling thread loop looks something like,

  1. Get a buffer from the free list
  2. Read into the buffer until full or timeout
  3. Pass buffer to parser.
    1. Parser puts buffer in its own receive list
    2. Parsing sends a signal to wake up its thread.

Repeat until terminated. If the free list is emptied, your program is probably still too slow to keep up. Perhaps adding more buffers will allow the program to get through a busy period, but if the data flow is relatively constant and the free list empties out... Well, you have a problem.

Parser loop also repeats until terminated looks like:

  1. If receive list not empty,
    1. Get buffer from receive list
    2. Process buffer
    3. Return buffer to free list
  2. Otherwise
    1. Sleep

Remember to protect the lists from concurrent access by the different threads. C11 and C++11 have a number of useful tools to assist you here.

user4581301
  • 33,082
  • 7
  • 33
  • 54