µTasker Forum
µTasker Forum => µTasker general => Topic started by: beethoven62 on November 26, 2008, 04:51:04 PM
-
Hi Mark,
Thanks to uTasker and your help, I was able to get uTasker fully functional on my AT91SAM7X-EK board.
On another note, I was wondering how difficult would it be to port just the OS portion to other processors that do not need a TCP/IP stack (especially those that don't have EMACs)? I'm thinking of the AT91SAM7S and MSP430 processors. These processors have USARTs which I would use to communicate with.
Thanks,
Johnas
-
Hi Johnas
If you remove the #define ETH_INTERFACE in config.h it will remove everything to do with the Ethernet connection (including IP and all other related protocols). This may allow it to already work on other SAM7 types (although I haven't actually tried this).
In the case of the LPC project it does work from the smallest LPC2101 up to the largest LPC2378. Also the Luminary project allows the smallest LM3S1968 up to LM3S8962 to operate by setting one project define..
The peripherals in a processor family tend to be compatible.
There is no port to the MSP430 family available. A basic port tends to require a week or so fo work but then each peripheral may take several days to add - so a new family does represent quite a lot of work. A derivative in a family is however generally not a big deal, as mentioned above.
Regards
Mark
-
Hi Mark,
I've successfully ported uTasker to the AT91SAM7S. At least something that works (it's not pretty). I seem to be limited on the number of software timers I can allocate for my tasks. Presently, I can support 6 tasks. When I add the 7th task, I get an exception and it sits in a forever loop. I'm quite sure it has to do with the memory allocation. I had to downsize the heap allocation and redefine the memory boundaries. I'm using an AT91SAM7S64 which only has 64K flash and 16K RAM. I also seem to have a problem using the serial port. I am going to revisit this to see what is wrong. I suspect it is also due to the memory limits.
I've removed the TCP/IP stack and I am trying to minimize the code so that it only utilizes the resources on the SAM7S (no ethernet, no CAN, no PIOB, etc.). If you have any insight as to how to fix the timer limit and serial port problem, it would be greatly appreciated.
Thanks,
Johnas
-
Hi Mark,
Forget what I said about the serial port. It's been working all along. I had my COM port connected to another cable (oops).
Thanks,
Johnas
-
Hi Johnas
I am not sure where this limit if coming from at the moment. The NE64 project runs TCP/IP, Telnet and serial from 8k RAM (including Ethernet buffers) - although Ethernet frames sizes may have to be restricted to 256 bytes. Also the project runs on an LPC2101 with 2k of RAM, where most of this is reserved for UART buffers.
Therefore the 16k SRAM in the AT91SAM7S is still quite a luxury in comparison.
You may like to do the following:
- set break points in the routines uMalloc() and uMallocAlign()
- start the SW and note the sizes of memory that are being allocated on each call (and the calling routine).
In fact it is easier to do this in the simulator, where the results should be very similar.
You may find an unexpectedly large block being requested and then you will understand why it is so close to the limit. If the allocation fails it will usually cause the system to fail since it just doesn't have enough memory to run. If this is the case it is important to understand what the memory is being used for and allocate it meaningfully.
Good luck
Regards
Mark
-
Hi Mark,
I've tried changing the heap size allocation down to 4K and I still seem to have a problem. I've traced the problem to the uMemcpy function. This function is called from the fnGetOurParameters function in the application task (fnApplication). There are two calls to uMemcpy in that function. The first call is successful. The second one hangs the system on the return. I've traced it into uMemcpy on the second call and I can see that the memory copy of the parameters into &temp_pars->temp_parameters is successful. However, when uMemcpy attempts to return to the calling function, fnGetOurParameters, it goes elsewhere. This elsewhere is at the end of the startup_gnu.s file in the default exception vectors routine where it loops forever. So, what I can see is that the application task is called, but then an exception occurs and it sits in a forever loop.
I then tried your suggestion and placed a break point in the uMalloc function. I noticed that the present_HeapSize variable cycles through the following values: 144, 220, 348, 368, 437, 460, 497, 520, 557, 580, 617, 640, 677, 700, 737, 800, and 884. After the present_HeapSize variable reaches 884 there is a pause and it recycles again starting at 144. I've defined the OUR_HEAP_SIZE constant to 4692 bytes. The system doesn't hang in the exception loop, but not it seems to cycle through the uMalloc routine forever.
I also tried placing a breakpoint in the uMallocAlign function. The debugger never stops there.
I will try to note the sizes of memory that is being allocated on each call and the calling routine tomorrow.
Any ideas on what is going on?
Johnas
-
Hi Johnas
It is possible that you are seeing a 'crash' at the uMemcpy(). This will possibly be due to the fact that it is being passed a null-pointer (is temp_pars valid when it is called?). This may cause a problem if it overwrites stack (return details trashed) rather that heap space and the watchdog will restart the board after a short delay.
It doesn't look as though that much memory is being used - 884 was the highest value you saw, but did this last entry return with no memory and cause the following problem? (check the return 0; in the routine).
Since the heap size starts at 144 again it is fairly certain that you are seeing a reset and a new start, which repeats and repeats.
If you disable the watchdog you may find that the CPU is really hanging in the exception loop.
uMallocAlign() is obviously not being used (I just mentioned it to be sure since some HW drivers need specially aligned memory and use this to get 8, or 16 byte aligned memory, for instance). Depending on the processor type, uMalloc() will tend to return 4 byte aligned memory per default.
Regards
Mark
-
Hi Mark,
I found the problem, but I seem to have to use an unusual method to fix it. The problem is that my stack and heap occupy the same memory space. I know you have the heap dynamically allocated so its size is set to zero for the build. However, when the program runs, the ucBottomOfHeap variable is set to the user/system stack start. The only way I could think of clearing this was to set my stack size equal to the normal stack size (1 Kbyte) plus the heap size (4 Kbytes + 600 bytes) I wanted. I'm quite sure this is not the way to do it. I must have some setting that is incorrect in my project. I'm using the Rowley Crossworks software. I've attached the map file. You can see that both the heap and stack start at address 0x00200204. What was happening was that as tasks were added the heap grew up and ran into the stack which grew downwards. When a new task was added and it overwrote the active stack area, the program hung.
Thanks for your help,
Johnas
-
Hi Johnas
It is in fact normal that heap and stack start at the same address, since the heap size of the project is zero (if the project requires library heap - using malloc() and free() etc. the size of heap can be adjusted).
Looking at the map file, also the position of this is fine.
Since the last variable in the system is at 0x00200203, the stack begins at 0x00200204 and, since the SAM7 has 16k of RAM, it leaves some 15k for the uTasker heap and the rest for the CPU stack. With 4.6k declared for the heap there is thus plenty of working space for the CPU.
But the problem is that the stack pointer is set to the end of the declared stack space. The stack pointer can be set to the top of RAM and then it will give the maximum possible space without you having to set it up (which depends on the SRAM size and the variables in the system and so not easy to set up perfectly).
What has happened is that you are using a different LD file. The standard GNU LD files need the stack space defined and the stack pointer is put to the top of this. But, as you have seen, you need to make this section large enough and, to set it to fully utilise the available space, needs you to manually check the variables and calculate the size so that it equals the top of RAM. If you add variables to the system you may then have to change the linker file again to compensate. All-in-all quite messy.
If you look at the original LD file in the uTasker project (uTaskerV1.3_FLASH.ld) you will find the following entry:
__stack_und_end__ = __SRAM_segment_end__; /* stack limits for use by the start up assembler code */
__stack_abt_end__ = __stack_und_end__ - __STACKSIZE_UND__;
__stack_irq_end__ = __stack_abt_end__ - __STACKSIZE_ABT__;
__stack_fiq_end__ = __stack_irq_end__ - __STACKSIZE_IRQ__;
__stack_svc_end__ = __stack_fiq_end__ - __STACKSIZE_FIQ__;
__stack_end__ = __stack_svc_end__ - __STACKSIZE_SVC__;
This uses the top of RAM as a reference. Then subtracts the various interrupt stack sizes (only a couple of hundred bytes or so) and then uses a fixed value of __stack_end__ which is then set in the start up file as stack pointer value. This means that the size of stack is not used, ensuring the optimum set up in an automated fashion.
All you need to do is to modify the size of the SRAM in the original LD file to suit the SAM7 size and that should be enough...
...however, one has to be quite careful with Rowley since it tends to add its own LD file from the automated setup and this is not always noticed. You need to add the (modified) uTasker LD file to the project and ensure that it is really being used. I think that the method is:
- click on the LD file in Rowley Crossworks (in the project explorer) and with right-click open the properties dialogue.
- select configuration = common.
- in the file options pull-down select "Linker script".
This should set it as LD file for the target (overriding any automated ones).
You will know when it is correct because __stack_und_end__, in the map file, will equal the top of the SRAM and __stack_end__ (the initial stack pointer value) will be just a little below it.
Good luck
Regards
Mark
-
Hi Mark,
You were right about the .ld script file. I had used Rowley's version thinking that you simply did the same. I went back to the uTasker flash script, modified a few things for the SAM7S and it worked perfectly. Now, the stack is located at the upper end of RAM 0x203E00 and the heap starts after the system variables at 0x2001CC. There should be no chance of overwriting the stack now. Thanks again for your help.
Johnas