cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with switch/case

Jakub B
Associate III
Posted on April 03, 2018 at 15:22

Hi

I got a problem with a switch in my MCU. I use custom board with STM32F030C8T6.

This here is part of my program:

void rozkaz3(void) {

switch(bufor[3]){

case 0:

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);

break;

case 1: HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);

break;

case 2:

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET);

break;

case 3:

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);

break;

case 5:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);

break;

case 6:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

break;

case 7:

case 4:

default:

break;

case 12:

NVIC_SystemReset();

break;

it switches on and off outputs i chose based on number. My board has 6 outputs. Case 4 and case 7 are not configured and not connected.

If i order case 0,1,2,3,5,6,11,12 all works well.

If i order case 4 or 7 my program works on case 0 then case 4/7. If i delete case 0 it will work on case 1 and then case 4/7 and so on.

It works first available case in switch then case i ordered.

Now if i change only this:

case 7:

case 4:

default:

HAL_Delay(1000);

break;

I works ok.

And with HAL_Delay(1) its not working again.

Whats happening and how to make it work right without HAL_Delay ?

Note: this post was migrated and contained many threaded conversations, some content may be missing.
34 REPLIES 34
Posted on April 04, 2018 at 13:19

So I think that takes us right back to the very first reply - from

Waclawek.Jan

:

https://community.st.com/0D70X000006SlY6SAK

And from

meyer.frank

:

https://community.st.com/0D70X000006SlY6SAK

Something else is 'corrupting'

bufor[3] ...

Posted on April 04, 2018 at 13:29

My experience tells me:

  • NEVER use a synchronous wait;
  • Always work on a snapshot copy of asynchronous data (keyword PLC ...)
Posted on April 04, 2018 at 13:30

Yes, there is a race condition on bufor: it is memset to 0xff in the main loop, while it can be destination of memcpy in RxCpltCalback.

BTW, DMA receive function is non blocking and the DMA completion callback happens on interruption (so asynchronously).

Start to fixing the race first.

Posted on April 04, 2018 at 13:43

memset was added as a countermeasure (was trying to eliminate using case 0 if bufor was not cleared - nothing changed) and is not really needed (as well as bufor++ in callback) especially if it can cause trouble.

i originally was doing comunication on IT and changed to DMA but if you think it will help ill go back to it (its not much of work).

edit: i removed clearing buffor and changed from DMA to IT - still no change

Posted on April 04, 2018 at 13:59

Whether it's interrupts of DMA is irrelevant - you are working on a buffer while something else is (or may be) still writing to it!

:(

You need to wait until you have a complete message, and then process it.

If there's a possibility that another message might start coming in before you've finished with the previous one then, as

meyer.frank

‌ said, you will need to take a copy of the message to work on ...

Posted on April 04, 2018 at 14:05

If you debug around the memcpy, what is the content of Receive and bufor ?

Posted on April 04, 2018 at 14:14

Recieve is constantly changing because im asking for states of inputs. Thats why i have 'ramka'. If ramka is set to 1 i dont write another package from recieve to bufor. bufor is available for change only after doing rozkaz3, stany or config. then is cleared and i do another order from recieved.

There is no other instance of writing to bufor aside after completing order.

ramka is cleared in main loop, and set to 1 right after recieving package (if ramka is zero) and right after this i copy recieved to bufor (in callback)

Posted on April 04, 2018 at 14:33

after checking debug:

recieved is checked for address

recieved is writen to bufor number after number

recieved is changing (because other orders are flying in)

recieved is not copied to bufor (because ramka is set 1)

i do rozkaz3, stany, config from bufor

then ramka is set 0

and again recieve and bufor from beggining

Posted on April 04, 2018 at 14:40

Set a breakpoint at memcpy, inspect Receive at *that* moment, the program is breaked and no other incoming data is received, the Receive area will not change until you restart. Can you see the exact content of what you sent through the UART ?

Posted on April 04, 2018 at 19:43

Now follow Laurent's guidelines, but next time, you should present a consistent set of code and problem description; don't just make random changes and then post.

JW