0

First of all, I use arm cm3 core chips and the function of my codes is Shift operation. For example, UART receive "f0", save "0f" to the corresponding address. Codes are below.

void UARTRXHandler(void) {
  volatile uint32_t *ramstoreaddr = RAM_START_ADDR ; 
  unsigned char rxchar;        
  uint32_t ch;
  if (uart_GetRxIRQStatus(UART) != 0) { // 检查接收中断状态  Check the receiving interrupt status                         
    rxchar = uart_ReceiveChar(UART); // 从 UART 接收字符  Receives characters from UART
    uart_ClearRxIRQ(UART); // 清除接收中断标志  Clear the receive interrupt flag
    ch = ((rxchar & 0x0F) << 4 ) | ((rxchar & 0xF0) >> 4 );
    *ramstoreaddr = ch; // 存储字符到内存 Stores characters to memory
    ramstoreaddr++;         
  } 

This is my interrupt function when i receive rxd's data. In theory, when rxd's data comes, it will jump into interrupt function, and "ramstoreaddr" won't change .

By the way , RAM_START_ADDR is also defined in another header file.

#define RAM_START_ADDR     (volatile uint32_t *)0x21001000

When rxd sends "0f" then "1f" "2f" "3f", address still remain at 0x21001000.(you can see it in pictures)

rxd comes from testbench it can correctly send "0f""1f" "2f" "3f".

this is signals in ram

address remain 0x21001000 first pic you can see 1000 in ADDR which refers to 0x21001000

address remain 0x21001000 second pic

address remain 0x21001000 third pic

I try to make declaration and initialization out of the function in the same c file like this:

volatile uint32_t *ramstoreaddr = RAM_START_ADDR ; 

void UARTRXHandler(void) {
  unsigned char rxchar;        
  uint32_t ch;
  if (uart_GetRxIRQStatus(UART) != 0) { // 检查接收中断状态  Check the receiving interrupt status
    rxchar = uart_ReceiveChar(UART); // 从 UART 接收字符  Receives characters from UART
    uart_ClearRxIRQ(UART); // 清除接收中断标志  Clear the receive interrupt flag
    ch = ((rxchar & 0x0F) << 4 ) | ((rxchar & 0xF0) >> 4 );
    *ramstoreaddr = ch; // 存储字符到内存 Stores characters to memory
    ramstoreaddr++;         
  }

The result turns like this in pictures , it didn't process in a right way.

wrong write f you can see in picture and compare it with pictures above, after HWDATA's "f" , it turns to 0 and HADDR is 4, which it suppose to write in 0x21001000(1000 in HADDR )

wrong write 1f

And it change address to another one which I never set.

9
  • Possible side issue. (Note: no part number so can't check reference manual for the part you are using. You should check the details there, I could be missing something.) If this function is an ISR, the placement of the line uart_ClearRxIRQ(UART); appears to be incorrect. It should be be moved to after the ramstoreaddr++; line to preclude the possibility of a subsequent RxIRQ occurring and being processed before the save and address modification from the earlier IRQ is completed. Also the uart_GetRxIRQStatus(UART) != 0 seems like it might be unneeded In an ISR. . . . Commented Aug 18, 2024 at 20:05
  • . . . These comments would not apply if the function was used to poll for new characters. This issue producing an error at runtime would be require specific timing. The chance of this occurring is dependent on the overall design and is hopefully quite low. Better to make it impossible, even if the design changes. Commented Aug 18, 2024 at 20:05
  • ramstoreaddr or the memory it points at will needs some means of protection against race conditions. And why you store 8 bit data in a 32 bit array, I don't know. Commented Aug 19, 2024 at 8:27
  • @Lundin UART sends 8bits data but my address is 32-bits. And how can I check what kind of means of protection against race conditions it will take. Commented Aug 19, 2024 at 9:31
  • @AviBerger I don't what you mentioned poll for new charactors means, but it does a little bit like polling. And your first suggestion to put that sentence below doesn't work, waveform in verdi shows the same and address targeted is still not written. And just like I comment in first answer below, But not long ago, I use another global variable counter to count every interrupt and my address plus (4*counter) to write in right address. So right now although i am confused about why i cannot use my second code above to realize function, I can see 0f in 0x21001000 and 1f in 0x21001004. Commented Aug 19, 2024 at 9:56

1 Answer 1

1

Your first example appears not to increment ramstoreaddr because ramstoreaddr is defined as a local variable and therefore it gets reinitialized every time UARTRXHandler is executed.

Your second example defines ramstoreaddr as a static variable so it will maintain its value outside the scope of UARTRXHandler. I suspect ramstoreaddr is incrementing by sizeof(uint32_t) every time UARTRXHandler receives a char. Is your intention to increment the address by 4 bytes?

You might be misinterpreting the RAM signals for the second example. Look at how the disassembly of the function has changed from your first to second examples. The first example might keep ramstoreaddr in a CPU register and therefore doesn't read the value out of RAM. The second example might have more and different instructions to read the value of ramstoreaddr out of RAM before writing to that address. Maybe additional RAM accesses are confusing your interpretation.

Why are you trying to debug this by looking at the RAM signals? It would be much easier to use a debugger tool.

Sign up to request clarification or add additional context in comments.

7 Comments

Yes, I try to add 4 bytes in address, like 0x21001000 to 0x21001004. So when i check difference between two disassenmblies, which part should i foucus on, like UARTRX_Handler part or anything else. Lastly, I can only get rxd's sending from testbench and I don't konw whether i can do something to debug in UARTRX_Handler function in Keil MDK.
@ADemonevil what makes you think you cannot use the Keil debugger for interrupt debugging? If the sender continues to send while halted, you will get an overrun, but that can be overcome.
@ADemonevil I was only trying to suggest that the RAM signals could look very different for your two pieces of code and it's difficult to debug by interpreting RAM signals. You'd be better off stepping through the code and examining what happens in the debugger.
@ADemonevil The second piece of code will increment the address by 4, which is what you expect. So what is the problem? Describe what you expect and what happens differently from what you expect. The problem may be elsewhere in the code.
@ADemonevil. I am not talking about simulation. There is no restriction on debugging any of your code. You place a breakpoint in the handler and issue the appropriate stimulus to trigger the interrupt. I have no idea what "testbench" is, but you can send single serial characters from a terminal emulator such as PuTTY or TeraTerm for example. It is not rocket science.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.