Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - twoerner

Pages: [1] 2
1
NXPTM M522XX, KINETIS and i.MX RT / FLASH blocks
« on: July 20, 2007, 08:32:22 PM »
I have just one more piece of the puzzle to understand: writing data to the flash.

As I understand it, if I wanted to write just 1 byte to flash I first need to erase the entire block in-which that 1 byte is found. How large is the size of the block that must be erased? So to write 1 byte would require me to save and entire block to RAM, modify the 1 byte in RAM, erase the entire block on FLASH, then write the entire block from RAM to FLASH, right?

I've so far been looking at fnEraseFlashSector() and fnWriteBytesFlash(). These are great, but I'll need to know the block size in order to use them correctly. I'm guessing uTasker probably has some functions and/or defines that make this easier?

Looking at uTasker's fnEraseFlashSector() it would appear that 1 flash block is 0x1000 bytes (given that the address is ANDed with ~0x3. But looking through the code that comes with Freescale's dBUG program there is a define in cfm_flash.h that appears as though the block size is 0x800. I guess there's a fair amount of confusion because different texts refer to "block page size", "block sector size", "flash block size", "flash logical block size", ...and several more permutations on what may or may not be the same concept.

I've been playing around with fnEraseFlashSector() and fnWriteBytesFlash() and can see that I can modify bytes of FLASH, but without understanding everything that is going on I can't use them effectively.

2
µTasker general / MAC address
« on: July 20, 2007, 05:45:24 PM »
Hi Mark,

Just out of curiosity, looking at the uTasker demo project, the ethernet's MAC address is hard-coded into the application to an initial value of all zeros and can subsequently be changed by the user. Don't ethernet chipsets have a MAC address stored in them from the manufacturer? Do we have access to this value?

It would be nice if, by default, the MAC address of my board were already set to something expected to be unique (i.e. the value stored in the hardware). Otherwise I'm guessing I can't have two devices on the same network running the uTasker code at the same time (until someone comes along and changes at least one of them)!

Best regards,
    Trevor Woerner

3
NXPTM M522XX, KINETIS and i.MX RT / Re: moving uTasker
« on: July 19, 2007, 09:24:01 PM »
Wow! I got it working! I created a "Hello, world!"-type simple program using the M52235 stationary from Metrowerks and by seeing what they're doing I was able to move the entire application to start at 0x00030000 and set the reset boot vector to point there so when the board is RESET it executes all the code starting from that location.

I modified the LCF to look like:
Code: [Select]
MEMORY
{
    flash1  (RX)   : ORIGIN = 0x00000000, LENGTH = 0x00420
    flash2  (RX)   : ORIGIN = 0x00030000, LENGTH = 0x000FFFF
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram    (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

You'll notice that I removed the flash_config.s stuff and instead wrapped it all up in Startup.s. Taking a page from the project stationary my Startup.s now looks like:

Code: [Select]
.text

/*
 * Exception Vector Table
 */
VECTOR_TABLE:
_VECTOR_TABLE:
INITSP: .long ___SP_INIT /* Initial SP */
INITPC: .long start        /* Initial PC */
vector002: .long asm_exception_handler /* Access Error */
vector003: .long asm_exception_handler /* Address Error */
vector004: .long asm_exception_handler /* Illegal Instruction */
vector005: .long asm_exception_handler /* Reserved */
vector006: .long asm_exception_handler /* Reserved */
vector007: .long asm_exception_handler /* Reserved */
vector008: .long asm_exception_handler /* Privilege Violation */
vector009: .long asm_exception_handler /* Trace */
vector010: .long asm_exception_handler /* Unimplemented A-Line */
vector011: .long asm_exception_handler /* Unimplemented F-Line */
vector012: .long asm_exception_handler /* Debug Interrupt */
vector013: .long asm_exception_handler /* Reserved */
...
vector251: .long asm_exception_handler
vector252: .long asm_exception_handler
vector253: .long asm_exception_handler
vector254: .long asm_exception_handler
vector255: .long asm_exception_handler

CFM_FLASH_CONFIG:
_CFM_FLASH_CONFIG:
/*
 * CFM Flash Configuration Field
 */
KEY_UPPER:  .long   0x00000000
KEY_LOWER:  .long   0x00000000
CFMPROT:    .long   0x00000000
CFMSACC:    .long   0x00000000
CFMDACC:    .long   0x00000000
CFMSEC:     .long   0x00000000

To ensure that the above is not deadstripped I've modified M5223X.c -> mcf52235_init() to contain:
Code: [Select]
extern unsigned long VECTOR_TABLE[];
volatile unsigned long someValue;
...
someValue = VECTOR_TABLE[0];

The volatile is extremely important.

I then removed all references to flash_config, and added a simple asm_interrupt_handler() and it works.

The handler looks like the following and was added to Startup2.s:
Code: [Select]
asm_exception_handler:
    rte

The start of my S-record file looks like:
Code: [Select]
S0030000FC
S32100000000200080000003000000030090000300900003009000030090000300905C
S3210000001C00030090000300900003009000030090000300900003009000030090BD
S3210000003800030090000300900003009000030090000300900003009000030090A1
...
S321000003D40003009000030090000300900003009000030090000300900003009002
S321000003F0000300900003009000030090000300900000000000000000000000009F
S3190000040C0000000000000000000000000000000000000000D6
S3210003000046FC2700203C200000000680000000214E7B0C052E7C20008000203CCF

Notice how the FLASH config registers are set to 0 as needed.
Awesome! :-)

4
NXPTM M522XX, KINETIS and i.MX RT / Re: moving uTasker
« on: July 19, 2007, 07:25:58 PM »
I have an application based on the uTasker sample application and I'm trying to minimize the amount of code in FLASH below 0x00030000; ideally I'd like there to be no code below this address, except for:

1) the initial SP value at 0x00000000
2) the initial PC value at 0x00000004
3) the FLASH controller config at 0x00000400 - 0x00000418

I modified the LCF file so that the ORIGIN of FLASH2 is 0x00030000, and this works fine.

I then edited Startup.c to remove all the functions except for "start" (e.g. mcf5xxx_wr_vbr, asm_int_off, asm_int_on, ) and placed them in Startup2.c which, in the LCF, I placed into FLASH2. Looking through the xMAP file I can see that the code for these routines is in fact located above 0x00030000. Everything still works fine.

At this point:
1) initial SP (from Startup.c) is 0x20008000 in location 0x00000000
2) initial PC (from Startup.c) is 0x00000008 in location 0x00000004
3) FLASH controller config is zeroed
4) I'm using about 80 bytes starting at 0x00000008 for the code of the "start" routine

Code: [Select]
S0030000FC
S32100000000200080000000000846FC2700203C200000000680000000214E7B0C05D0
S3210000001C2E7C20008000203C4000000006800000000123C040000000203C0000D6
S31D0000003800000680000000614E7B0C044EB9000317144EB9000300505B
S31D00000400000000000000000000000000000000000000000000000000DE
S32100030000

Then I tried to move more code from below 0x00300000. I edited "start" in Startup.c to just include a "jsr start2" and moved the actual code of the "start" routine to Startup2.c in a routine called "start2". After compiling I end up with an S-record that looks like:

Code: [Select]
S0030000FC
S3150000000020008000000000084EB900030000000038
S31D00000400000000000000000000000000000000000000000000000000DE
S32100030000

But this does not work. Any ideas why? The initial SP and PC are still set correctly. The "jsr start2" is the first instruction executed after a reset, and the FLASH config registers are still setup properly. Any idea why this code (with the "start" routine essentially at 0x00030000) is wrong but the previous (with the "start" routine at 0x00000008) is fine?

I guess another way to ask the question is: of the 5 things done in "start" why must they be done in low FLASH memory? Can't they be done somewhere else?

The 5 things I'm referring to are:
1) set SR to 0x2700
2) init RAMBAR1 to __SRAM + 0x21
3) init SP to __SP_INIT
4) init IPSBAR to __IPSBAR + 0x1
5) init RAMBAR0 to __FLASH + 0x61

5
µTasker general / Re: updating parameters via the HTTP
« on: July 19, 2007, 02:37:36 PM »
Our codes are in fact equivalent.

Well unless there's some side non-expected consequence of uStrcpy() then
Code: [Select]
uStrcpy(&cValue[(sizeof(cValidate) - 1)], cValidate); is not equivalent to
Code: [Select]
uStrcpy (cValue, "Validate");since the first example copies the string not at location zero but at a location the size of the string into the array.

Also for some reason you calculate the size as double the actual.

As you see, there should be no restrictions. However I still stick to the method with validation and timeouts since it ensures that no device is left stranded with invalid or unknown settings.

I think your idea of having a verify step is awesome, that's definitely one to put in the ol' toolbox of tips and tricks. I just did not think that the process required a 3-step procedure for the user, I believe the same results can be achieved using a 2-step procedure and was wondering if I had misunderstood your intentions.

Don't forget that you can use DHCP and there are various other network tricks allowing IP to be set
using ARP sequences and.... but that is another story!!

DHCP is a phase 2 item for my project :-)
I assume you're talking about gratuitous ARPs? Yes, very clever.

Thanks again!

6
NXPTM M522XX, KINETIS and i.MX RT / Re: moving uTasker
« on: July 18, 2007, 11:13:34 PM »
So if I have a target and in its LCF I've defined:

Code: [Select]
MEMORY
{
    flash   (RX)   : ORIGIN = 0x0000800, LENGTH = 0x0003F800   
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

I can look at the generated S-record file and see that the last line is:

Code: [Select]
S70500000808EA

Does that not mean that when the flash tool is done putting the application in FLASH, that it doesn't put the address 0x0000808 (which, according to the generated xMAP file, is the address of the "start" label and therefore the address of the first instruction of the application) into the reset vector FLASH address 0x00000004?

7
µTasker general / Re: updating parameters via the HTTP
« on: July 18, 2007, 10:38:30 PM »
Your suggestions are awesome... and so quick! I guess what I needed most was to look at fnInsertString and that I needed the £v operation.

Just a couple quick notes...
1) Operation 'M' is already taken (for MAC display) so I used 't' which appears to be unused so far.
2) I'm not sure your code example as given would work, it looked more complicated than it needs to be. But the following works fine for me:

Code: [Select]
        // save/verify button when updating network params
        case 't':
                    if (fnAreWeValidating()) {
                            uStrcpy (cValue, "Validate");
                            *usLengthToSend = 8;
                    }
                    else {
                            uStrcpy (cValue, "Save");
                            *usLengthToSend = 4;
                    }
                    break;

with an HTML page of:

Code: [Select]
<input type=submit value=£vt1 name=em>

Now here is where I'm getting confused. I have been modifying a fair amount of the uTasker code so there's always the possibility that I've modified a couple things too many and have somehow lost the functionality you've programmed. But with the code that I have:

1) I load the page from address 192.168.0.3, it shows 192.168.0.3 as its IP address and the "Save" button label is active
2) modify the IP address to 192.168.0.4, click "Save"
3) because we're sending the "em" command no reset occurs
4) the button label never moves into "verify" mode
5) I can open a new browser window, but at address 192.168.0.3, and I see the IP address value of 192.168.0.4
6) if I reboot the board it shows up at 192.168.0.3, and the IP value is 192.168.0.3

So no change has taken place and I can't verify the change.

So I modified the code to look like:
Code: [Select]
        // save/verify button when updating network params
        case 't':
            switch (*ptrBuffer) {
                    case '1':
                            if (fnAreWeValidating()) {
                                    uStrcpy (cValue, "Validate");
                                    *usLengthToSend = 8;
                            }
                            else {
                                    uStrcpy (cValue, "Save");
                                    *usLengthToSend = 4;
                            }
                            break;

                    case '2':
                            if (fnAreWeValidating()) {
                                    uStrcpy (cValue, "em");
                                    *usLengthToSend = 2;
                            }
                            else {
                                    uStrcpy (cValue, "es");
                                    *usLengthToSend = 2;
                            }
                            break;

                    default:
                            uStrcpy (cValue, "??");
                            *usLengthToSend = 2;
                            break;
            }
            break;

and use a web page of:

Code: [Select]
<input type=submit value=£vt1 name=£vt2>

So that the web page switches between "es" and "em". Using this code:

1) I load the page at 192.168.0.3, it shows 192.168.0.3 and a "Save" button
2) I change the IP address to 192.168.0.4 and click "Save", the "es" command is sent
3) the board resets
4) after reset I log into the board at address 192.168.0.4, the button label shows "Validate" and the board's IP address is reported at 192.168.0.4
5) I click "Validate", the "em" command is sent
6) the IP address field is editable again

Now, here's where my confusion is at this point, if I press RESET or power-cycle the board, after it comes up it is still at 192.168.0.4 (i.e. the new IP address) however, the IP field is not editable and the button label shows "Validate". I can keep clicking on "Validate" and power-cycling all I want, every time the board comes back up the values still need to be validated. I now need to issue one more "es" command. Only after I perform one more "es" command can I power-cycle and have the board be at IP address 192.168.0.4, show that IP address in the address field, have the IP address editable, and the button label read "Save".

In other words it seems like I have to perform an
1) "es"
2) "em"
3) "es"
command sequence to change the IP address and have it survive a power-cycle or reset.

Is there a way to short-circuit this sequence so that, say, after the second command (the validate or "em") I can power-cycle and have the IP address saved? I guess I could just edit the code to perform the "es" block after a "em" block. Is this how you intended the code to work?

8
NXPTM M522XX, KINETIS and i.MX RT / moving uTasker
« on: July 18, 2007, 09:18:51 PM »
As shipped, the uTasker demo application for M52235 assumes it can run from flash address zero. I would like to move the application so that it resides entirely above 0x36000 and touches nothing below this address (except, of course, for the reset vectors for the stack pointer and the program counter).

Looking at the supplied *.lcf files I found that M52235_BOOT_APP_FLASH.lcf looks somewhat like what I'm looking for. So I created a new target with a copy of this *.lcf file inwhich I change the flash "ORIGIN=" value. This doesn't seem to work. So then I tried to build and run the bare_min_app_rom target (which is the target that uses the M52235_BOOT_APP_FLASH.lcf script) and it doesn't seem to work for me either.

Any idea what I'm doing wrong?

9
µTasker general / updating parameters via the HTTP
« on: July 18, 2007, 06:59:52 PM »
Hi Mark,

I have a minimal HTML page to allow a user to change the device's IP/netmask. My understanding (and this seems to work) is that after changing the, say, IP address in the <input> box the user then needs to

a) click on some button which will cause an "I" variable to have the value of the new IP address (e.g. Ii=192.168.0.4) and an "es" command which causes the values to be saved temporarily and cause a reset to occur
b) once back up the user has 3 minutes to issue an "em" command to validate the settings
c) then click again to issue an "es" command

I would like to be able to do 2 things:
1) have just one button which is smart enough to either say "save" or "verify" based on which state it is in
2) only have to do steps 'a' and 'b' above, in other words I think it would be nice if it were only a 2-step process to change the device's IP address

Does this sound possible? I can post snippets of code if you need a better idea of how I've been modifying things.

10
µTasker general / Re: errors when POSTing
« on: July 16, 2007, 10:42:17 PM »
Truly awesome Mark. Thanks for your explanation.

I decided to not use your modified tcp.c and work with the data the "correct" way in which it is being presented. To this end I created a "status" variable inside the POSTING_DATA_TO_APP case. If that variable is still true when the next block of data comes in (from the POST) then process this new data, otherwise discard it. While processing the current block, if anything goes wrong set the status to false so that no further processing will occur with any subsequent data from this same POST.

Back inside http.c's HTTP_STATE_POSTING_DATA, when we've come to the end of the POST (i.e.
Code: [Select]
if (HTTP_session->FileLength == 0)) I do one more fnHandleWeb() with a new case I created: POST_STATUS. The point of making this call is to retrieve the status from all the previous POSTING_DATA_TO_APP calls. Based on that information I call fnHandleWeb with either INFORM_POST_SUCCESS or INFORM_POST_FAILED.

It's starting to come together quite nicely. A couple more hurdles (which I'll probably end up having to bug you about yet again) and the project will be done :-)

11
µTasker general / errors when POSTing
« on: July 13, 2007, 06:35:53 PM »
I have modified parts of http.c -> fnPostFrame() -> HTTP_STATE_POSTING_DATA to look like the following:

Code: [Select]
if (HTTP_session->ucState != HTTP_STATE_DUMPING_DATA) {
    MAX_FILE_LENGTH FileLength = HTTP_session->FileLength;
    HTTP_session->FileLength = usPortLen;
    status = fnHandleWeb(POSTING_DATA_TO_APP, (CHAR *)ucIp_Data, HTTP_session);
    if (status) {
            fnHandleWeb (INFORM_POST_FAILED, 0, HTTP_session);
            return (fnDoWebPage (0, HTTP_session));
    }
    HTTP_session->FileLength = FileLength;

    if ((usPortLen) && (HTTP_session->ptrFileStart == HTTP_session->ptrFile)) {
        HTTP_session->ptrFileStart += FILE_HEADER;
    }
}

My hope was that if I detected an error while receiving the POST'ed file (e.g. checksum error) I could pass that information up (from webInterface.c -> fnHandleWeb() -> POSTING_DATA_TO_APP) and report the error back to the user as soon as possible. If everything was okay then I'd just pass zero back to report success.

This works... however it takes a long time. If there's an error the web browser spins and spins and spins and spins and it takes a long time to display the error page. Any ideas what's going on and how I could get that error page to appear quicker?

BTW: what's the last if() doing in the above code (i.e. the one with the usPortLen)?

12
µTasker general / Re: turning off FS
« on: July 10, 2007, 10:06:21 PM »
Hi Mark, awesome replies.

1. When posting, also make sure that you know what type of data is to be posted. Images, Text, binary etc. The single or multiple file types should each be defined (SUPPORT_POST_BINARY and/or SUPPORT_POST_TEXT and/or SUPPORT_POST_GIF). Unrecognised file types will be received without any errors but the contents will be dumped.
This is not a problem that you have since you already get further than this.

While trying to understand how the sample application works, I stumbled across this part of the code. I also discovered that the code is a bit too restrictive. For kicks I was fumbling around trying to upload an HTML file as part of the POST and it just wasn't working, when I dug around I noticed that your text MIME handling only accepts "text/plain" files and not, for example "text/html". So I edited the code to look like the following:

Code: [Select]
#ifdef SUPPORT_POST_TEXT
                    if (!(uMemcmp("text/", ucIp_Data, 5))) {
                        unsigned char *ptr;
                        unsigned myTmp, diff;
                       
                        ptr = ucIp_Data;

                        // find first '\n'
                        for (myTmp=0; myTmp<32; ++myTmp) {
                            ++ptr;
                            if (*ptr == '\n')
                                break;
                        }
                        if (myTmp == 32)
                            break;

                        // find second '\n'
                        for (myTmp=0; myTmp<32; ++myTmp) {
                            ++ptr;
                            if (*ptr == '\n')
                                break;
                        }
                        if (myTmp == 32)
                            break;

                        diff = (unsigned)ptr - (unsigned)ucIp_Data;
                        ucIp_Data += diff;
                        usPortLen -= diff;
                        HTTP_session->FileLength -= (diff + 2);
                        HTTP_session->FileLength -= HTTP_session->ucBoundaryLength;
                        HTTP_session->ucState = HTTP_STATE_POSTING_DATA;
                        break;
                    }
#endif

Let me be the first, of course, to admit that's not the most elegant code. But it was just a quickie doodle for education purposes. Now the "text" MIME handling will accept any "text/..." type.


Code: [Select]
HTTP_session->ptrFile = 0;  // we decide not to save this to a file but handle it ourselves

Your suggestion to add that one line to "webinterface.c -> fnHandleWeb() -> case CAN_POST_BEGIN" works perfectly! What I've slowly come to realize is when I've modified the code and want to test it, it seems that I need to use the flash tool to erase then program the board, THEN I can press debug in the IDE. If I don't re-flash the device before pressing "debug" there seems to be some sort of mixup between what I wrote and what's running. In other words, it turns out my first set of modifications work fine, but due to some flash mixup it didn't appear to be working. But I like your solution better.

For kicks I can upload html or plain text files using POST then view them by asking for the "H" file ("H" by itself gives a  binary, "H.htm" returns it in a way the browser can display). I assume something in the sample uTasker program is changing the sent MIME type based on the requested filename?

Is it correct to further assume that it is the browser that sets the MIME type for POST uploads?

13
µTasker general / Re: turning off FS
« on: July 10, 2007, 06:36:34 PM »
Hi Mark, thanks for your reply.

I've re-enabled the filesystem and am trying to get the SUPPORT_HTTP_POST_TO_APPLICATION / POSTING_DATA_TO_APP mechanism working. Unfortunately, every time the application comes to http.c -> fnPostFrame() -> case HTTP_STATE_POSTING_DATA, HTTP_session->ptrFile is always non-zero so the fnHandleWeb (POSTING_DATA_TO_APP...) function is never called and uFileWrite() is always called instead. As a very simple work-around I've just removed the if-statement which checks if HTTP_session->ptrFile is zero or not. But I'm guessing you probably had something in mind when you added that code, any idea what I'm doing wrong?

14
µTasker general / tftp tests
« on: July 09, 2007, 11:21:39 PM »
app: uTasker sample app V1.3.0 with SP1-4

I don't mean to nit-pick, but in order to play around with the TFTP demo/test software, it was necessary to add the file 'stack\tftp.c' to the project, otherwise the link would fail.

15
NXPTM M522XX, KINETIS and i.MX RT / USE_IP_STATS
« on: July 09, 2007, 11:08:35 PM »
platform: M5223x
app: uTasker sample app V1.3 with SP1-4

I just wanted to point out that simply commenting out '#define USE_IP_STATS' causes the compile to fail. There are 4 places in Hardware\M5223X.c that call fnIncrementEthernetStats(), only one of which is protected by the required '#ifdef USE_IP_STATS'.

Pages: [1] 2