Login

Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

ARM websites use two types of cookie: (1) those that enable the site to function and perform as required; and (2) analytical cookies which anonymously track visitors only while using the site. If you are not happy with this use of these cookies please review our Privacy Policy to learn how they can be disabled. By disabling cookies some features of the site will not work.

ARM Community: [Cortex-M3] PendSV, svc and priorities - ARM Community

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

[Cortex-M3] PendSV, svc and priorities Rate Topic: ****- 1 Votes

#1 User is offline   brag 

  • Member
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 15-June 12

Posted 15 June 2012 - 10:03 AM

Is it possible a case when PendSV will execute earlier than SVcall when both have the same priority? The cpu is Cortex-M3 STM32F1xx

I had an issue when PendSV and SVC have the same priority levels (lowest) with this code:

ePendSV_handler:
	mrs r0,PSP
	stmdb r0!,{r4-r11,lr}

; ... load ... load new PSP valu here to R0

	ldmia r0!,{r4-r11,lr}
	msr PSP,r0
	bx lr


 void eSVCall(void){
	unsigned int a0,a1,a2,a3,svc,*psp;
	
	psp=(U32*)__get_PSP();
	a0=psp[0];a1=psp[1];a2=psp[2];a3=psp[3]; //get registers from user stack
	svc=psp[4]; // service call ID
	
	a0=service(svc,a0,a1,a2,a3);
	
	psp[0]=a0; //overwrite R0(return value) in user stack
}

 SVC usage in thread level code:
	mov R12, #1 ; service call ID 
	mov R0, #123 ; arg
	svc #0
 ; now R0 holds return value


PENDSVSET can be set asynchronously from timer interrupt or from service() function. Sometimes I had a situations when ePendSV was called before eSVCall and overwrited PSP register and then eSVCall fails because new PSP is not tend to the thread which called svc instruction. When I incrased priority of SVcall exception the code above began working correct.

Can some exception execute and terminate executiong svc instruction when svc instruction is fetched but not executed yet?

sorry for bad english...

This post has been edited by brag: 15 June 2012 - 08:38 PM

0

#2 User is offline   Joseph Yiu 

  • Regular Contributor
  • PipPipPip
  • Group: Members.
  • Posts: 217
  • Joined: 01-March 10

Posted 15 June 2012 - 02:55 PM

Since SVC is exception 11 and pendSV is exception 14 , if both of them happen at the same time and if both of them are the same priority, the SVC should take place first.regards. Do you have trace tools? For example, even with low cost debug adapter like ulink2 you can get exception trace, which might be useful for debugging problem like this as it shown the exceptions triggered.
regards,
Joseph


0

#3 User is offline   brag 

  • Member
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 15-June 12

Posted 15 June 2012 - 08:34 PM

Thanks.
I created some testcase for this situation
__svc(42) void svc00(void);

	SCB->SHPR[11-4]=0xF0;  // system handler 11, SVCall
	SCB->SHPR[14-4]=0xF0;  // system handler 14, PendSV
	__cpsie_i();
	SCB->ICSR=SCB_ICSR_PENDSVSET;
	svc00();
	while(1);


ePendSV
	bx lr

eSVCall
	bx lr



Initial stage:
Attached File  stage1.png (27.15K)
Number of downloads: 2
There is a breakpoints on ePendSV and eSVCall.
Then pressing F5. Now we are in PendSV(14) handler but SVCall(13) is in pending state!
Attached File  stage2.png (31.55K)
Number of downloads: 3
So the SVCall will be tail-chained which results incorrect behaviour(using the stack pointer of thread which has not called SVC) within my previous example.

Increasing priority of SVCall (setting SCB->SHPR[11-4]=0xE0; ) and running the code again
Attached File  stage3.png (30.28K)
Number of downloads: 1
Now we are in SVCall(13) handler and PendSV(14) is in pending state. The behaviour will be correct.

This post has been edited by brag: 15 June 2012 - 08:49 PM

0

#4 User is offline   Joseph Yiu 

  • Regular Contributor
  • PipPipPip
  • Group: Members.
  • Posts: 217
  • Joined: 01-March 10

Posted 15 June 2012 - 10:46 PM

I see what is happening now. I didn't really understand what you were doing because I thought PendSV exceptions was triggered from timer interrupt and the timer interrupt happen just before an SVC. What you are having is something different.

The sequence:
- PendSV pending status is set, so the NVIC detect it and accept the interrupt.
- Since PendSV is an asynchronous exception, in parallel the core execute SVC as the last instruction before the core execute the ISR.
- SVC pending is set, but because PendSV exception arrived before SVC, so the NVIC arranged it as tail chain.

To be honest, it seems to be a very strange way to program this. SInce PendSV is asynchronous to the instruction stream, it could take place after several instructions has executed, or it can happened immediately. For example, if the program is running on a device with waitstate on flash, the SVC might not get executed.

If you want to make sure PendSV happen before the SVC, you can use memory barrier instructions:
        SCB->ICSR=SCB_ICSR_PENDSVSET;
        __DSB();
        __ISB();
        svc00();


If you want to make sure PendSV happen after SVC, you should set the PENDSV pending status inside SVC.

Hope this helps.
regards,
Joseph
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic