Automated testing of open metal C code (microprocessor firmware): modeling changes in hardware registers

I want to write automated tests for very low-level C code on a PC, which I will transfer to a microprocessor. I understand that there will be differences (specific to the implementation of behavior, such as int size) that I will have to live with.

I need ideas on how to simulate changes in mutable variables (which relate to special function registers in the microcontroller). For example. in the code below, the value of the TX_BUFF_FULL register TX_BUFF_FULL can change many times during code execution, when the space in the transfer buffer becomes available or is used:

 void send_str(char * str){ // for each non-null character for (char i = 0; str[i]; i++){ // wait for space in TX hardware buffer while(TX_BUFF_FULL); // put character into hardware FIFO TX_REGISTER = str[i]; } } 

TX_BUFF_FULL and TX_REGISTER are variable variables mapped to the address of special function registers for UART.

Ideally, I’ll write a source so that it can be compiled without changes for both automatic tests on a PC and for working on a microcontroller, which probably require preprocessor directives.

For example, a directive that uses this line when compiling for a microcontroller:

 while(TX_BUFF_FULL); 

but uses this when compiling for testing on a PC:

 while(test_tx_buff_full()); 

where the test_tx_buff_full() function will be part of a test suite that emulates state changes in registers. I can’t think of another way to achieve the result.

Is this a smart way? What would be a neat way to implement preprocessor directives to achieve this? Is there a tidier way? Thanks

Edit: From this question , this question and this question , some other ideas:

  • using preprocessor macros that produce inline code to replace register reading
  • with the help of a programmable hardware stand that can download and run tests for unit and integration, bypassing the need for a simulator
+7
c multithreading automated-tests cross-compiling
source share
1 answer

It seems to me that this can be done using the APIs used to implement break debugging. In linux, this can be ptrace (in particular, the PTRACE_POKEDATA operation can be used to deliver a new mutable value and PTRACE_SINGLESTEP will allow you to set the exact time of its delivery). I am sure that analogues exist on Windows and BSD, but I am less familiar with these platforms.

+1
source share

All Articles