Hello All,
Today I am going to share with you an interesting story of an intelligent programmer who almost lost the hope on C programming and basically on everything.
The programmer had to implement a delay function using 32 bit Timer peripheral of Cortex M3 microcontroller. First it looked so simple. He was ignorant of what coming next to his way.
The tool/editor provided everything, from compiler to drivers of each and every peripheral of micro controller. It required just a foolish programmer to add A and B to get things done.
The tool also provided JTAG access to microcontroller to run the programs in Debug mode where user can add break points or user can program the inbuilt flash of microcontroller with final code, which is called Release mode. The microcontroller has an inbuilt SRAM where all the code runs. On power up, code from flash is shadowed to SRAM by the microcontroller. Don't ask me how.
Moving on to timer story. Initialize it with periodic or one shot mode. Load the count, enable the interrupt and enable the timer. It will begin to count down to zero and interrupts controller. If it is in periodic mode, it will reload itself and starts counting down to provide periodic interrupts.
Below is the implementation of delay function and how it was tested.
/****************************************************************************/
#define TIMER_DELAY_STOPPED
(0U)
#define TIMER_DELAY_STARTED
(1U)
#define TIMER_DELAY_ACHIEVED
(2U)
UINT32 gu32TimerDelay = TIMER_DELAY_STARTED;
void timer1Init (void)
{
/*--------------------------------------------------------------------------
* Ensure the CMSIS-PAL provided g_FrequencyPCLK0 global variable contains
* the correct frequency of the APB bus connecting the MSS timer to the
* rest of the system.
*/
SystemCoreClockUpdate();
MSS_TIM1_init( MSS_TIMER_ONE_SHOT_MODE );
}
/* Delay function implemented by programmer */
void sDelay(UINT32 u32Sec)
{
UINT32 u32TimerLoadVal;
UINT32 u32TimerResolution;
/* For a 100Mhz system, this global variable will hold 100M as count which is equal to one second */
u32TimerResolution = (g_FrequencyPCLK0);
u32TimerLoadVal = (u32TimerResolution * u32Sec);
MSS_TIM1_load_immediate( u32TimerLoadVal );
gu32TimerDelay = TIMER_DELAY_STARTED;
MSS_TIM1_start();
MSS_TIM1_enable_irq();
while (gu32TimerDelay != TIMER_DELAY_ACHIEVED)
{
/* In tight loop till timer interrupts and sets the flag */
;
}
gu32TimerDelay = TIMER_DELAY_STOPPED;
MSS_TIM1_stop();
}
/* Linkage for Timer ISR function provided by compiler. User can add his logic inside this ISR.
__attribute__((__interrupt__)) void Timer1_IRQHandler( void )
{
gu32TimerDelay = TIMER_DELAY_ACHIEVED;
MSS_TIM1_clear_irq();
}
void main (void)
{
UINT32 count = 0;
while (1)
{
sDelay(2);
count = count + 2;
printf("\nTime elapsed in sec: %d", count);
}
}
Output:
Time elapsed in sec: 2
Time elapsed in sec: 4
Time elapsed in sec: 6
Time elapsed in sec: 8
.
.
.
/*****************************************************************************/
So the programmer wrote the above functions and tested it in Debug mode and it worked in one shot. He patted his own back and started using delay function everywhere in his final code and flashed it to microcontroller in Release mode.. Voila!!!! There lies the mystery. Not even one single print on the console after the first delay function was called.
To make sure the interrupt is working, programmer added print in ISR. Yes!! The print showed up on console. But no other prints after that. He added prints everywhere. Only prints till the timer interrupt ended, where showing up on the console. None after. Then commenced the long hours of debugging the issue and listening to various so called other intelligent programmers' suggestions.
One of the gossip was how the tool, in debug mode, adds delay to the execution of the code and in release mode, where there is no JTAG interaction with the microcontroller, causing the delay function to fail. Few morons agreed to this. Few experienced fellows said it was not the issue.
So our hero tried many foolish stuffs to debug the issue. Did he succeed? Was there a foolish mistake? Or was there a secret villain who added the mystery spice into the code?
To be continued.... (Only if any positive response to the story is observed.)