Recent Posts

Pages: 1 ... 6 7 [8] 9 10
71
µTasker general / How to configure SPI_FILE_SYSTEM to work with serial loader
« Last post by Ray on September 01, 2023, 10:43:58 PM »
Hi Mark

On a main application, the SPI_FILE_SYSTEM  based on SPI_FLASH_W25Q128 devices (16MB)  seems to work perfectly as a USB MSD. 
(I needed to commented out   // #define ACTIVE_FILE_SYSTEM    which appeared to mess with my FAT32 format)
Reading and writing files and dragging folders to the DISK seems to be fully operational. 

I've had the serial loader with the SDCARD working, but flash chips are a whole lot better solution for me.
It's time for me to tackle the problem with the serial loader.  First, just treating it as a USB MSD doesn't seem to work.  with the  #defines set like this, it seems to lockup. 

loader.h
#define UTASKER_APP_START     (36 * 1024)
#define UTASKER_APP_END           (unsigned char *)(UTASKER_APP_START + (476 * 1024))
#define _UTASKER_APP_START_   (UTASKER_APP_START + (ROOT_FILE_ENTRIES * 32))

config.h of serial loader
    #define USB_INTERFACE                                                // enable USB driver interface
#define USB_MSD_DEVICE_LOADER                                 // USB-MSD device mode (the board appears as a hard-drive to the host)
   
#define USB_DEVICE_SUPPORT             
#define USB_MSD_TIMEOUT       
#define SPI_FLASH_FAT                                                // SPI flash
#define SIMPLE_FLASH                                             // don't perform block management and wear-leveling
#define FLASH_FAT_MANAGEMENT_ADDRESS     (SIZE_OF_FLASH)
#define DELETE_SDCARD_FILE_AFTER_UPDATE   

#define UTFAT_WRITE
#define UTFAT_LFN_READ                                               // enable long file name read support
#define STR_EQUIV_ON                                                 // ensure that this routine is available
#define UTFAT_LFN_WRITE
#define UTFAT_LFN_WRITE_PATCH
#define RANDOM_NUMBER_GENERATOR
#define UTFAT_RETURN_FILE_CREATION_TIME   

Nothing works, it locks up, but  creates a USB_MSD

UPLOAD_DISK(F:)  1.31 MB free of 1.32MB 

This is incorrect because the flash chip is fully formatted with a folder f:\web and it's lone file when I run the application code.

I think the problem is it's not correctly configured for what it is. 

I have it configured with #define USB_MSD_DEVICE_LOADER
however I don't think this is the proper way for it to be implemented for my use-case.

For the initial programming of a new board, the serial loader should fail with this:  #define _DISPLAY_SD_CARD_NOT_PRESENT() fnDebugMsg("SD-Card not present\r\n")
Jump to the main application, and then the main application has a initialization with formats the new device...and all is well.

I'm confused as to how exactly I configure SPI_FLASH as a MSD for the serial loader?  Is it an "SD Card" or USB Device? 
It seems to to walk the line and be a little bit of both?
I noticed I can't just use USB_MSD and SDCARD_SUPPORT

FYI - when I have a properly formatted W25QXXX.ini  the UART3.txt indicates
> SD-Card presentAndFormatted
No Application

I'd like it to act like a SDCARD and the USB doesn't need to do anything until it jumps to the main application.
Debug is fine with just the UART


Oh, some other details are the linker edits, although I feel I have them correctly setup.

and my K_512_128_BM.ld uses:
MEMORY
{
    FLASH (rx) : ORIGIN = 0x00009080, LENGTH = 0x00080000-0x9080         /* 512k Flash - boot loader */
    SRAM (wx)  : ORIGIN = 0x1fff01f0, LENGTH = 0x00020000-0x1f0          /* 128k RAM with vector size 0x1f0 (488 bytes - maximum for all processors) */
}

SECTIONS
{
  __SRAM_segment_start__   = 0x1fff01f0;
  __SRAM_segment_end__     = 0x2000ffff;
  __Vector_segment_start__ = 0x00009080;                                 /* application start address */
  __Vector_segment_end__   = 0x0000908f;
  __FLASH_segment_start__  = 0x00009090;
  __FLASH_segment_end__    = 0x0007ffff;
Thanks
Ray
73
I corrected the double "defined" in the previous post (which was of course incorrect).
Regards
Mark
74
#if defined defined USER_INFO_MASK   
Actually should be
#if defined USER_INFO_MASK

The copy/paste demon wins again  :)

I'll update and test

Thanks
Ray
75
Hi Ray

    #if IP_INTERFACE_COUNT > 1 || IP_NETWORK_COUNT > 1                   // {74}
        #define _TCP_SOCKET_MASK_ASSIGN(uSocket)  (uSocket &= (SOCKET_NUMBER_MASK))
        #define _TCP_SOCKET_MASK(uSocket)         (USOCKET)((uSocket) & (SOCKET_NUMBER_MASK))
        #define _UDP_SOCKET_MASK_ASSIGN(uSocket)  (uSocket &= (SOCKET_NUMBER_MASK))
        #define _UDP_SOCKET_MASK(uSocket)         (USOCKET)((uSocket) & (SOCKET_NUMBER_MASK))
    #else
        #define _TCP_SOCKET_MASK_ASSIGN(uSocket)
        #define _TCP_SOCKET_MASK(uSocket)         (uSocket)
        #define _UDP_SOCKET_MASK_ASSIGN(uSocket)
        #define _UDP_SOCKET_MASK(uSocket)         (uSocket)

    #endif


When used in a single network/single interface environment the masks become dummy.
However I see that when SNMP is used a further USER_INFO_MASK field is used (in order to control multiple SNMP managers).
My suggestion is that the use of the mask for UDP sockets (not TCP sockets) be forced with:

    #if ((IP_INTERFACE_COUNT > 1) || (IP_NETWORK_COUNT > 1))             // {74}
        #define _TCP_SOCKET_MASK_ASSIGN(uSocket)  (uSocket &= (SOCKET_NUMBER_MASK))
        #define _TCP_SOCKET_MASK(uSocket)         (USOCKET)((uSocket) & (SOCKET_NUMBER_MASK))
        #define _UDP_SOCKET_MASK_ASSIGN(uSocket)  (uSocket &= (SOCKET_NUMBER_MASK))
        #define _UDP_SOCKET_MASK(uSocket)         (USOCKET)((uSocket) & (SOCKET_NUMBER_MASK))
    #else
        #define _TCP_SOCKET_MASK_ASSIGN(uSocket)
        #define _TCP_SOCKET_MASK(uSocket)         (uSocket)
        #if defined SER_INFO_MASK
            #define _UDP_SOCKET_MASK_ASSIGN(uSocket)  (uSocket &= (SOCKET_NUMBER_MASK))
            #define _UDP_SOCKET_MASK(uSocket)         (USOCKET)((uSocket) & (SOCKET_NUMBER_MASK))
        #else

            #define _UDP_SOCKET_MASK_ASSIGN(uSocket)
            #define _UDP_SOCKET_MASK(uSocket)     (uSocket)
        #endif
    #endif
#endif


Thanks for identifying the issue - presumably I always had a mult-network environment when working with SNMP to have missed this.

Regards

Mark
76
Hi Mark,
I stared at that 'M' and while it didn't set off the right alarms for me, it did seem odd.  Yes, that fixed my SNMP_TASK problem and now I am able to use the fnRetry(socket,n) to pull from the queue.

Ah, now that worked, but...  Yes a little more.
This makes sense now:
unsigned char ucSNMP_manager = ((socket >> USER_INFO_SHIFT) & USER_INFO_MASK); // extract the snmp manager information

socket is a 5 bit (max 31 sockets, no socket 0)
Needed to extract
        #define USER_INFO_SHIFT      5
        #define USER_INFO_MASK       0x03                                // 4 users supported
        #define SOCKET_NUMBER_MASK   0x1f                                // single network and interface with up to 4 user functions (USOCKET can be single byte width)
      
      
This is the root cause of my fnSendUDP failure too.   I believe you meant to do something with this preprocessor directive _UDP_SOCKET_MASK(SocketHandle); 
in tcpip.h   (487)    #define _UDP_SOCKET_MASK(uSocket)         (uSocket)
however, it doesn't do anything and allows the top 3 bits to shine through.

I actually solved this by doing this instead:
SocketHandle = (SOCKET_NUMBER_MASK & SocketHandle);

extern signed short fnSendUDP(USOCKET SocketHandle......)
UDP_TAB *ptrUDP = tUDP;
  SocketHandle = (SOCKET_NUMBER_MASK & SocketHandle);
  if ((SOCKET_NUMBER_MASK & SocketHandle)> UDP_SOCKETS){ //(_UDP_SOCKET_MASK(SocketHandle) > UDP_SOCKETS) {                  // {7}
      return INVALID_SOCKET_HANDLE;
  }
  if ((uMemcmp(dest_IP, cucNullMACIP, IPV4_LENGTH)) == 0) {
      return(INVALID_DEST_IP);
  }
      
   By the time we are in fnSendUDP()  no other info seems necessary,
   
   if somehow I haven't thought this completely through, I think you might want me to update the #define _UDP_SOCKET_MASK(uSocket)  (uSocket&SOCKET_NUMBER_MASK)
   
   At this point my traps on all 3 managers are being received without me resorting to forcing any ARP requests outside of the normal ARP algorithm.
77
Ray

Check that TASK_SNMP is in ctNodes[] in TaskConfig.h

In addition, make sure that you have no new task with the same name.

    {"MsnMp",     fnSNMP,       SMALL_QUEUE, (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP},


#define TASK_SNMP               'n'                                      // SnMP protocol task

This looks wrong - TASK_SNMP should match the first character of the task's string name.

Try with

    {"nsnMp",     fnSNMP,       SMALL_QUEUE, (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP},

instead!

Regards

Mark

78
Hi Mark,
Well, I'm drilling down and feel I'm close to the root problem, I must be missing something important.

The ARP appeared to be contributing to the problem because it changed so frequently in my noisy environment. 
Locking down the ARP to only required entries from requests seemed to solve the problem however, my system failed in the middle of the night.  Modbus worked, SNMP GET worked, UDP broadcast worked.  Everything but traps. 

With another solid day of debugging with the simulator, I think I've reached a conclusion: 
TASK_SNMP is not in the taskTable and unable to process the trap queue. extern void fnSNMP(TTASKTABLE *ptrTaskTable)
This is how the trap queue draws down, and resends when the message from ARP arrives.  This task is never called.

I added //uTaskerStateChange(TASK_SNMP, UTASKER_ACTIVATE); to my period timer and it falied to find a TASK_SNMP entry
I tried to follow extern TASK_LIMIT uTaskerStart()  these are the tasks it loaded

wdog
ARP
Eth
TCP
usb
O-MOD
app
maintenance
MassSt
DHCP
dNS
period
IGMP
NetInd
keeper
1
2
3
4
5 mine
6 mine
7 mine
8 mine
9 mine
lowPower
NULL

I'm not sure why SNMP doesn't get processed into the task array?
79
Hi Ray

In ip.c I see that only ARPs directed directly to your IP address are entered so I am not sure that it is appropriate to remove that when ARP_IGNORE_FOREIGN_ENTRIES is enabled.
However the ARP table should not be critical since the worst thing that can happen is that a resolution needs to first be performed when the destination is not yet known.
You can also increase the size of the ARP table so that entries don't need to be deleted when new ones are entere but there is not space for all.

Regards

Mark

80
Hi Mark,
Yes, I believe ARP is not the root cause, rather, it is possible the ARP process is just a little overwhelmed in my noisy network envornment.
The ARP request for 172.22.0.1 is for the gateway, probably for NTP - I've disabled this for now.


I mistakenly changed one of the ARP_IGNORE_FOREIGN_ENTRIES  in static void fnSendARP_response(ARP_INPUT *ptrArpInput)
On line 682, if we received our own ARP request, it wasn't being added, I have fixed this.
What I meant to comment out was your suggestion in fnHandleARP_response()
That is now commented out with the preprocessor, however it didn't fix the problem of extra ARP entires.

Additionally, there is an instance of fnAddARP() located in ip.c  line 688
This was adding all the misc ARP's it received, I have diabled with the preprocessor, now my ARP table has 3 and only 3 entries (+ broadcast)

This didn't resovle my trap problem. The symptom was trap manager 1 worked but 2 or 3 didn't.   
As always your amazing debugger to the rescue and discovered in static int fnSendTrap() function, line 1099 fnSendUDP()  has extra information OR'd into the SocketHandle and would fail the first check.   

Commenting this allows traps beyond manager 1 to send /* | ptrSNMP_manager_details[iManagerRef].snmp_manager_details | ((iManagerRef & USER_INFO_MASK) << USER_INFO_SHIFT)*/
I have no idea what those values are for, but commenting them out allows my 3 managers to receive traps.

if (fnSendUDP((USOCKET)(SNMPSocketNr /* | ptrSNMP_manager_details[iManagerRef].snmp_manager_details | ((iManagerRef & USER_INFO_MASK) << USER_INFO_SHIFT)*/)  ,(unsigned char*)ptrSNMP_manager_details[iManagerRef].snmp_manager_ip_address, SNMP_MANAGER_PORT, (unsigned char*)&UDP_Message.tUDP_Header, (unsigned short)iNewLength, OWN_TASK) == NO_ARP_ENTRY)

which failes the first check of fnSendUDP(USOCKET SocketHandle, unsigned char *dest_IP, unsigned short usRemotePort, unsigned char *ptrBuf, unsigned short usDataLen, UTASK_TASK OwnerTask)

    if (_UDP_SOCKET_MASK(SocketHandle) > UDP_SOCKETS) {                  // {7}
        return INVALID_SOCKET_HANDLE;
    }
   
Cautiously, all is well...I'm running a 5 day blast on coldstart traps to make sure we don't bog down.

Thank You
Ray
Pages: 1 ... 6 7 [8] 9 10