MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Hello RTOSer’s and Richard, Someone has asked me to look at the port for the MSP430F6659. Note this ‘430 has a discontinuous memory space for internal RAM – there is a lower 16KB < 0xFFFF and the rest ~ 49KB is greater than 0xFFFF. The part has 66 KB of RAM and 512 KB of FLASH – so it is one of the ‘bigger’ ‘430’s. The ‘regular’ ‘430 demo works fine as long as you don’t allocate too much memory. So, what does that mean? I had a port handy for the ‘5635. I didn’t have the hardware at first – the other port I posted was from stuff in the simulator. I thought I had something that would work. I modified the port the blink the 3 LED’s on the ‘PZ100USB demo board from TI – the usual LED tasks run fine using the usual demo code – no problem. But when I try to allocate > 20KB using the FreeRTOS heap manager – the port fails. I tried this with heap1 and heap3. Using the malloc from IAR resulted in the same thing when trying to allocate > 20KB. I looked in the map files in both instances – and noticed this difference: In the first case – where I allocate around 14KB of memory – the DATA20Z segment falls into: DATA20Z 2406 – 5E2F 3A2A rel 1 and in the case that fails: DATA20_Z 000F0000 – 000F5229 522A rel 1 I took a look at the port assembly and I don’t think the problem is there – but I am not 100% certain yet. I have traced through it – one problem is the tools become a bit unstable when an error occurs; so it will take some additional time to determine what is wrong. I am using v7.5.3 in the port. So – there seems to be a problem with addressing – when something is in the DATA20_Z segment when it is mapped > 0xFFFF by the linker – the port fails. I have checked the variables that are addressed int the port assembly – I tried changing those – but the port fails in the same way. Note xTickCount does not increment before the failure – so we are not reaching that yet. All of the demo tasks are made successfully. The 430 has a requirement to have all IRQ code in the lower memory – at or below 0xFFFF – I don’t think there is an issue – vPortTickISR in the port is below 0xFFFF in case you were wondering. I will post results as I have them – I am working on this currently on a time available basis. Thanks, John W.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Hello – just wondering – has anyone else out there looked at this? I am planning on looking at this again in the very near future using ver 8.x (latest) and the latest from IAR. Regards, John W.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Richard, I was wondering if a small enhancement could be made to the heap files. Can there be a new definition in FreeRTOSConfig.h – such as: #define MORETHANONECONTIGUOUSHEAP_SPACE 2 // number indicating how many And – then: #ifdef MORETHANONECONTIGUOUSHEAP_SPACE #define configTOTALHEAPSIZE1 … #define configTOTALHEAPSIZE2 … … #else #define configTOTALHEAPSIZE … #endif … So that processors that have a non-contiguous heap could be used? It may be necessary to know what the memory map is of memory to be used in this manner – could be helpful, especially if addresses cross boundaries – like 0xFFFF to 0x10000. Thanks, John W.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Hello John I vote for this one! Atmel’s SAM4E Xplained board has the same problem: it has two separate banks of SRAM, each 0.5MB. I solved it temporarily by including two instances of heap_<n>.c, which isn’t elegant. Beside having more-than-one-contiguous-heap-space, it would be very useful if the actual size of the heap can be set at runtime. ~~~~~~ /* Allocate the memory for the heap. */ static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; ~~~~~~ Often “configTOTALHEAPSIZE” is unknown at compile time, but it is known at link-time. The linker is able to set 2 pseudo variables from which the offset and size can be calculated: ~~~~~~ extern const void __heapstart; extern const void __heapend;

define SIZE ((uint32t) ( ((const char*)&heap_end) – ((const char*)&heapstart) ))

define START ((uint32_t) ((const char*)&__heap_start))

~~~~~~ There are several versions of heap<n>.c of which I find _heap4.c_ the best. It implements its own version of malloc/free in a very fast, efficient and correct way. If you use heap_4.c, make sure that there are no hidden calls to standard malloc/free. E.g. you should make the following replacements: ~~~~~~ localtime -> localtimer gmtime -> gmtimer strtok -> strtok_r ~~~~~~ and probably some more. The “_r” versions are also thread-safe because you provide your own memory. Proposal: ~~~~~~ struct xMemoryEntry { uint32t mem; sizet size; }; struct xMemoryEntry entries[] = { { 0x61000000, 80000 }, { 0x63000000, 80000 }, }; void main() { pvPortSetMemories(entries, sizeof entries/sizeof entries[0]); } ~~~~~~ What would you think of this? (it is a bit tricky, because before this call, no malloc’s can be done). Regards, Hein

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

There are two fairly common requests related to the memory allocation, both of which I think already have outstanding feature request tickets: 1) Allowing static allocation. Although not directly documented as such, there is actually already a mechanism for statically allocating the TCB and statck used by a task, but not for allocating the memory used by queues/semaphores/mutexes/etc. It would be easy enough to add in a mechanism for statically allocating the memory for these other objects too – but there are a couple of issues that must be accounted for – firstly an unwelcome increase in the code size, and secondly increasing the complexity for end users (the more options and choices the more complex and confusing). If static allocation is required for reasons of safety critical qualification then it is actually quite feasible to qualify heap_1.c, which cannot suffer non-determinism or memory fragmentation, so does not suffer the issues that safety critical systems try and avoid. It is really just a statically allocated array. 2) Allow the heap to span multiple memory regions. First a note about using the linker variables to dimension the heap rather than the configTOTALHEAPSIZE constant. I am definitely not in favour of that as it is not portable even between different GCC projects, let along to the other 17 or so compilers for which there are official FreeRTOS ports. Also these linker variables are used by the standard library malloc and free, and I want to draw a clear distinction between the two methods (the standard library allocation and FreeRTOS allocation). If you need a fixed size heap because your application just creates all the RTOS objects up front, then never deletes anything (which is the normal case), then the xPortGetFreeHeapSize() and xPortGetMinimumEverFreeHeapSize() functions can be used to see how much heap was actually used, then the configTOTALHEAPSIZE variable can be adjusted accordingly. It should also be noted that FreeRTOS keeps memory allocation in the portable layer as it is recognised than different embedded projects have very different memory allocation requirements. It is therefore always possible to just add in your own version of pvPortMalloc and vPortFree to do whatever you want, however… …heap4.c is the favoured memory allocation for all applications except the most trivial or the most safety critical. heap4.c in effect keeps a linked list of free memory blocks, with the list jumping over the blocks that are allocated to the application. At initialisation time heap4.c just creates one block that covers the entire memory region on the assumption there is only one contiguous heap. There is no reasons why heap4.c could not be extended such that at initialisation time a linked list is set up whereby the first block covers the entire first contiguous heap areas, with the block pointing to the second contiguous heap areas, with that block pointing to the next, and so on for however many heap areas there were. Only the initialisation code would need to change. The code that allocates and frees memory would not need to change because to it the gaps in the memory that are actually gaps between separate heap areas would just look like gaps that were created by memory actually being allocated to the application. The user could initialise such a heap scheme by passing in an array of structures, with each structure defining the start address and size of each available heap area. The function to do so could just be added to the heap_4.c implementation. Users with just a single array of memory (as per the current scheme) could ignore the new function, the more advanced users with complex memory maps could call the new function as a first step – before they create any RTOS primitives (tasks, queues, event groups, etc.). One disadvantage of this scheme is that there is no way of telling the allocation function from which heap area it should allocate the RAM if there is more than one heap area in use. This is actually quite important as often one heap area will be in fast internal static RAM, which is a good place to store task stacks, and another heap area might be in a huge external RAM which may be much slower and not so suitable for use as a stack. Ideally when allocating you would want to say from which memory (fast or slow) the allocated block should come, and it might be best to ensure any changes cover that option too – although that could introduce incompatibilities…. Regards, Richard Barry

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Hi John, Take a look at heap_5.c in SVN (link below) – does this do what you want? I have added usage notes to the top of the file as there is nothing on the FR.o website about this yet. You will also need the head revision of portable.h. https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/MemMang/heap_5.c https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/include/portable.h Note there are download links enabling you to download just these files on these URLs. Regards, Richard Barry.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Hello Richard, This looks great. I will give it a try and get back to you. Once again, thanks for the great work! I think others will benefit from this too. Best Regards, John Westmoreland

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Richard, Added the new files – but I am getting an error – I have attached a screen shot. ‘a value of type “unsigned long” cannot be used to initialize an entity of type “uint8_t*” I will look into this more – but thought you may recognize the issue. Thanks, John

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Richard, Does xPortGetFreeHeapSize(); work with this yet? And, for HeapSize – do you just add all of the memory together for configTOTALHEAPSIZE? I guess so. (Edit)The program is stopping in an NMI now. I did a cast to ‘fix’ the above – not 100% sure all is well with that but I just cast those two values for now. Thanks, John

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Ah right, documentation error. The first number in each position is in fact a pointer to a memory address, so needs to be cast. I will update the comment in the file to show this: HeapRegiont xHeapRegions[] = { { ( uint8t * ) 0x2400UL, 0x4000 }, { ( uint8_t * ) 0xF0000UL, 0xC000 }, { NULL, 0 } }; In your case you may find that sizeof( uint32 ) > sizeof( uint8_t * ) … in which case you may need to remove the ‘UL’ from the end of the addresses to prevent a different warning. Regards.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

[our previous two posts crossed mid Ether] xPortGetFreeHeapSize() should be working too but you have to be careful how you interpret its results. Just because it says there are 100 bytes left it does not necessarily mean you can allocate 100 bytes as it does not say anything about where the bytes are or how they are fragmented. For example you may have 2 free blocks in your first region, each of which are 8 bytes each, with another block of 84 bytes in the second region. In that case the biggest block you would able to allocate would be (typically on a 32-bit architecture at least) 76 bytes (as 8 bytes in the 84 byte block would get consumed by the heap’s own internal data structures). Regards.

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Richard, Thanks. The NMI is me clobbering myself. I allocated the entire memory space, which of course you can’t do due to other system resources needing memory. I just allocated the upper 32 KB, and that is running – so this does appear to be working. I will ‘play’ with it a little more to see if I can cross the 0xFFFF boundary OK. Thanks, John

MSP430X Port for MSP430F6659 – Has Discontinuous SRAM Memory Model

Richard, I just allocated 8KB below 0xFFFF and the ‘upper’ 32KB and that is running OK. I set configTOTALHEAPSIZE to 33K, something safe but larger than 32KB, and the demo program is happy. So, other than grappling with the new (alternate) definition of what xPortGetFreeHeapSize() returns, and also keeping track of what the target system could be doing in different regions of memory (which is why it’s a good idea to do memory management with FreeRTOS), I would say this is working. The demo I have will break very quickly if something was amiss, and it is running fine. So, I would say you could declare success here – at least for a ‘first release’.
Good work and a BIG enhancement. Thanks, John