Jump to content

ARM7->ARM9 latency problem


Stonebone

Recommended Posts

I've implemented a simple TFTP-server that I'm going to use for a project later. TFTP works by sending one DATA packet, wait for ACK, send next DATA, and so on. This means only one packet is in the queue at any time and therefore the protocol is very sensitive to latency.

 

I've only gotten about 5 kb/s transfer rates. I've discovered that the bottleneck is the communication between the ARM7 and the ARM9 processors. The ARM9 polls for new packages every 50 ms, when the Wifi_Timer_50ms() function is called. That means new packages are recieved 10 times every second. Since TFTP sends 512 bytes in every package you only get a transfer rate of 10 * 512 ~ 5 kb/s.

 

This leads me to two questions:

 

1. Why is it using polled communications between the processors when the IPC interrupts could be used?

 

2. Why is the IP stack implemented on the ARM9 processor and not ARM7? It would be much more efficient if I could implement the TFTP-server in ARM7... The socket functions could be made available on both processors using IPC for ease of use.

 

And another question:

 

3. In wifi_lib_test TIMER3_DATA is set to -13106. Doesn't that give an interrupt every 100 ms instead of 50 ms?

 

PS. using wifi_lib 0.2b

Link to comment
Share on other sites

I've implemented a simple TFTP-server that I'm going to use for a project later. TFTP works by sending one DATA packet, wait for ACK, send next DATA, and so on. This means only one packet is in the queue at any time and therefore the protocol is very sensitive to latency.

 

I've only gotten about 5 kb/s transfer rates. I've discovered that the bottleneck is the communication between the ARM7 and the ARM9 processors. The ARM9 polls for new packages every 50 ms, when the Wifi_Timer_50ms() function is called. That means new packages are recieved 10 times every second. Since TFTP sends 512 bytes in every package you only get a transfer rate of 10 * 512 ~ 5 kb/s.

 

This leads me to two questions:

 

1. Why is it using polled communications between the processors when the IPC interrupts could be used?

 

2. Why is the IP stack implemented on the ARM9 processor and not ARM7? It would be much more efficient if I could implement the TFTP-server in ARM7... The socket functions could be made available on both processors using IPC for ease of use.

 

And another question:

 

3. In wifi_lib_test TIMER3_DATA is set to -13106. Doesn't that give an interrupt every 100 ms instead of 50 ms?

 

PS. using wifi_lib 0.2b

 

 

 

 

2. I was also wondering why... :lol: It will be faster, no ? Can't the ARM7 CPU be used more than it is actually ? ;)

 

And another question:

 

4. Do you progress on the projet sgstair ? :P

Link to comment
Share on other sites

I had hoped that sgstair would respond to this thread... Anyway, I've implemented some simple IPC interrupts in the lib, only a few lines of code changed, and the speed increased from about 5 kb/s to about 30 kb/s. That six times faster...

 

If anyone wants the changes I can post them here.

Link to comment
Share on other sites

I had hoped that sgstair would respond to this thread... Anyway, I've implemented some simple IPC interrupts in the lib, only a few lines of code changed, and the speed increased from about 5 kb/s to about 30 kb/s. That six times faster...

 

If anyone wants the changes I can post them here.

 

Hi,

 

I'd like to see these changes, actually I had the same exact problem some time ago with wifi transfer program: sending 1kb packets and waiting for ack, would bring to max 10 kbps speeds, so this matches. I think Sgstair is implementing this in the next reelase of the library, but it would be nice to get it now :P

 

By the way, I amnaged to get speeds of 90kbps (writing to CF card) using a different protocol, simply sending packet, waiting 10-14 ms, sending packet form the server side, and asking for retransmissions when needed on the DS side.

It's not standard, but works quite well.

 

Bafio

Link to comment
Share on other sites

somethign that worked for me is using a transmit window (i think thats how it's called)

lets say i'm downloading a file to the ds, i ask for part 1 of the file

the server sends parts 1 2 3 4 5

the ds receibes what it can, lets say 1 2 3 5

so it writes down 1 2 3 and asks for piece 4

and again, the sercver sends 4 5 6 7 8

it worked good for me

Link to comment
Share on other sites

I'd like to see these changes, actually I had the same exact problem some time ago with wifi transfer program: sending 1kb packets and waiting for ack, would bring to max 10 kbps speeds, so this matches. I think Sgstair is implementing this in the next reelase of the library, but it would be nice to get it now :P

Download the new code here: http://www.itstud.chalmers.se/~larssten/wifi_lib.tar.bz2

 

It has some changes to make it compile with the latest devkitpro on linux, but search for "stonebone" to find the important changes. Basically it's just calling IPC_SendSync(0) when a packet is ready to be sent or recieved.

 

Here's what you need to do to use the hacked version. Before you would do something like this in ARM9:

TIMER3_CR = 0;
irqSet(IRQ_TIMER3, Wifi_Timer_50ms);
irqEnable(IRQ_TIMER3);
TIMER3_DATA = (u16)-13106;
TIMER3_CR = TIMER_IRQ_REQ | TIMER_DIV_256;

1. Replace "Wifi_Timer_50ms" with "sgIP_ARP_Timer100ms". Since Wifi_Timer_50ms() used to call that function we still need to have that timer. Perhaps it could be solved in some other way but it worked for me.

 

2. Then add the following code:

irqSet(IRQ_IPC_SYNC, Wifi_Update);
irqEnable(IRQ_IPC_SYNC);
REG_IPC_SYNC = IPC_SYNC_IRQ_ENABLE;

This makes dswifi check for new packages every time the IPC interrupt occurs.

 

3. You also need to add the above code block to ARM7 as well somewhere early in main().

 

4. I think you also need to call Wifi_Update() after printing "ARM7 Init Confirmed." (on ARM9) because it does some more stuff than checking for packages. It can't hurt to have it anyway.

 

Hope that was all.

 

By the way, I amnaged to get speeds of 90kbps (writing to CF card) using a different protocol, simply sending packet, waiting 10-14 ms, sending packet form the server side, and asking for retransmissions when needed on the DS side.

It's not standard, but works quite well.

Yes I looked at your code but it was very hard to understand so I thought it would be easier to write something from scratch. My goal was to write a similar program as yours but which writes to my Flash Advance Pro 256M cart. It doesn't have all the complicated menus of wifi_lib_test which makes it quicker to use. At the moment it has hardcoded wifi settings but I plan to read them from firmware instead which should work fine. Ofcourse if you don't have Mario Kart DS it would be complicated to change the settings but I don't know how useful this program will be for others anyway.

Link to comment
Share on other sites

somethign that worked for me is using a transmit window (i think thats how it's called)

lets say i'm downloading a file to the ds, i ask for part 1 of the file

the server sends parts 1 2 3 4 5

the ds receibes what it can, lets say 1 2 3 5

so it writes down 1 2 3 and asks for piece 4

and again, the sercver sends 4 5 6 7 8

it worked good for me

By using a standard protocol I don't need to write a pc client. This is how I do on the pc side:

curl -T tftpds.ds.gba tftp://192.168.0.189

Link to comment
Share on other sites

Hi, thanks a lot for the code ;)

 

I have been trying to indroduce it, but I have just a porblem:

 

If I understood it right, I added to main:

	TIMER3_CR = 0;
irqSet(IRQ_TIMER3, sgIP_ARP_Timer100ms); // Wifi_Timer_50ms);
irqEnable(IRQ_TIMER3);
TIMER3_DATA = (u16)-13106;
TIMER3_CR = TIMER_IRQ_REQ | TIMER_DIV_256;

irqSet(IRQ_IPC_SYNC, Wifi_Update);
irqEnable(IRQ_IPC_SYNC);
REG_IPC_SYNC = IPC_SYNC_IRQ_ENABLE;

and just a bit later:

while(Wifi_CheckArm7Init()==0) swiWaitForVBlank();
Wifi_Update();

 

This way the ARP timer gets called avery 100ms and I enable the wifi updates with the FIFO.

Problem is this won't compile, because sgIP_ARP_Timer100ms and Wifi_Update are not exposed. If I add the.h files to the path, I run into a whole series of other errors. How do I do this?

 

Thanks

 

Bafio

Link to comment
Share on other sites

This way the ARP timer gets called avery 100ms and I enable the wifi updates with the FIFO.

Problem is this won't compile, because  sgIP_ARP_Timer100ms and Wifi_Update are not exposed. If I add the.h files to the path, I run into a whole series of other errors. How do I do this?

Ah yes I should have said, I added this before the main method as well:

extern void sgIP_ARP_Timer100ms();
extern void Wifi_Update();

Link to comment
Share on other sites

Thanks a lot! It's working really well, I also noticed that drawing on my chat program works much better with these changes!

 

Even more, it's interesting finally being able to compile the lib on new devkitpro...

I'll have some surprises real soon ;)

 

Bafio

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...