FreeRTOS V8.2.0 - PIC24_dsPIC Port - Move to EDS space

lz1msz wrote on Monday, June 06, 2016:

Hi guys,

Our new industrial device is based on version 8.2.0, used target is PIC24EP512GU810. This target has 2 types of memory, near(Address 0x0000 - 0x7FFF) and EDS(0x7FFF ->…). For all the used tasks we need 8K RAM for RTOS task stack i features. The access to both memory regions is different and requires different pointer type and access approach. Due to used many libraries (file i/o, Graphics, ethernet, bootloader…) The near memory is full and the linker cannot solve the build due to not enough memory and still we have 45% free space (in the EDS region). The problem is, that moving some firmware module to EDS memory requires source code modification, and most of the librarys contains source code, which is automatically generated and cannot be touched by hand, due to override when next compile (examle is the graphics screens and widgets, generated by PC application).
** Due to most of the memory used is by the RTOS, we need to move the entire module to the EDS memory in order to free near memory.** I still struggle to manualy rewrite all the pointers, function types and parameters, pointer castings defines, typedefs. I managed to reach successfull compilation but still cannot start the scheduler successfully and receive address and stack error traps.
** My question is how we can move the entire RTOS to the EDS space (i suggest there is short cut scenario), and if there is no short cut, i need recomendation of good approach to manually rewite step by step**. In spite of all efforts i doubt of success, due to some functions use pointers to global objects(EDS) and local objects (suppose EDS but may be near because of the linker setting to keep the stack in the near memory)
We missed the release of the device and already have alpha series of 30pcs in field. If we can manage with your help to solve this issue, we will release them now, otherwise we will need to migrate to PIC32MX, which will make big impact for the other libraries migration.

Used target: PIC24EP512GU810
Used compiler: XC16 1.21 PRO
Optimization level: "s"
RTOS version: 8.2.0

Thank you in advance for your support and efforts

Kind regards
Dimitar Belev

rtel wrote on Monday, June 06, 2016:

It is not clear what you are wanting to move into EDS RAM - the
executable code or the heap used for the task stacks (and other RTOS

If you are wanting to move the executable code then you can make use of
something like this in FreeRTOSConfig.h:

#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))

then configure your linker script so the privileged_functions section is
in EDS memory, then the code will end up in that section.

You can do a similar thing with the PRIVILEGED_DATA macro if this memory
is RAM.

If you want to place the heap into a pre-determined memory address, then
either use heap_5.c, or make


lz1msz wrote on Monday, June 06, 2016:

Thank you for your suggestions!

Yes, my point is to free RAM in the near region, and moving the RTOS heap in the EDS region will do the job. The problem is, that accessing memory EDS spase has architectural differencies and different pointer types, which will typpically requires additional pointer attribute in order to access the heap, because this region cannot be accessed from regular pointers directly, also the memcpy library function does not support the EDS space and will generate address error trap (it is needed different pointer type and library copy function, for example _memcpy_eds()). I will try to use the heap5.c and will return with the result.


lz1msz wrote on Monday, June 06, 2016:

I just tested the heap5.c. When the heap is targeted @ address 0x3000 (inside the near region), the objects and handlers are initialized successfully, but i cannot have enough stack due to memory limitation to make full test. When i put the heap in address 0x8000 (the beginning of the EDS region), the first call of xQueueCreate() returns NULL. Please note, that all library functions for memory allocation, copy, compare are dedicated for near memory only, and fail when the address is above the near region. I can see, that the save/restore context is designed for EDS and near memory. Can you suggest can i do anything to make the RTOS working correctly with heap in the EDS space, otherwise i need to migrate to PIC32MX and this will cost additional time and migrating the hardware and all the libraries?

In basic the recomendation for michochip is:

  1. Make all the global variables to be placed in the EDS space, with this approach:
    eds int attribute((eds)) DeviceFlags;

  2. Change the type of all pointers to:
    eds int *MyPointer;

  3. Use another library functions:
    memcpy(&a, &b, 100); ------> _memcpy_eds(&a, &b, 100); // a and b are eds pointers

As far as made attempt, i converted the RTOS source code and reached until successfull build, but still cannot start the scheduler and receive address error and stack error traps.

Thank you

richard_damon wrote on Tuesday, June 07, 2016:

I haven’t worked on the EDS variants of the PIC, but from what I remember, I suspect that you can’t put a task stack in EDS space, but these need to be in the near data space, because the stack pointer doesn’t have the information to know where in EDS space to access.

The option I see is to use the new static creation functions, so you can force the stacks into near space, while other FreeRTOS allocations could be put inton EDS space, and have your tasks minimize their use of stack variables, but use globals/heap for most of their storage.

lz1msz wrote on Tuesday, June 07, 2016:

Hi guys,

The question become:
Is the EDS migration of the RTOS stack not possible due to architecture limitation(the stack pointer does not work in EDS area), or it is possible at reasonable time cost and how to do it. I made parallel support request to microchip guys and will confirm also here if it is possible from architecture point of view(i saw mplab linker option “Keep local stack”, uncheck this and the MPLAB stack can spread in the EDS space, so may be it is somehow possible).

rtel wrote on Tuesday, June 07, 2016:

I think, as you have already done, Microchip (or the reference manual
for the part) are your best bet for an authoritative/definitive answer
on that. It is a very chip specific question, rather than a direct
FreeRTOS question.

richard_damon wrote on Tuesday, June 07, 2016:

Perhaps you don’t understand how EDS works, which would help understand the problem with using EDS memory for the stack.

The Pic24 family has a 16 bit data access address, so physically can only access 64k of data memory at any one time. The bottom 32k of this address space is always and directly mapped to the register set, built in devices and some local memory.

The upper 32 bits is a window that can be mapped via a couple of registers to provide a window into Program space, or for the newer EDS parts, some extended memory called the EDS memory. Note, there is no physical memory at addresses 0x8000 to 0xFFFF, it is just a window. I seem to remember that EDS memory is described as having addresses starting from 0x10000.

The problem with trying to put your stack into EDS memory is that the stack pointer is only a 16 bit address, and has no knowledge of EDS space, so a stack in EDS space would actually be point the EDS registers to the right page, and then point the stack to the window in 0x8000 to 0xFFFF, but if you do so, then you can’t also use it at any time you might need the stack (and since interrupts would need the stack, that is almost any time) to point to another block of EDS memory.

The Microchip compiler also assumes that the stack isn’t in the EDS window (because doing so doesn’t normally make sense), so the code it generates doesn’t keep the EDS window pointing to the ‘stack page’ while the code is running, which will cause all sorts of havok for code executing and using the stack.

My understanding of this is that the hardware might be able to work with the stack in the EDS space, but the whole Microchip tool set assumes it isn’t becuase arciteturally it really doesn’t make sense to try to do it, so any attempt to try is going to fail. EDS space is a tack on to the architecture, adding some limited capability memory to the system. This memory is quite usable for things like buffers and such for code that fully understands that it is EDS memory (and needing to understand is why you need special pointers), but doesn’t work (or at least not well/reliably) for code that isn’t expecting the data to be in EDS space, which includes the use of the stack.