An alternative to malloc for interrupt safety

Again, I'm not a developer, I'm a woodworker, so my questions might be, well, stupid.

I forgot something really important. I have to use gcc-3.8 to compile as the source code I am working with cannot compile with a newer version. I forgot to talk about it altogether, sorry.

I am sending data from a tool to an autonomous robot. Robot receives data as unsigned char * I have read a lot and it seems that malloc is not interrupt safe.

Since the robot can do bad and dangerous things, I try to make all parts safe (at least as much as possible).

This malloc occurs after an interrupt caused by the received data. This segment of code is now giving me a hard time to make it safe, also my syntax is probably bad.

char* _Xp = (char*) malloc(strlen((char*)_X)*sizeof(char));
strcpy(_Xp, (char*)_X);

      

1) does malloc really break safety? the information I found is from 2004.

2) is there a more efficient way to initialize the buffer?

3) why is unsigned char "bad"? (read something about it).

4) Last question: does strcpy break security as well? the sources I read differ on this issue.

===== answering some questions:

The robot does not have an operating system, the target is STR911FFM44 at 25 MHz (if that helps)

The input arrays are all nul-terminated.

The code is not in the interrupt handler, but in an infinite loop and is processed only if IrHandler is set as a flag for it.

I don't know how bit rate "hardcodes" security. but the interrupt must be in the range of 500ms to 1500ms.

+3


source to share


2 answers


1) does malloc really fail safely?

malloc

accesses and modifies a global resource, a shared memory pool for your running program. If the access comes from two unsynchronized locations such as the normal program thread and ISR 1 then it can mess up the pool. If your ISR doesn't call itself malloc

, this won't be a problem.

If so, you will need to install the system to prevent re-login malloc

. For example, end the call malloc

in a function that will disable interrupt handling and then re-enable it.

2) is there a more efficient way to initialize the buffer?

If you want a buffer with an allocated storage duration (i.e. you decide when its lifetime will end, not the area it was allocated in), there is really no standard alternative to C. By the way, sizeof(char)

always 1, so it is not needed indicate. And since C allows implicit conversion of pointer types fromvoid*

, the call can be at least slightly interrupted by bit 2 :



char* _Xp = malloc(strlen((char*)_X));

      

3) why is unsigned char "bad"?

They are not bad. In fact, when you need to know for sure whether a character type is signed or not, you should use signed char

or unsigned char

. Regular char

can be signed on one platform and unsigned on another.


1 Interrupt service procedure.
2 C has the concept of reserved identifiers . In particular, any identifier that starts with an underscore followed by an uppercase letter is always reserved. Therefore, renaming variables can help with portability.

+4


source


First of all, you say you are using a bare metal microcontroller, so malloc never makes sense . This is not a computer - you are not sharing your RAM with anyone else. Thus, all the dangers and disadvantages of malloc are not even in the discussion, since malloc doesn't make sense to use you at all.

1) does malloc really break safety? the information I found is from 2004.
4) last question: does strcpy break security as well? the sources I read differ on this issue.

No function sharing resources between the ISR and the host application is interrupt-safe. You should avoid calling library functions from the ISR, they should be minimal.

All data shared between the ISR and the caller must be handled with care. You must provide atomic access to individual objects. You should declare variables such as volatile

to prevent optimizer errors. You may need to use semaphores or other synchronization tools. This applies to all such data, whether you change it yourself or through a library function.

Failure to do all of the above will lead to very cryptic and subtle bugs, resulting in data corruption, race conditions, or code that never gets executed. In general, interrupts are always difficult to work with because of all this additional complexity. Use them only when your real-time requirements don't give you other options.

2) is there a more efficient way to initialize the buffer?

Yes, use an array. static char _Xp [LARGE_ENOUGH_FOR_WORST_CASE];

It is generally a .data

good idea to store such buffers on a segment rather than the stack, hence the static

.



3) why is unsigned char "bad"? (read something about it).

There is nothing wrong with them. The different types are char

problematic because, in theory, they could be different sizes than 8 bits. Worse, char

unsigned / unsigned has an application-defined signature, which means it can be signed or unsigned depending on the compiler. This means that you should never use a type char

to store anything other than text strings.

If you need a variable type to store data bytes, always use uint8_t

from stdint.h.

Since the robot can do bad and dangerous things, I try to make all parts safe (at least as much as possible).

Writing secure software for embedded systems is a highly skilled task. I would not recommend anyone with less than 5 years of full time experience with embedded firmware programming to even consider it, unless there is at least one seasoned C veteran who is part of your team and all the code goes through peer review and static analysis.

You seem to have benefited a lot from reading the MISRA-C: 2012 rules. It is a safe subset of the C language intended for use in security-critical applications or any form of application where bugs are bad. Unfortunately, the MISRA-C document is not free, but it is becoming an industry standard.

+1


source







All Articles