This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with _global_reg()

Hi guys,

I use a _global_reg var in my program to avoid save/load:

_global_var uint32_t finished_pixels;

this variable is updated in ADC interrupt.

In main, I have following code:

register uint32_t processed_pixels = 0;

finished_pixels = 0;     // Initial global reg

while (processed_pixels >= finished_pixels)

{

     // Process new pixel

     ...

}

But the armcc will optimize all code in while loop, i.e, "// Process new pixel" section.

I tried "volatile _global_var uint32_t finished_pixels;", but the compiler says it has no effect and the same thing happens;

Now I use "volatile register uint32_t processed_pixels = 0;" to avoid the trap, but it looks ugly.

Is that a compile bug?

Any bettrer solutions?

Thanks a lot!

Parents
  • Sorry daith, I made a mistake. As you said, on pixel takes up to 0.25us.

    I use a sub pixel algorithm to accumulate pixel values and location weighted pixel values:

    note: val_sum is a global uint32_t and  weighted_sum is a uint64_t var.

    the assembly code uses  lots save/load as following:

                      ADC1_2_IRQHandler PROC

    ;;;787   

    ;;;788    void ADC1_2_IRQHandler(void)

    000254  b4c0              PUSH     {r6,r7}

    ;;;789    {

    ;;;790      /* Test on ADC end of conversion interrupt */

    ;;;791      // if(ADC_GetITStatus(ADC1, ADC_IT_EOC))

    ;;;792      {

    ;;;793        register uint32_t val;

    ;;;794   

    ;;;795    #if USE_INTERPOLATION

    ;;;796        register uint32_t interpolation;

    ;;;797    #endif

    ;;;798   

    ;;;799        /* Clear ADC end of conversion interrupt -- 读取ADC1->DR时自动清除 */

    ;;;800        // ADC_ClearITPendingBit(ADC1, ADC_IT_EOC)

    ;;;801   

    ;;;802        /* ADC value */

    ;;;803        val = ADC1->DR;

    000256  f04f40a0          MOV      r0,#0x50000000

    00025a  6c00              LDR      r0,[r0,#0x40]

    ;;;804   

    ;;;805    #if USE_INTERPOLATION

    ;;;806        interpolation = (prev_val + val) >> 1;

    ;;;807        prev_val = val;

    ;;;808   

    ;;;809        interpolation *= interpolation;

    ;;;810        val_sum += interpolation;

    ;;;811        curr_pixel++;

    00025c  1c64              ADDS     r4,r4,#1

    00025e  1829              ADDS     r1,r5,r0              ;806

    000260  0849              LSRS     r1,r1,#1              ;806

    000262  fb01f201          MUL      r2,r1,r1              ;809

    000266  4912              LDR      r1,|L1.688|

    000268  4605              MOV      r5,r0                 ;807

    00026a  68cb              LDR      r3,[r1,#0xc]          ;810  ; val_sum

    ;;;812        weighted_sum += interpolation * curr_pixel;

    00026c  e9d1c704          LDRD     r12,r7,[r1,#0x10]

    000270  189e              ADDS     r6,r3,r2              ;810

    000272  fb02f304          MUL      r3,r2,r4

    000276  2200              MOVS     r2,#0

    000278  eb130c0c          ADDS     r12,r3,r12

    00027c  eb420307          ADC      r3,r2,r7

    ;;;813    #endif

    ;;;814   

    ;;;815        val *= val;

    000280  4368              MULS     r0,r5,r0

    ;;;816        val_sum += val;

    000282  4406              ADD      r6,r6,r0

    ;;;817        curr_pixel++;

    000284  1c64              ADDS     r4,r4,#1

    ;;;818        weighted_sum += val * curr_pixel;

    000286  4360              MULS     r0,r4,r0

    000288  eb10000c          ADDS     r0,r0,r12

    00028c  415a              ADCS     r2,r2,r3

    00028e  60ce              STR      r6,[r1,#0xc]  ; val_sum

    ;;;819   

    ;;;820    #if USE_INTERPOLATION

    ;;;821        if (curr_pixel >= (PIXEL_CNT << 1))

    000290  e9c10204          STRD     r0,r2,[r1,#0x10]

    000294  f5b46f00          CMP      r4,#0x800

    ;;;822    #else

    ;;;823        if (curr_pixel >= PIXEL_CNT)

    ;;;824    #endif

    ;;;825        {

    ;;;826          /* 已采集足够像素,关掉ADC中断 */

    ;;;827          ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);

    ;;;828        }

    ;;;829      }

    ;;;830    }

    000298  bf3c              ITT      CC

    00029a  bcc0              POPCC    {r6,r7}

    00029c  4770              BXCC     lr

    00029e  2200              MOVS     r2,#0                 ;827

    0002a0  bcc0              POP      {r6,r7}               ;827

    0002a2  2104              MOVS     r1,#4                 ;827

    0002a4  f04f40a0          MOV      r0,#0x50000000        ;827

    0002a8  f7ffbffe          B.W      ADC_ITConfig

    ;;;831   

                              ENDP

    For a STM32F302CBT6@72MHZ, only 93M/s*0.25us=23 single cycle instructions allowed.

    Also. the row pixel values should be send to UART in calibrate mode.

    So I tried get data in ADC interrupt & process data in main loop/calibrate loop to avoid save/load.

    Could you give me further suggestion?

    Thanks.

Reply
  • Sorry daith, I made a mistake. As you said, on pixel takes up to 0.25us.

    I use a sub pixel algorithm to accumulate pixel values and location weighted pixel values:

    note: val_sum is a global uint32_t and  weighted_sum is a uint64_t var.

    the assembly code uses  lots save/load as following:

                      ADC1_2_IRQHandler PROC

    ;;;787   

    ;;;788    void ADC1_2_IRQHandler(void)

    000254  b4c0              PUSH     {r6,r7}

    ;;;789    {

    ;;;790      /* Test on ADC end of conversion interrupt */

    ;;;791      // if(ADC_GetITStatus(ADC1, ADC_IT_EOC))

    ;;;792      {

    ;;;793        register uint32_t val;

    ;;;794   

    ;;;795    #if USE_INTERPOLATION

    ;;;796        register uint32_t interpolation;

    ;;;797    #endif

    ;;;798   

    ;;;799        /* Clear ADC end of conversion interrupt -- 读取ADC1->DR时自动清除 */

    ;;;800        // ADC_ClearITPendingBit(ADC1, ADC_IT_EOC)

    ;;;801   

    ;;;802        /* ADC value */

    ;;;803        val = ADC1->DR;

    000256  f04f40a0          MOV      r0,#0x50000000

    00025a  6c00              LDR      r0,[r0,#0x40]

    ;;;804   

    ;;;805    #if USE_INTERPOLATION

    ;;;806        interpolation = (prev_val + val) >> 1;

    ;;;807        prev_val = val;

    ;;;808   

    ;;;809        interpolation *= interpolation;

    ;;;810        val_sum += interpolation;

    ;;;811        curr_pixel++;

    00025c  1c64              ADDS     r4,r4,#1

    00025e  1829              ADDS     r1,r5,r0              ;806

    000260  0849              LSRS     r1,r1,#1              ;806

    000262  fb01f201          MUL      r2,r1,r1              ;809

    000266  4912              LDR      r1,|L1.688|

    000268  4605              MOV      r5,r0                 ;807

    00026a  68cb              LDR      r3,[r1,#0xc]          ;810  ; val_sum

    ;;;812        weighted_sum += interpolation * curr_pixel;

    00026c  e9d1c704          LDRD     r12,r7,[r1,#0x10]

    000270  189e              ADDS     r6,r3,r2              ;810

    000272  fb02f304          MUL      r3,r2,r4

    000276  2200              MOVS     r2,#0

    000278  eb130c0c          ADDS     r12,r3,r12

    00027c  eb420307          ADC      r3,r2,r7

    ;;;813    #endif

    ;;;814   

    ;;;815        val *= val;

    000280  4368              MULS     r0,r5,r0

    ;;;816        val_sum += val;

    000282  4406              ADD      r6,r6,r0

    ;;;817        curr_pixel++;

    000284  1c64              ADDS     r4,r4,#1

    ;;;818        weighted_sum += val * curr_pixel;

    000286  4360              MULS     r0,r4,r0

    000288  eb10000c          ADDS     r0,r0,r12

    00028c  415a              ADCS     r2,r2,r3

    00028e  60ce              STR      r6,[r1,#0xc]  ; val_sum

    ;;;819   

    ;;;820    #if USE_INTERPOLATION

    ;;;821        if (curr_pixel >= (PIXEL_CNT << 1))

    000290  e9c10204          STRD     r0,r2,[r1,#0x10]

    000294  f5b46f00          CMP      r4,#0x800

    ;;;822    #else

    ;;;823        if (curr_pixel >= PIXEL_CNT)

    ;;;824    #endif

    ;;;825        {

    ;;;826          /* 已采集足够像素,关掉ADC中断 */

    ;;;827          ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);

    ;;;828        }

    ;;;829      }

    ;;;830    }

    000298  bf3c              ITT      CC

    00029a  bcc0              POPCC    {r6,r7}

    00029c  4770              BXCC     lr

    00029e  2200              MOVS     r2,#0                 ;827

    0002a0  bcc0              POP      {r6,r7}               ;827

    0002a2  2104              MOVS     r1,#4                 ;827

    0002a4  f04f40a0          MOV      r0,#0x50000000        ;827

    0002a8  f7ffbffe          B.W      ADC_ITConfig

    ;;;831   

                              ENDP

    For a STM32F302CBT6@72MHZ, only 93M/s*0.25us=23 single cycle instructions allowed.

    Also. the row pixel values should be send to UART in calibrate mode.

    So I tried get data in ADC interrupt & process data in main loop/calibrate loop to avoid save/load.

    Could you give me further suggestion?

    Thanks.

Children
No data