AnsweredAssumed Answered

Removing useless variables turns a unworking code to a working code.

Question asked by JulienD on Oct 26, 2015
Latest reply on Oct 26, 2015 by JulienD
Hi

Some days ago I tried to add a PWM function in my project, As it was unsuccessfull, I built
a working standalone pwm project that I tried to integrate to the real life project.
I did not succeed in making it work.

To understand what happens, I removed every piece of code to get a minimum non working
project.

Now I face some very stranges behaviours :
- removing one or several unused uint16_t variables turns the unworking code to a working one.
- inlining a function called once turns the unworking code to a working one.
- replacing a call to function A which only do a call to function B by a direct call to function B turns the unworking code to a working one.

I really don't unerdstand what happens. If anybody has an idea of what may happen, I'm interested in any clue.

Optimization is -O0.
µc : STM32F103VET6.

Code attached and below.
Search for "XXX" pattern to find comments that points the above lines of code.


main.c
01.#include <stddef.h>
02.#include "board.h"
03. 
04.int main( void )
05.{
06.    // board_timer_init();
07.    board_init_mcu();    // XXX calling the previous commented function instead of this one makes the code work.
08.    RightTimerLedStart(  );
09.    while( 1 )
10.    {
11.    }
12.}

board.h
01.#ifndef SRC_BOARD_H_
02.#define SRC_BOARD_H_
03. 
04.#include <stddef.h>
05.#include <stdbool.h>
06.#include <stdlib.h>
07.#include "stm32f10x.h"
08.#include "timer_board.h"
09. 
10. 
11. 
12./*!
13. * Board GPIO pin names
14. */
15.typedef enum
16.{
17.    PA_0 = 0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15,
18.    PB_0, PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15,
19.    PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14, PC_15,
20.    PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14, PD_15,
21.    PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14, PE_15,
22.    PF_0, PF_1, PF_2, PF_3, PF_4, PF_5, PF_6, PF_7, PF_8, PF_9, PF_10, PF_11, PF_12, PF_13, PF_14, PF_15,
23.    PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, PH_8, PH_9, PH_10, PH_11, PH_12, PH_13, PH_14, PH_15,
24.    // Not connected
25.    NC = ( int )0xFFFFFFFF
26.} PinNames;
27. 
28. 
29./*!
30. * Define the GPIO IRQ on a rising, falling or both edges
31. */
32.typedef enum
33.{
34.    NO_IRQ = 0,
35.    IRQ_RISING_EDGE,
36.    IRQ_FALLING_EDGE,
37.    IRQ_RISING_FALLING_EDGE
38.} IrqModes;
39. 
40./*!
41. * Define the IRQ priority on the GPIO
42. */
43.typedef enum
44.{
45.    IRQ_VERY_LOW_PRIORITY = 0,
46.    IRQ_LOW_PRIORITY,
47.    IRQ_MEDIUM_PRIORITY,
48.    IRQ_HIGH_PRIORITY,
49.    IRQ_VERY_HIGH_PRIORITY
50.} IrqPriorities;
51. 
52./*!
53. * Structure for the GPIO
54. */
55.typedef struct
56.{
57.    PinNames  pin;
58.    uint16_t pinIndex;
59.    GPIO_TypeDef *port;
60.    uint16_t portIndex;
61.} Gpio_t;
62. 
63. 
64. 
65.#define RIGHT_BLUE_LED                PA_9
66. 
67.extern Gpio_t right_blue_led;
68. 
69.void board_init_mcu( void );
70.void board_timer_init( void );
71. 
72./*!
73. * \brief Initializes the given GPIO object
74. *
75. * \param [IN] obj    Pointer to the GPIO object to be initialized
76. * \param [IN] pin    Pin name ( please look in pinName-board.h file )
77. * \param [IN] mode   Pin mode (This parameter can be a value of @ref GPIOMode_TypeDef)
78. * \param [IN] value  Default output value at initialization
79. */
80. 
81.void gpio_init( Gpio_t *obj, PinNames pin, GPIOMode_TypeDef mode);
82. 
83. 
84.#endif /* SRC_BOARD_H_ */

board.c
01.#include "board.h"
02. 
03.Gpio_t right_blue_led;
04. 
05.void board_init_mcu( void )
06.{
07.    board_timer_init();
08.}
09. 
10.void board_timer_init( void )
11.{
12.    TimersLedsInit();
13.}
14. 
15.void gpio_init( Gpio_t *obj, PinNames pin, GPIOMode_TypeDef mode)
16.{
17.    GPIO_InitTypeDef GPIO_InitStructure;
18. 
19.    if( pin == NC )
20.    {
21.        return;
22.    }
23. 
24.    obj->portIndex = ( uint32_t ) pin >> 4;
25. 
26.    obj->pin = pin;
27.    obj->pinIndex = ( 0x01 << ( obj->pin & 0x0F ) );
28. 
29.    obj->port = ( GPIO_TypeDef * )( GPIOA_BASE + ( obj->portIndex << 10 ) );
30.    RCC_APB2PeriphClockCmd( ( RCC_APB2Periph_GPIOA << obj->portIndex ), ENABLE );
31. 
32.    GPIO_InitStructure.GPIO_Mode = mode;
33.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
34.    GPIO_InitStructure.GPIO_Pin = obj->pinIndex;
35.    GPIO_Init( obj->port, &GPIO_InitStructure );
36.}

timer_board.h
01.#ifndef SRC_TIMER_BOARD_H_
02.#define SRC_TIMER_BOARD_H_
03. 
04.#include <stdint.h>     /* C99 types */
05. 
06.void TimersLedsInit();
07.void RightTimerLedStart(  );
08. 
09.#endif /* SRC_TIMER_BOARD_H_ */

timer_board.c
01.#include <stdint.h>     /* C99 types */
02.#include <math.h>
03.#include "board.h"
04. 
05. 
06.void TimersLedsInit()
07.{
08.    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
09. 
10.    /* Time base configuration */
11.    TIM_TimeBaseStructure.TIM_Prescaler = 56000;
12.    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
13.    TIM_TimeBaseStructure.TIM_Period = 1000;
14.    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
15. 
16.    /* TIM1 clock enable */
17.    RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
18. 
19.    /* Time base configuration */
20.    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseStructure );
21. 
22.    TIM_Cmd( TIM1, DISABLE );
23.}
24. 
25./* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
26. 
27.void RightTimerLedStart(  )
28.{
29.    gpio_init( &right_blue_led, RIGHT_BLUE_LED, GPIO_Mode_AF_PP );  //  XXX Changing this line by the following paragraph (which is the inline equivalent) makes the code work.
30. 
31.//    GPIO_InitTypeDef GPIO_InitStructure;
32.//    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE );
33.//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
34.//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
35.//    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
36.//    GPIO_Init(GPIOA, &GPIO_InitStructure );
37. 
38.    uint16_t CCR1_Val = 500;
39.    uint16_t CCR2_Val = 249;     //  XXX Removing this unused variable makes the code work.
40.    uint16_t CCR3_Val = 166;     //  XXX Removing this unused variable makes the code work.
41. 
42. 
43.    /* PWM1 Mode configuration: Channel1 */
44.    TIM_OCInitTypeDef  TIM_OCInitStructure;
45.    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
46.    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
47.    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
48.    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
49. 
50.    TIM_OC1Init( TIM1, &TIM_OCInitStructure );       // XXX removing this (useless) line makes the code work.
51.    TIM_OC2Init( TIM1, &TIM_OCInitStructure );
52. 
53.    TIM_ARRPreloadConfig( TIM1, ENABLE );
54. 
55.    /* TIM3 enable counter */
56.    TIM_Cmd( TIM1, ENABLE );
57. 
58.    TIM_CtrlPWMOutputs( TIM1, ENABLE );
59.}

Attachments

Outcomes