FreeRTOS 10.2.1 for the Arduino M0+ compilation errors.

mjachapman wrote on Tuesday, July 02, 2019:

Hi, I have taken a Version 8.3.1 Free RTOS that compiles and runs on an Adafruit M0+ and used that as the basis of an upgrade to 10.2.1. There is another Arduino library based on 10.2.1 but its for AVR processors and includes a lot of assembler inserts so is less useful to me.

The IDE is Atmel Studio that uses a GCC compiler.

The files came from the M0+ port.

However I have to the stage of trying to get it compile but unfortunately is fails around a function that includes assembler inserts:

void vPortStartFirstTask( void )
{
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
table offset register that can be used to locate the initial stack value.
Not all M0 parts have the application vector table at address 0. /
__asm volatile (
" .syntax unified \n"
" ldr r2, pxCurrentTCBConst2 \n" /
Obtain location of pxCurrentTCB. /
" ldr r3, [r2] \n"
" ldr r0, [r3] \n" /
The first item in pxCurrentTCB is the task top of stack. /
" adds r0, #32 \n" /
Discard everything up to r0. /
" msr psp, r0 \n" /
This is now the new top of stack to use in the task. /
" movs r0, #2 \n" /
Switch to the psp stack. /
" msr CONTROL, r0 \n"
" isb \n"
" pop {r0-r5} \n" /
Pop the registers that are saved automatically. /
" mov lr, r5 \n" /
lr is now in r5. /
" pop {r3} \n" /
Return address is now in r3. /
" pop {r2} \n" /
Pop and discard XPSR. /
" cpsie i \n" /
The first task has its context and interrupts can be enabled. /
" bx r3 \n" /
Finally, jump to the user defined task code. */
" \n"
" .align 4 \n"
"pxCurrentTCBConst2: .word pxCurrentTCB "
);
}

If I comment out assembler in this function it compiles but the compliation error doesn’t seem to be related to the code!

Compiling ‘4_RTOS_10_2_SAMD21_Demo_V01’ for ‘Adafruit Feather M0’
cc3u5LMY.s: Assembler messages
Error compiling project sources
Build failed for project ‘4_RTOS_10_2_SAMD21_Demo_V01’

cc3u5LMY.s*:86: cannot honor width suffix – mov r4,#128
cc3u5LMY.s*:87: lo register required – sub r3,r0,#4
cc3u5LMY.s*:88: cannot honor width suffix – lsl r4,r4,#17
cc3u5LMY.s*:90: lo register required – sub r3,r3,#4
cc3u5LMY.s*:93: lo register required – sub r3,r3,#4
cc3u5LMY.s*:95: lo register required – sub r3,r3,#20
cc3u5LMY.s*:96: lo register required – sub r0,r0,#64
cc3u5LMY.s*:129: cannot honor width suffix – mov r0,#0
cc3u5LMY.s*:149: cannot honor width suffix – mov r2,#255
cc3u5LMY.s*:151: cannot honor width suffix – lsl r2,r2,#16
cc3u5LMY.s*:152: cannot honor width suffix – orr r2,r1
cc3u5LMY.s*:155: cannot honor width suffix – mov r2,#255
cc3u5LMY.s*:156: cannot honor width suffix – lsl r2,r2,#24
cc3u5LMY.s*:157: cannot honor width suffix – orr r2,r1
cc3u5LMY.s*:161: cannot honor width suffix – mov r4,#0
cc3u5LMY.s*:169: cannot honor width suffix – mov r2,#7
cc3u5LMY.s*:199: cannot honor width suffix – mov r3,#250
cc3u5LMY.s*:200: cannot honor width suffix – lsl r3,r3,#2
cc3u5LMY.s*:225: cannot honor width suffix – mov r2,#128
cc3u5LMY.s*:226: cannot honor width suffix – lsl r2,r2,#21
cc3u5LMY.s*:255: lo register required – add r2,r2,#1
cc3u5LMY.s*:289: lo register required – sub r3,r3,#1
cc3u5LMY.s*:345: cannot honor width suffix – mov r2,#128
cc3u5LMY.s*:347: cannot honor width suffix – lsl r2,r2,#21

rtel wrote on Wednesday, July 03, 2019:

Can you show the command line to GCC - I suspect the MCU definition
passed to the command line is wrong.

mjachapman wrote on Wednesday, July 03, 2019:

I’m not sure how that happens Richard. The MCU is selected in a dropdown on the ATMEL IDE (likewise using the Arduino IDE) and the core software is built under the covers with the application code and it works. The library based on 8.3.2 works but the code for this function is slightly different

I should point out that there are many assembler code inserts but it is only the one functiionlisted above that seems to be causing a problem. What is pussling is that the error listing doents match the code.

I looked up the error on the internet and it suggests the cause is the assembler code.

mjachapman wrote on Wednesday, July 03, 2019:

Puzzling! Dislexic fimgers.

rtel wrote on Wednesday, July 03, 2019:

I don’t think there is an official V8.3.1 of FreeRTOS, seems V8.2.3 was
the last in the 8.x.x line. Diffing the V8.2.3 and 10.1.1 code I see
the assembly was updated to use unified syntax - which I think was
necessary due to changes in the newer versions of GCC. So my best guess
at the moment is that you are using an older GCC version.

mjachapman wrote on Thursday, July 04, 2019:

Yes you’re right its is the earlier Arduino library is based on V8.3.2 and it does compile and run. I assume youmeant 10.2.1?

Are you suggesting that V8.3.2 would not compile owing to the more rigorous assembler syntax?

Do you know what the verson of toolshain that should work?

Note: The later Arduino library for avr processor is based on 10.2.0 and it compiles but I’m perhaps it uses a different toolchain?

Yes I’m using Code Compare to investigate the problem but the snag is changes in structure and increased functionality makes it difficult to spot if there are significant changes in the versions.

rtel wrote on Thursday, July 04, 2019:

Are you suggesting that V8.3.2 would not compile owing to the more
rigorous assembler syntax?

The assembly code was updated because it needed to be for use with newer
compiler versions. Hence I’m suggesting that if you have problems
compiling the code then it might be because you are using an older
compiler version that expects the older assembly syntax.

Do you know what the verson of toolshain that should work?

Not without looking through the gcc change logs I’m afraid.

Note: The later Arduino library for avr processor is based on 10.2.0 and
it compiles but I’m perhaps it uses a different toolchain?

That is a different architecture, hence is building a different FreeRTOS
port.

mjachapman wrote on Friday, July 05, 2019:

Thanks Richard.

From what I have read the last upgrade to the Cortex toolchain was 12/2018 and the Arduino IDE would have picked that up with the latest version (1.8.9) that I’m using.

I have copied in the code from V 8.3.2 and it works as far as I can tell, i.e. compiles with no assembler errors and the sketch (app) runs with the rest of V 10.2.1 port. I’ve yet to check the configurable options but the fact that it now runs is a good start.

I have changed the function as shown below which suggests that there is something not quite right with the assembler syntax as suggested by an Cortex article I found on the internet.

void vPortStartFirstTask( void )
{
/* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector
table offset register that can be used to locate the initial stack value.
Not all M0 parts have the application vector table at address 0. */

// Code from V 8.3.2
	__asm volatile(
	"	ldr	r2, pxCurrentTCBConst2	\n" /* Obtain location of pxCurrentTCB. */
	"	ldr r3, [r2]				\n"
	"	ldr r0, [r3]				\n" /* The first item in pxCurrentTCB is the task top of stack. */
	"	add r0, #32					\n" /* Discard everything up to r0. */
	"	msr psp, r0					\n" /* This is now the new top of stack to use in the task. */
	"	movs r0, #2					\n" /* Switch to the psp stack. */
	"	msr CONTROL, r0				\n"
	"	pop {r0-r5}					\n" /* Pop the registers that are saved automatically. */
	"	mov lr, r5					\n" /* lr is now in r5. */
	"	cpsie i						\n" /* The first task has its context and interrupts can be enabled. */
	"	pop {pc}					\n" /* Finally, pop the PC to jump to the user defined task code. */
	"								\n"
	"	.align 2					\n"
	"pxCurrentTCBConst2: .word pxCurrentTCB	  "
	);
// Code from the V10.2.1 port
//__asm volatile (
//"	.syntax unified				\n"
//"	ldr  r2, pxCurrentTCBConst2	\n" /* Obtain location of pxCurrentTCB. */
//"	ldr  r3, [r2]				\n"
//"	ldr  r0, [r3]				\n" /* The first item in pxCurrentTCB is the task top of stack. */
//"	adds r0, #32				\n" /* Discard everything up to r0. */
//"	msr  psp, r0				\n" /* This is now the new top of stack to use in the task. */
//"	movs r0, #2					\n" /* Switch to the psp stack. */
//"	msr  CONTROL, r0			\n"
//"	isb							\n"
//"	pop  {r0-r5}				\n" /* Pop the registers that are saved automatically. */
//"	mov  lr, r5					\n" /* lr is now in r5. */
//"	pop  {r3}					\n" /* Return address is now in r3. */
//"	pop  {r2}					\n" /* Pop and discard XPSR. */
//"	cpsie i						\n" /* The first task has its context and interrupts can be enabled. */
//"	bx   r3						\n" /* Finally, jump to the user defined task code. */
//"								\n"
//"	.align 4					\n"
//"pxCurrentTCBConst2: .word pxCurrentTCB	  "
			  //);

}

mjachapman wrote on Friday, July 05, 2019:

Richard, I just reread your last response and I think there is a misunderstanding of what I was trying to say.

  1. V 8.3.2 compiles and runs the same sketch that I’m using for V 10.2.1 so it is okay.
  2. V 10.2.1 has the problem with the assembler insert that I replaced by the same function in V 8…3.2 and it works. You were suggesting that assembler inserts had to be modified to use the later of the toolchain. Bear in mind its only that function in my port of 10.2.1 that seesm to have a problem and there are many functions with assembler inserts .

At the moment I’m happy running the V 10.2.1 with the fix I’ve incorporated in my previous comment, unless you say otherwise?

rtel wrote on Friday, July 05, 2019:

That sounds right and probably confirms my suspicion that you are using
an old compiler version. You have the latest FreeRTOS kernel code
except for the assembly function in question, which you have patched
with code from the kernel version that was written for older compilers.

Anyway - sounds like you are up and running - which is great.