I'm trying to enable hot plug-in debug option on RL78 MCU by setting the HPIEN bit in the corresponding option byte.
When I attach the E1 debugger to the running target, I can use Live Watch to inspect the RAM variables, however, trying to break the execution results in "can not compulsory break" error message:
The test software I'm trying to debug is a simple infinite loop incrementing a variable, toggling a pin and servicing the watchdog:
volatile long i = 0;
void main( void )
{
hpi_initialize_prog();
PM8_bit.no5 = 0;
while (1)
{
i++;
P8_bit.no5 = i;
WDTE = 0xAC;
}
}
Did anyone manage to use breakpoints / step through the program using the hot plug-in debug?
Related
I'm debugging C code running on a MSP430 microprocessor using GDB.
When I set a breakpoint on the line double average = sum / 10; using break 172, it confirms by responding Breakpoint 1 at 0xc01c: file main.c, line 172, but when I continue with c, the code runs until it hits Breakpoint 1, main () at main.c:184.
I wasn't having issues debugging until recently, so I tried reverting everything to the previous version and I still have this issue. I have also tried:
Turning my laptop off and on.
Unplugging and re-plugging every cable related to the microprocessor and its circuit.
Closing and re-opening all terminal windows.
Re-compiling and re-loading my C code into the microprocessor.
Print statements to help debugging aren't an option because the microprocessor can't hold #include <stdio.h>.
Clearing all breakpoints present before setting this one, but none are found.
The code looks something like:
void main(void)
{
OtherMethod();
while(1)
{
int sum = 0;
for(int i = 0; i < 10; i++)
{
sum += i;
}
double average = sum / 10; // Line 172
}
}
void OtherMethod(void)
{
P1DIR |= LED1 + LED2; // Line 184
}
Other information that might be helpful is that I can successfully set a breakpoint on the line sum += i;.
Any ideas are appreciated.
If you compile with optimization, several "strange" things might happen, see your compiler's documentation. This might lead to statements being removed or re-arranged, and when debugging, surprising behaviour.
To debug a program "by the line", compile without optimization.
Or live with the surprises; it's a source of delight, in any case.
In the following program, what is the meaning of the line of code
fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM
in the below section of code. I have some idea about what is happening here,In order to overcome read while write violation, copying the code from flash to RAM using the above lines of code. But what is exact meaning of these lines.
static int fnProgram(unsigned long *ptrWord, unsigned long *ptr_ulWord)
{
while ((FTFL_FSTAT & FTFL_STAT_CCIF) == 0) {} // wait for previous commands to complete
if ((FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR)) != 0) { // check for errors in previous command
FTFL_FSTAT = (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_RDCOLERR); // clear old errors
}
FTFL_FCCOB0 = FCMD_PROGRAM; // enter the command sequence
FTFL_FCCOB1 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 16); // set address in flash
FTFL_FCCOB2 = (unsigned char)(((CAST_POINTER_ARITHMETIC)ptrWord) >> 8);
FTFL_FCCOB3 = (unsigned char)((CAST_POINTER_ARITHMETIC)ptrWord);
FTFL_FCCOB7_4 = *ptr_ulWord++; // enter the long word to be programmed
FTFL_FCCOBB_8 = *ptr_ulWord; // enter the second long word to be programmed
uDisable_Interrupt(); // protect this region from interrupts
fnRAM_code((volatile unsigned char *)FLASH_STATUS_REGISTER); // execute the command from SRAM
uEnable_Interrupt(); // safe to accept interrupts again
return (FTFL_FSTAT & (FTFL_STAT_ACCERR | FTFL_STAT_FPVIOL | FTFL_STAT_MGSTAT0)); // if there was an error this will be non-zero
}
The only code that needs to be in RAM is this:
static void fnFlashRoutineInRam(volatile unsigned char *ptrFTFL_BLOCK)
{
*ptrFTFL_BLOCK = FTFL_STAT_CCIF; // launch the command - this clears the FTFL_STAT_CCIF flag (register is FTFL_FSTAT)
while ((*ptrFTFL_BLOCK & FTFL_STAT_CCIF) == 0) {} // wait for the command to terminate
}
This looks like older NXP (former Freescale/Motorola) HCS08, HCS12 or Coldfire. On those devices, you have different cases when writing a flash driver: either you can execute it from flash or you cannot. This entirely depends on which "bank" the program flash belongs to: generally you cannot execute code on a MCU from the very same flash bank it is currently programming.
So ideally you put the flash programming code in another bank, but some devices only have one single flash bank. Then they provide a work-around by executing the code from RAM, which is kind of a quick & dirty fix.
Commonly they solve this by providing an array of raw data op codes. This array of op codes is copied to RAM and then they set a function pointer to point at the RAM address. I suspect fnRAM_code is such a function pointer. The (volatile unsigned char *)FLASH_STATUS_REGISTER part is simply passing on the address of the flash status register. Likely, FLASH_STATUS_REGISTER is synonymous with FSTAT.
The uDisable_Interrupt(); and uEnable_Interrupt(); should correspond to asm SEI and asm CLI respectively, blocking all maskable interrupts from triggering during the flash write, which would potentially cause the write to fail or the program to hang up.
There should be app notes available describing all of this in detail.
Please note that this code is very close to the hardware and relies on tons of poorly-defined behavior. I wouldn't count on it compiling as expected on anything but the Codewarrior compiler. gcc would for example spew out numerous strict aliasing bugs.
I am working with a STM32F030R8T6 and the HAL libraries. I use the STM32CubeMX for all the initialization code.
When I use a "if" statement inside the infinite loop it does not work.
Eg.
while (1) {
if ((Seconds - oldSec) >= 10) {
printf("Entramos 10sec\r\n");
oldSec = Seconds;
}
}
but if a use a HAL_Delay() function it works eg.
while (1) {
HAL_Delay(1);
if ((Seconds - oldSec) >= 10) {
printf("Entramos 10sec\r\n");
oldSec = Seconds;
}
}
I do not know, what is the problem?
I use the arm-gcc compiler with makefile.
CubeMX provides optimization level 3 by default and this causes problems if variables are not volatile but changed outside context (like in interrupts).
Solution is to have Seconds and oldSeconds as volatile and make sure Seconds is increased in SysTick_IRQHandler or in HAL_SYSTICK_Callback functions.
Solution is also to set optimizations to level 0. But as you can see what can happen if you don't follow volatile rule, it is better to stay at level 3.
In the code below, I can see that the timer is working normally as the LED is always blinking. But the value of the count variable never changes inside the second while.
I don't know what could possibly go wrong?
// count variable used only in main and TIM2_IRQHandler.
uint8_t count=0;
int main(void)
{
count=0;
SystemInit();
GPIOInit();
NVIC_Configuration();
TIM_Configuration();
init_USART3(115200);
// All initialization is ok.
USART_puts(USART3, "\r\nConnection ok.\r\n");// Working normally
while (1)
{
if(asterixok==1)// No problem. This code if ok ->>process continue next step.
{
GPIO_SetBits(GPIOD , GPIO_Pin_12); // Led on (ok)
count=0;// count going to zero, timer working, must be change in there
while(1)
{
//Led blinking continue
//Timer query working normal led (13) blink.
//There is a problem
if(count>5) // Timer working, count never change in timer interrupt query (WHY)
{
GPIO_SetBits(GPIOD , GPIO_Pin_14); // LED OFFFFFFFFFFFFFFFF
USART_puts(USART3, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\n");
goto nextstate;
}
}
nextstate:
GPIO_SetBits(GPIOD , GPIO_Pin_15); // Led never going on because code step in while loop.
}
}
}
void USART3_IRQHandler(void)
{
if( USART_GetITStatus(USART3, USART_IT_RXNE) )
{
unsigned char t = USART3->DR;
if(t=='*')
{
asterixok=1;
}
}
}
void TIM2_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )
{
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);
count++;
if(count>100)
count=0;
if( display )
{
GPIO_ResetBits(GPIOD , GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOD , GPIO_Pin_13);
}
display = ~display;
}
}
I have tried with another Discovery board but the problem continues.
Please help. I'm going crazy!
You should declare count as volatile, as such :
volatile uint8_t count;
While compiling main the compiler was able to prove that count was not modified in the loop body, and so it probably cached its value in a register and maybe even optimized out the if statement. You could verify that by looking at a disassembly. The compiler does not know about interrupts as per the standard and so is permitted to perform such optimizations. Qualifying count as volatile will forbid the compiler from making these optimizations, forcing it to reload the variable from memory each time it is used.
In this simple case volatile will be enough but please be aware that it doesn't guarantee atomicity of operations, and it doesn't prevent the compiler and CPU from reordering instructions around accesses to the variable. It only forces the compiler to generate memory access instructions each time the variable is used. For atomicity you need locks, and to prevent reordering you need memory barriers.
I've recently started with C and Im trying to figure out how to make a 10ms delay for
PIC16F884. From the formulas in the datasheet I've managed to create the following:
fosc = 20MHz and Toscx4 = 200ns
If I put a preset to 100 => t=100x200ns=20us and to get a 10 ms delay
10ms/20us = 500
Will the following code in C give me what Im looking for (10ms delay)? Assume I have all the initiating code and variables.
void interrupt ISR(void){
if(TMR0IF){
TMR0IF=0;
counter++;
}
if(counter==100){
delay++;
counter=0;
}
}
int main(void){
TMR0=155;
if(delay>4){
//any code
delay=0;
}
}
Might be a bad example but hopefully you understand
No, since the code in main() never actually waits, it won't implement a delay.
Assuming the interrupt and timer logic is properly set up, you're still going to need to loop:
delay = 0;
TMR0 = 155; /* Start timer. */
while(delay < 4)
; /* Do nothing */
/* More code here, delay has expired */
Also, remember to make delay a volatile variable since you're accessing it from multiple parallel threads of execution.
If you're a really beginner and want a tool that can help you calculate timer settings I advise you to look at this link :
http://www.mikroe.com/timer-calculator/
It generate the ccode for settiing properly a lot of different microcontroller