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 - mark

Pages: [1] 2 3 ... 219
1
NXPTM M522XX, KINETIS and i.MX RT / Re: DIO internal PullDown
« on: May 28, 2026, 09:33:50 PM »
Hi Neil

I wonder what happens f you connect a 1MOhm resistor to GND from the pin?
If it then goes to '0' it would presumably mean that there is a very low leakage path to 3V but not enough to supply any real current.

Regards

Mark


2
NXPTM M522XX, KINETIS and i.MX RT / Re: DIO internal PullDown
« on: May 28, 2026, 06:04:05 PM »
Hi Neil

Unfortunately AN doesn't have any internal pull-up or pull-down capabilities - see attached image.

Regards

Mark



3
µTasker general / Re: uTasker Utilities
« on: April 25, 2026, 11:42:28 AM »
The utilities run in a Windows environment and require some Microsoft DLLs that are generally present.
In some situations (a new PC which has not had general programs installed yet) the DLLs may be missing.
A typical error message is
"The code excecution cannot proceed because VCRUNTIME140.dll was not found. Reinstalling the program may fix this problem"

If unsure whether this issue is present or not please use the command "uTaskerConvert.exe -v" in a DOS shell to clearly see the result.

In case of this issue existing, the DLL can be installed from
https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170

Note that many programs that are installed will supply the DLL, since they also need it in order to be able to operate, and so it is rare that this is required.

4
Hi

Example: When peripherals are enabled (gated) and then used it is possible that between gating and it being ready there is a delay (in the synchronisation of clock domains) that means that the code using the peripheral will use it slightly too early.
What happens is that there is a hard fault. If the hard fault lands in a forever loop it fails. If the hard fault simply returns it then repeats (and works) and all is fine and it continues.
That is, there can be 'temporary' hard faults that are not really critical.
Often they can be avoided by using instruction / data barrier commands like

asm volatile ("dsb 0xf":::"memory");
asm volatile ("isb 0xf":::"memory");


which cause the processor to wait until the previous peripheral write operations have completed but this can be fiddly.

What I do is use a very simple hard fault handler that counts how often it happens, doesn't result in a loop and recovers (if it is a 'real'/serious hard fault it results in a hard fault interrupt loop anyway, which is very easy to debug as you just need to connect with a debugger and you see the exact code that is faulting (over and over again)).


volatile unsigned long ulHardFaultCounter = 0;
// Serious error interrupts
//
static void irq_hard_fault(void)
{
    ulHardFaultCounter++;                                                // hard faults are often recoverable so we count how many were detected for statistical reasons
}


I can always check the counter value to see whether it does every occasionally happen. If I prefer to 'clean' it up so that it doesn't I just set a break point on the increment line, let it run and see exactly where it takes place and then, if I want, I can add a barrier instruction (or similar - eg. adding some other code before accessing usually works) to exclude it. Recoverable hard faults are however not really worth worrying about as they have no negative side effects (that I ever experienced).

Regards

Mark

5
Hi

Make sure that you have switched the repo. to V2.0.0 so that you are using newest source (master source will have linker script files that stopped working with newest GCC versions).

When using MCUXpresso the managed build is not used (where the internal settings are configured) but instead the linker script is entered (see the MCUXpresso guide document or video).

I wouldn't bother changing 8M Flash to 4Meg since it won't change anything. It would just give you an error in case >4 Meg was actually used.

Regards

Mark

P.S: Below is the content of \Applications\uTaskerV1.4\GNU_iMX\iMX_RT_10XX_FlexSPI_NOR.ld as reference


======================================================================

/* iMX_RT_10XX_FlexSPI_NOR.ld - compatible with MCUXpresso > V11.4        */
/* GCC memory file for the iMX RT 10XX - for use with the uTasker project */
/* Use when running from FlexSPI Flash (total up to 512k CPU SRAM)        */


_HeapSize = 0x0;                                    /* uTasker project usually does not use library heap */
_StackSize = 0x0;                                   /* uTasker project organises stack at run time       */

MEMORY
{
  /* Define each memory region */
  BOARD_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x800000 /* 8M bytes (alias Flash) */ 
  SRAM_DTC (rwx) : ORIGIN = 0x20000300, LENGTH = 0x80000-0x0300 /* up to 512K bytes (alias RAM) - with vectors at the start */ 
  SRAM_ITC (rwx) : ORIGIN = 0x0, LENGTH = 0x80000 /* up to 512K bytes (alias RAM2) */ 
  SRAM_OC (rwx) : ORIGIN = 0x20200000, LENGTH = 0xc0000 /* 768K bytes (alias RAM3) */ 
  BOARD_SDRAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x1e00000 /* 30M bytes (alias RAM4) */ 
  NCACHE_REGION (rwx) : ORIGIN = 0x81e00000, LENGTH = 0x200000 /* 2M bytes (alias RAM5) */ 
}

  /* Define a symbol for the top of each memory region */
  __base_BOARD_FLASH = 0x60000000  ; /* BOARD_FLASH */ 
  __base_Flash = 0x60000000 ; /* Flash */ 
  __top_BOARD_FLASH = 0x60000000 + 0x800000 ; /* 8M bytes */ 
  __top_Flash = 0x60000000 + 0x800000 ; /* 8M bytes */ 
  __base_SRAM_DTC = 0x20000300  ; /* SRAM_DTC */ 
  __base_RAM = 0x20000000 ; /* RAM */ 
  __top_SRAM_DTC = 0x20000300 + 0x80000 - 0x0300 ; /* up to 512k bytes */ 
  __top_RAM = 0x20000000 + 0x80000 ; /* up to 512k bytes */ 
  __base_SRAM_ITC = 0x0  ; /* SRAM_ITC */ 
  __base_RAM2 = 0x0 ; /* RAM2 */ 
  __top_SRAM_ITC = 0x0 + 0x80000 ; /* up to 512K bytes */ 
  __top_RAM2 = 0x0 + 0x80000 ; /* up to 512K bytes */ 
  __base_SRAM_OC = 0x20200000  ; /* SRAM_OC */ 
  __base_RAM3 = 0x20200000 ; /* RAM3 */ 
  __top_SRAM_OC = 0x20200000 + 0xc0000 ; /* 768K bytes */ 
  __top_RAM3 = 0x20200000 + 0xc0000 ; /* 768K bytes */ 
  __base_BOARD_SDRAM = 0x80000000  ; /* BOARD_SDRAM */ 
  __base_RAM4 = 0x80000000 ; /* RAM4 */ 
  __top_BOARD_SDRAM = 0x80000000 + 0x1e00000 ; /* 30M bytes */ 
  __top_RAM4 = 0x80000000 + 0x1e00000 ; /* 30M bytes */ 
  __base_NCACHE_REGION = 0x81e00000  ; /* NCACHE_REGION */ 
  __base_RAM5 = 0x81e00000 ; /* RAM5 */ 
  __top_NCACHE_REGION = 0x81e00000 + 0x200000 ; /* 2M bytes */ 
  __top_RAM5 = 0x81e00000 + 0x200000 ; /* 2M bytes */ 



ENTRY(__vector_table)

SECTIONS
{
     /* Image Vector Table and Boot Data for booting from external flash */
    .boot_hdr : ALIGN(4)
    {
        FILL(0xff)
        __boot_hdr_start__ = ABSOLUTE(.) ;
        KEEP(*(.boot_hdr.conf))
        . = 0x1000 ;
        KEEP(*(.boot_hdr.ivt))
        . = 0x1020 ;
        KEEP(*(.boot_hdr.boot_data))
        . = 0x1030 ;
        KEEP(*(.boot_hdr.dcd_data))
        . = 0x1fb0 ;
        KEEP(*(.boot_hdr.key))
        . = 0x1fe0 ;
        KEEP(*(.boot_hdr.init))
        __boot_hdr_end__ = ABSOLUTE(.) ;
        . = 0x2000 ;
    } >BOARD_FLASH

    /* MAIN TEXT SECTION */
    .text : ALIGN(4)
    {
        FILL(0xff)
        __vectors_start__ = ABSOLUTE(.) ;
        KEEP(*(.vectors))
        /* Global Section Table */
        . = ALIGN(4) ;
        __section_table_start = .;
        __data_section_table = .;
        LONG(LOADADDR(.data));
        LONG(    ADDR(.data));
        LONG(  SIZEOF(.data));
        LONG(LOADADDR(.data_RAM2));
        LONG(    ADDR(.data_RAM2));
        LONG(  SIZEOF(.data_RAM2));
        LONG(LOADADDR(.data_RAM3));
        LONG(    ADDR(.data_RAM3));
        LONG(  SIZEOF(.data_RAM3));
        LONG(LOADADDR(.data_RAM4));
        LONG(    ADDR(.data_RAM4));
        LONG(  SIZEOF(.data_RAM4));
        LONG(LOADADDR(.data_RAM5));
        LONG(    ADDR(.data_RAM5));
        LONG(  SIZEOF(.data_RAM5));
        __data_section_table_end = .;
        __bss_section_table = .;
        LONG(    ADDR(.bss));
        LONG(  SIZEOF(.bss));
        LONG(    ADDR(.bss_RAM2));
        LONG(  SIZEOF(.bss_RAM2));
        LONG(    ADDR(.bss_RAM3));
        LONG(  SIZEOF(.bss_RAM3));
        LONG(    ADDR(.bss_RAM4));
        LONG(  SIZEOF(.bss_RAM4));
        LONG(    ADDR(.bss_RAM5));
        LONG(  SIZEOF(.bss_RAM5));
        __bss_section_table_end = .;
        __section_table_end = . ;
        /* End of Global Section Table */

        *(.after_vectors*)

       *(.text*)
       *(.rodata .rodata.* .constdata .constdata.*)
       . = ALIGN(4);
    } > BOARD_FLASH
    /*
     * for exception handling/unwind - some Newlib functions (in common
     * with C++ and STDC++) use this.
     */
    .ARM.extab : ALIGN(4)
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > BOARD_FLASH

    .ARM.exidx : ALIGN(4)
    {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > BOARD_FLASH
 
    _etext = .;
       
    /* DATA section for SRAM_ITC */

    .data_RAM2 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM2 = .) ;
        PROVIDE(__start_data_SRAM_ITC = .) ;
        *(.ramfunc.$RAM2)
        *(.ramfunc.$SRAM_ITC)
        *(.data.$RAM2)
        *(.data.$SRAM_ITC)
        *(.data.$RAM2.*)
        *(.data.$SRAM_ITC.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM2 = .) ;
        PROVIDE(__end_data_SRAM_ITC = .) ;
     } > SRAM_ITC AT>BOARD_FLASH

    /* DATA section for SRAM_OC */

    .data_RAM3 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM3 = .) ;
        PROVIDE(__start_data_SRAM_OC = .) ;
        *(.ramfunc.$RAM3)
        *(.ramfunc.$SRAM_OC)
        *(.data.$RAM3)
        *(.data.$SRAM_OC)
        *(.data.$RAM3.*)
        *(.data.$SRAM_OC.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM3 = .) ;
        PROVIDE(__end_data_SRAM_OC = .) ;
     } > SRAM_OC AT>BOARD_FLASH

    /* DATA section for BOARD_SDRAM */

    .data_RAM4 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM4 = .) ;
        PROVIDE(__start_data_BOARD_SDRAM = .) ;
        *(.ramfunc.$RAM4)
        *(.ramfunc.$BOARD_SDRAM)
        *(.data.$RAM4)
        *(.data.$BOARD_SDRAM)
        *(.data.$RAM4.*)
        *(.data.$BOARD_SDRAM.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM4 = .) ;
        PROVIDE(__end_data_BOARD_SDRAM = .) ;
     } > BOARD_SDRAM AT>BOARD_FLASH

    /* DATA section for NCACHE_REGION */

    .data_RAM5 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM5 = .) ;
        PROVIDE(__start_data_NCACHE_REGION = .) ;
        *(.ramfunc.$RAM5)
        *(.ramfunc.$NCACHE_REGION)
        *(.data.$RAM5)
        *(.data.$NCACHE_REGION)
        *(.data.$RAM5.*)
        *(.data.$NCACHE_REGION.*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM5 = .) ;
        PROVIDE(__end_data_NCACHE_REGION = .) ;
     } > NCACHE_REGION AT>BOARD_FLASH

    /* MAIN DATA SECTION */
    .uninit_RESERVED (NOLOAD) : ALIGN(4)
    {
        _start_uninit_RESERVED = .;
        KEEP(*(.bss.$RESERVED*))
       . = ALIGN(4) ;
        _end_uninit_RESERVED = .;
    } > SRAM_DTC AT> SRAM_DTC

    /* Main DATA section (SRAM_DTC) */
    .data : ALIGN(4)
    {
       FILL(0xff)
       _data = . ;
       PROVIDE(__start_data_RAM = .) ;
       PROVIDE(__start_data_SRAM_DTC = .) ;
       *(vtable)
       *(.ramfunc*)
       KEEP(*(CodeQuickAccess))
       KEEP(*(DataQuickAccess))
       *(RamFunction)
       *(NonCacheable.init)
       *(.data*)
       . = ALIGN(4) ;
       _edata = . ;
       PROVIDE(__end_data_RAM = .) ;
       PROVIDE(__end_data_SRAM_DTC = .) ;
    } > SRAM_DTC AT>BOARD_FLASH

    /* BSS section for SRAM_ITC */
    .bss_RAM2 : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM2 = .) ;
       PROVIDE(__start_bss_SRAM_ITC = .) ;
       *(.bss.$RAM2)
       *(.bss.$SRAM_ITC)
       *(.bss.$RAM2.*)
       *(.bss.$SRAM_ITC.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM2 = .) ;
       PROVIDE(__end_bss_SRAM_ITC = .) ;
    } > SRAM_ITC AT> SRAM_ITC

    /* BSS section for SRAM_OC */
    .bss_RAM3 : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM3 = .) ;
       PROVIDE(__start_bss_SRAM_OC = .) ;
       *(.bss.$RAM3)
       *(.bss.$SRAM_OC)
       *(.bss.$RAM3.*)
       *(.bss.$SRAM_OC.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM3 = .) ;
       PROVIDE(__end_bss_SRAM_OC = .) ;
    } > SRAM_OC AT> SRAM_OC

    /* BSS section for BOARD_SDRAM */
    .bss_RAM4 : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM4 = .) ;
       PROVIDE(__start_bss_BOARD_SDRAM = .) ;
       *(.bss.$RAM4)
       *(.bss.$BOARD_SDRAM)
       *(.bss.$RAM4.*)
       *(.bss.$BOARD_SDRAM.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM4 = .) ;
       PROVIDE(__end_bss_BOARD_SDRAM = .) ;
    } > BOARD_SDRAM AT> BOARD_SDRAM

    /* BSS section for NCACHE_REGION */
    .bss_RAM5 : ALIGN(4)
    {
       PROVIDE(__start_bss_RAM5 = .) ;
       PROVIDE(__start_bss_NCACHE_REGION = .) ;
       *(.bss.$RAM5)
       *(.bss.$NCACHE_REGION)
       *(.bss.$RAM5.*)
       *(.bss.$NCACHE_REGION.*)
       . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */
       PROVIDE(__end_bss_RAM5 = .) ;
       PROVIDE(__end_bss_NCACHE_REGION = .) ;
    } > NCACHE_REGION AT> NCACHE_REGION

    /* MAIN BSS SECTION */
    .bss : ALIGN(4)
    {
        _bss = .;
        PROVIDE(__start_bss_RAM = .) ;
        PROVIDE(__start_bss_SRAM_DTC = .) ;
       *(NonCacheable)
        *(.bss*)
        *(COMMON)
        . = ALIGN(4) ;
        _ebss = .;
        PROVIDE(__end_bss_RAM = .) ;
        PROVIDE(__end_bss_SRAM_DTC = .) ;
        PROVIDE(end = .);
    } > SRAM_DTC AT> SRAM_DTC

    /* NOINIT section for SRAM_ITC */
    .noinit_RAM2 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM2 = .) ;
       PROVIDE(__start_noinit_SRAM_ITC = .) ;
       *(.noinit.$RAM2)
       *(.noinit.$SRAM_ITC)
       *(.noinit.$RAM2.*)
       *(.noinit.$SRAM_ITC.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM2 = .) ;
       PROVIDE(__end_noinit_SRAM_ITC = .) ;
    } > SRAM_ITC AT> SRAM_ITC

    /* NOINIT section for SRAM_OC */
    .noinit_RAM3 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM3 = .) ;
       PROVIDE(__start_noinit_SRAM_OC = .) ;
       *(.noinit.$RAM3)
       *(.noinit.$SRAM_OC)
       *(.noinit.$RAM3.*)
       *(.noinit.$SRAM_OC.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM3 = .) ;
       PROVIDE(__end_noinit_SRAM_OC = .) ;
    } > SRAM_OC AT> SRAM_OC

    /* NOINIT section for BOARD_SDRAM */
    .noinit_RAM4 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM4 = .) ;
       PROVIDE(__start_noinit_BOARD_SDRAM = .) ;
       *(.noinit.$RAM4)
       *(.noinit.$BOARD_SDRAM)
       *(.noinit.$RAM4.*)
       *(.noinit.$BOARD_SDRAM.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM4 = .) ;
       PROVIDE(__end_noinit_BOARD_SDRAM = .) ;
    } > BOARD_SDRAM AT> BOARD_SDRAM

    /* NOINIT section for NCACHE_REGION */
    .noinit_RAM5 (NOLOAD) : ALIGN(4)
    {
       PROVIDE(__start_noinit_RAM5 = .) ;
       PROVIDE(__start_noinit_NCACHE_REGION = .) ;
       *(.noinit.$RAM5)
       *(.noinit.$NCACHE_REGION)
       *(.noinit.$RAM5.*)
       *(.noinit.$NCACHE_REGION.*)
       . = ALIGN(4) ;
       PROVIDE(__end_noinit_RAM5 = .) ;
       PROVIDE(__end_noinit_NCACHE_REGION = .) ;
    } > NCACHE_REGION AT> NCACHE_REGION

    /* DEFAULT NOINIT SECTION */
    .noinit (NOLOAD): ALIGN(4)
    {
        _noinit = .;
        PROVIDE(__start_noinit_RAM = .) ;
        PROVIDE(__start_noinit_SRAM_DTC = .) ;
        *(.noinit*)
         . = ALIGN(4) ;
        _end_noinit = .;
       PROVIDE(__end_noinit_RAM = .) ;
       PROVIDE(__end_noinit_SRAM_DTC = .) ;       
    } > SRAM_DTC AT> SRAM_DTC

    /* Reserve and place Heap within memory map */
    .heap (NOLOAD) :  ALIGN(4)
    {
        _pvHeapStart = .;
        . += _HeapSize;
        . = ALIGN(4);
        _pvHeapLimit = .;
    } > SRAM_DTC

     /* Reserve space in memory for Stack */
    .heap2stackfill (NOLOAD) :
    {
        . += _StackSize;
    } > SRAM_DTC
    /* Locate actual Stack in memory map */
    .stack ORIGIN(SRAM_DTC) + LENGTH(SRAM_DTC) - _StackSize - 0 (NOLOAD) :  ALIGN(4)
    {
        _vStackBase = .;
        . = ALIGN(4);
        _vStackTop = . + _StackSize;
    } > SRAM_DTC

    /* Provide basic symbols giving location and size of main text
     * block, including initial values of RW data sections. Note that
     * these will need extending to give a complete picture with
     * complex images (e.g multiple Flash banks).
     */
    _image_start = LOADADDR(.text);
    _image_end = LOADADDR(.data) + SIZEOF(.data);
    _image_size = _image_end - _image_start;

    /* For compatibility with uTasker names */
    /*                                      */
    __data_start__ = _start_uninit_RESERVED;
    __data_end__ = __data_start__ + SIZEOF(.data);
    __data_load_start__ = LOADADDR (.data);
    __bss_start__ = __start_bss_RAM;
    __bss_end__ = __start_bss_RAM + SIZEOF(.bss);
    __heap_end__ = _pvHeapLimit;
}

6
Bill

Please use https://www.utasker.com/docs/iMX/GCC.pdf as guide to preparing the header and setting the necessary link address for any project.
If you don't find the details there try also https://www.utasker.com/docs/iMX/MCUXpresso.pdf as it may be a bit more 'foreign' application oriented.

Finally use the check-list in the appendix of https://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf in case of problems.

Regards

Mark

7
µTasker general / TeraTerm -> changing serial COM ports
« on: February 09, 2026, 01:44:26 AM »
Hi All

I recently upgraded TeraTerm from V4.106, which I was using successfully for a few years, to V5.5.2 and had an issue that was not obvious to solve.

The first thing that I did was to save my COM port setup for use with a certain HW connection (Baud rate and COM port used) so that it always stated with it. That works fine.
But I found that I couldn't connect to any other COM ports and I also couldn't connect to virtual COM ports - TeraTerm remained disconnected.

Initially I assumed some problem with virtual COM ports (which I had also just set up and was trying to confirm with the new TeraTerm version) and so I experimented with installing and de-installing these but without any improvement.

It turns out that newer versions of TeraTerm require a different method when ports are changed:
- it is not possible to start TeraTerm with a pre-defined COM port setting (in its TERATERM.INI) and subsequently change it to another COM port using "Setup | Serial port..."
- to do this these steps are now needed:
- - "File | Disconnect"
- - "File | New connection..."
- - "Setup | Serial port..."
Now the new COM port connects. The original Baud rate and other settings are retained.

I found it out here: https://github.com/TeraTermProject/teraterm/issues/552
where there is also an explanation for the changes that were made.

Regards

Mark


8
µTasker general / Re: Tools that might be of interest to uTasker users
« on: February 09, 2026, 01:14:31 AM »
Hi All

Since I finally moved to Windows 11 and had some issues with COM0COM I'll write up what I found:

1. The present COM0COM version is V3.0.0. This works only is secure boot is disabled in the PC's BIOS; if secure boot is enabled Windows won't start it, which will be seen with a warning in the device manager. If you are happy with disabling secure boot this version is fine (in fact the same as on Win10 as I used thsi version for a few years also with the secure boot disabled).
To disable secure boot in the PC's boot follows: https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/disabling-secure-boot?view=windows-11

2. An older version of COM0COM - V2.2.0 works without disabling secure boot. The following link to that version is here (if it stops working do an Internet search - it should be on sourceforge.net)
https://sourceforge.net/projects/com0com/files/com0com/2.2.2.0/com0com-2.2.2.0-x64-fre-signed.zip/download

Since I don't know of any advantages of 3.0.0 I am going to try to use always 2.2.0 as it avoids the complication (especially for those who are not allowed to disable secure boot on their company PCs).

I found the following useful as I needed to install/uninstall a number of times to do the testing - there is no mention of secure boot issues, but the messages is quite clear "2.2.0 GOOD, 3.0.0 BAD":

https://www.youtube.com/watch?v=5RIcez2Vpdk

Regards

Mark

9
NXPTM M522XX, KINETIS and i.MX RT / Re: Post method
« on: January 23, 2026, 12:29:37 AM »
Hi

Here are few additional tips about handling POST to a web server.

1. Use WireShark to view the POST that is being received to be sure that the type is known. For example if text based content is being received the POST header will contain the content type "text/plain".

2. Ensure that the type is supported by the HTTP server - for example
#define SUPPORT_POST_TEXT
will ensure that it recognises the type and not ignore it.

3. When a recognised/supported POST content type is received the application callback will be called with the event type CAN_POST_BEGIN and the application level can decide whether it wants to accept (return 0) it or ignore it (return 1). Ignored posts will be silently discarded but the transfer is allowed to take place (to nowhere).

4. POST content is either saved to file or passed to the application (on a TCP frame basis).
Posts that are saved to file report success at the end with the callback event INFORM_POST_SUCCESS or INFORM_POST_FAILED.
Posts that are handled by the application layer pass each TCP frame's payload using the event POSTING_DATA_TO_APP and the application uses the content for whatever purpose it chooses - for example it can also save it to a file or interpret its content as it arrives. The final events INFORM_POST_SUCCESS or INFORM_POST_FAILED again signal the end of the complete post content.

5. Plain text post content is usually handled by POSTING_PARTIAL_PARAMETER_DATA_TO_APP and POSTING_PARAMETER_DATA_TO_APP event (POSTING_PARTIAL_PARAMETER_DATA_TO_APP indicates a fragment of a larger plain-text post and POSTING_PARAMETER_DATA_TO_APP indicates either a complete one in a single frame or the last in a larger post. This is typically used for passing parameters (like JSON strings) where the application will parse the content to extract the values (in the case of partial frames it may need to add buffering so that it can collect complete parameters before interpretation is possible).

See fnHandleWeb() in webInterface.c in the uTaskerV1.4 project for some reference handling of the events.

It is recommended to use the simulator to test such transfers, where a break point in fnHandleWeb() allows each event and accompanying data packet to be analysed.

Regards

Mark


10
Hi All

If you ever have a difficulty with COM0CO on Windows 11 this link may come in handy:
https://groups.io/g/win4icomsuite/message/4126

Regards

Mark

11
NXPTM M522XX, KINETIS and i.MX RT / Re: Rookie Question: µTasker "SDKs"
« on: November 20, 2024, 12:15:50 PM »
Hi

It is possible to enable such functionality in the serial loader or the uTasker application but if you load your won application instead of the uTasker application none of its operation is available as only your application is running.

Therefore you can either implement the application using the uTasker project (use the uTasker project as a framework for your own application code) or you need to develop all functionality needed in your own application (as the loaders do not run in parallel with it).

Regards

Mark

12
Hi

When the serial loader has completed its work the application is started and the serial loader is no longer running - therefore its normal that the upload disk is no longer available.

For the disk to re-appear the application would need to implement the same USB-MSD loader functionality, although this is not practically possible as the application would delete itself during the operation.

Typically the application, when it knows that the loader is needed again, will command a reset to the loader and then the serial loader allows the next update.

Alternatively the application allows new code to be saved to an intermediate area in flash and the BM-loader then updates it at the next reset. This would allow USB-MSD to be used (to load to intermediate memory) if the application can implement its own method.

Regards

Mark

13
NXPTM M522XX, KINETIS and i.MX RT / Re: Connecting over Vcom
« on: November 20, 2024, 12:02:52 PM »
Hi

I would try first without RNDIS in case that is causing a problem with its composite configuration.
Also compare the operation withe a reference from https://www.utasker.com/iMX/RT1060.html since these are known to operate correctly.

Regards

Mark

14
USB / Re: USB MSD data corruption MK20DX256VLH7
« on: October 06, 2024, 01:44:40 AM »
Hi

Sorry that I didn't see this post until now.

I don't know why this would happen but it is due to the file object, which is written after loading a new FW, being corrupted. Potentially it was written correctly but later overwritten, causing some values to be modified.

Attached is the latest version of usb_device_loader.c which was modified with this change quite some time ago:
16.01.2017 Check valid file and display for delete if random data    {33}

You will see that it uses
fnCheckFileObject() to verify that the file object is not corrupted and will, if it finds it to be bad, display a file called "UNKNOWN.BIN" with a size matching the application area (instead of trying to display the content according to teh fiel object itself).

This allows the user to do a delete of the file (cleans the application area) and then load the FW (again).

The problem with a corrupted file object can also be that multiple strange files of seemingly random lengths are found and it may otherwise not be possible to delete them to clear it up. This check and the "UNKNOWN-BIN" method ensures easy recovery.

This doesn't help with a source of corruption itself though.

Regards

Mark



15
Hi All

As you are probably aware, the uTasker project typically uses FlexRAM for optimal speed efficiency and divides the FlexRAM into ITC (Instruction Tightly Coupled) for code location and DTC (Data Tightly Coupled) for variables. The FlexRAM partitioning is performed automatically in this mode when the boot loader starts the serial loader or application (when running in RAM).

During intensive testing of SW and watchdog resets it was identified that returning the FlexRAM back to its default configuration was not always guaranteed since this has to be done during the reset command and is not performed automatically in HW during reset. This happened maybe once every 1000 resets or so and is almost certainly due to the fact that the chip's ROM loader - which starts the boot up sequence - fails when OCRAM (general purpose configuration) is disabled during the partitioning (tests where an OCRAM bank was left as it was by default didn't suffer from the issue) and couldn't be returned reliably during the reset operation.

A solution to this, which was tested positively in a long term test of continuous SW and/or watchdog resets, has been added that is recommended to ensure that a board can't remain in an undefined state after a commanded or watchdog reset, noting that it is generally recommended to use an external power-cycling circuit to also capture any potential hanging situation - see https://www.utasker.com/docs/iMX/uTasker_iMX_WDOG.pdf

1. In the bare-minimum (primary) boot loader a routine has been added that can reliably return the FlexRAM settings to their defaults and command reset (the bare-minimum loader operates directly from QSPI flash and can, thus, do this easily.

Code: [Select]
static void fnRestoreFlexRAM(int iReset)
{
    IOMUXC_GPR_GPR16 = IOMUXC_GPR_GPR16_DEFAULT;                         // set the FlexRAM layout back to that taken from the eFuse setting (default configuration)
    if (iReset != 0) {
        APPLICATION_INT_RESET_CTR_REG = (VECTKEY | SYSRESETREQ);         // request cortex core reset, which will cause the software reset bit to be set in the mode controller for recognition after restart
    }
}

2. The location of this routine is added to its Flash configuration, which means that it is - for i.MX RT 10xx parts - at a fixed address of 0x200 offset from the start of QSPI flash:
Code: [Select]
const FLEXSPI_NOR_BOOT_CONFIGURATION __attribute__((section(".boot_hdr.conf"))) __boot_config
= {
    ....
    (unsigned long)fnRestoreFlexRAM                                      // insert the address of a routine that can be called to return the FlexRAM back to default settings and reliably reset the device
};

3. The general SW reset function now uses this call (when it exists) to ensure reliable resets:

Code: [Select]
// This routine is called to reset the processor
//
extern void fnResetBoard(void)
{
#if !defined iMX_BOOTLOADER
    uDisable_Interrupt();
#endif
#if (!defined iMX_BOOTLOADER && !defined NO_STACK_RESET)
    fnStackReset(1);                                                     // {7} if the boot loader supports this method the code will not return
#endif
    APPLICATION_INT_RESET_CTR_REG = (VECTKEY | SYSRESETREQ);             // request cortex core reset, which will cause the software reset bit to be set in the mode controller for recognition after restart
    IOMUXC_GPR_GPR16 = IOMUXC_GPR_GPR16_DEFAULT;                         // set the FlexRAM layout back to that taken from the eFuse setting (default configuration) - although the reset is commanded before executing this line it still operates and avoids the RAM layout being changed when the code is still running
}

and the watchdog interrupt also uses it:

Code: [Select]
// If the watchdog fires this interrupt is called 255 clock cycles before the watchdog reset actually takes place
//
static __interrupt void wdog3_irq(void)
{
    __disable_interrupt();
    #if !defined NO_STACK_RESET
    fnStackReset(0);                                                     // {7} if the boot loader supports this method the code will not return
    #endif
    IOMUXC_GPR_GPR16 = IOMUXC_GPR_GPR16_DEFAULT;                         // set the FlexRAM layout back to that taken from the eFuse setting (default configuration)
    FOREVER_LOOP() {}
}

in both cases as long as the user expressly disables it with
#define NO_STACK_RESET

4. As can be seen from the fnStackReset() code it first checks that the bare-minimum loader does have valid code and so it will use the original technique in case it doesn't.

Code: [Select]
// This routine calls a routine in QSPI flash that reconfigures the FlexRAM back to its default and then conditionally commands a core reset
//
extern void fnStackReset(int iReset)
{
        #if defined SECURITY_OTFAD
    void (*_fnCode)(int) = (void (*)(int))(*(unsigned long *)(FLEXSPI_FLASH_BASE + 0x600)); // fixed location in QSPI flash of code to be executed
        #else
    void (*_fnCode)(int) = (void (*)(int))(*(unsigned long *)(FLEXSPI_FLASH_BASE + 0x200)); // fixed location in QSPI flash of code to be executed
        #endif
    if (((unsigned long)_fnCode < FLEXSPI_FLASH_BASE) || ((unsigned long)_fnCode > (FLEXSPI_FLASH_BASE + 0x8000))) {
        return;                                                          // no valid code exists
    }
    _fnCode(iReset);                                                     // execute (doesn't return but either reset or wdog reset will restart the processor after the flexRAM has been set to default)
}

It is recommended that the bare-minimum loader uses this code (included in recent check-ins) and serial loader and applications the new SW reset and watchdog interrupt code to ensure reset reliability when using code from RAM operation.

Regards

Mark

Pages: [1] 2 3 ... 219