I’m working on a port in which the portSTACK type needs to be 20-bits - has anyone done a port with this being 20-bits wide?
If so - can you elaborate on how you made it work?
The PIC24 does simlar things. Pointers are 16bits, but the address space is 24bits - which makes it seem tricky to point to the start address of a task. Luckily in this case the compiler takes care of it for you through the use of a poitner jump table.
So what does the processor do when it stacks 20bit registers into 16bit wide RAM? (I could always read the datasheet but I’m a bit pushed for time). Does it just loose 4bits of the third register byte? The MSP430 has quite a few registers, so this would seem wastefull, but maybe this is not a problem as you get a lot more memory space to play with.
Is your problem then that you cannot declare the stack type as 16bits, as they are in fact 20bits, and you cannot declare the stack type as 32bits, as this gives you a whole byte (plus the 4 bits) too much (sorry for basic questions). Seems a bit tricky.
It sounds like it is using 32bits per 20bit value, in which case this would make the stack type unsigned long. You would have to setup the initial stack in port.c using 4bytes per 20bit register.
Looks like everything is OK up until the portRESTORE_CONTEXT when xPortStartScheduler is called - as soon as the reti is called - the app goes into the weeds.
Everything looks ok - the starting addr of the 1st task is where it’s supposed to be - but it’s 32 bits now vs. 16 (or 20) - maybe that’s where things are going wrong…
In your debugger, are you able to break in an interrupt routine, then inspect the stack just before a compiler generated reti instruction, so you can inspect the stack to see how the address is stored? You can then copy this. Maybe there is some magic somewhere, as per the PIC24 jump table mentioned previously.
One of the issues is in port.c - if everything is made 32-bits - including pxCode and portFLAGS_INT_ENABLED - from the databook
on RETI:
RETI Return from interrupt
Syntax RETI
Operation @SP → SR.15:0 Restore saved status register SR with PC.19:16
SP + 2 → SP @SP → PC.15:0 Restore saved program counter PC.15:0
SP + 2 → SP House keeping
Description The status register is restored to the value at the beginning of the interrupt
service routine. This includes the four MSBs of the program counter PC.19:16.
The stack pointer is incremented by two afterwards.
The 20-bit PC is restored from PC.19:16 (from same stack location as the
status bits) and PC.15:0. The 20-bit program counter is restored to the value
at the beginning of the interrupt service routine. The program continues at the
address following the last executed instruction when the interrupt was granted.
The stack pointer is incremented by two afterwards.
Looks like 16-bit values are expected - not 32-bit. I did a fix up on this and got a little further down the road - but the app still goes in the weeds.
Since I had the portFLAGS_INT_ENABLED set to be 0x08 - this was stored as 0x00000008 - and after the RETI was done - the 0x0008 was being grabbed by the SR but the
PC was being set to 0x0000; The task’s address was after that - stored as 0x0000383E; - but the PC didn’t get that far since jumping to weed-land at 0x0000;
I’m going to have to stop for today but I’ll be back at it this weekend.
So 4 bits of the program counter are stored in the unused bits of the stack pointer. Looks like you are going to have to do some shifting of values in pxPortInitialiseStack() to get everything in the right place. There is a port that does this already I think (?) but I cannot remember which processor it is.
Can you provide me with a part number or a link to a document that describes the architecture? I’ve looked at a couple on the TI site but they seem to have 16bit program counters.
I’m getting to the first vTaskDelayUntil - and when the RETA is executed - it bombs.
It looks like the SP may be off by one word - I just took a closer look in the debugger - and for some reason - this is what it looks like -
there’s a popw.m #6,R11 in vPortYield(); - and it looks like where the SP is pointing is SR info - (one word) - then the address of what should be executed - like
what you’d expect in a reti - but in this case it’s a RETA - from the datasheet:
* RETA Return from subroutine
Syntax RETA
Operation @SP → PC.15:0 LSBs (15:0) of saved PC to PC.15:0
SP + 2 → SP @SP → PC.19:16 MSBs (19:16) of saved PC to PC.19:16
SP + 2 → SP
Emulation MOVA @SP+,PC
Description The 20-bit return address information, pushed onto the stack by a CALLA
instruction, is restored to the program counter PC. The program continues at
the address following the subroutine call. The status register bits SR.11:0 are
not affected. This allows the transfer of information with these bits.
So - this is different than RETI - the SR isn’t affected - so the PC is picking up what looks like the SR info and then entering weed-land.
But - it looks like the SP is pointing to what would be expected by a RETI vs. a RETA.
It is interesting to note that the stacking of the address is different between CALLA/RETA and Interrupt/RETI. In the interrupt case PC.15:0 is pushed first, while in the CALLA case PC.15:0 is pushed last.
After doing the ‘shift fix-up’ - could that affect the tskTCB down the road? I’ve looked that this and don’t think so - but wanted to see what
you thought.