-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Anomalies in scheduling of TCP tasks #22
Comments
Thank you for your report.
For your example though, if the system timer resolution is 1 ms, i.e. SYS_TMR_TickCounterFrequencyGet() returns 1000, the calculation should work without any rounding taking effect: so the stack TCPIP_STACK_Task() will be called every 5 ms, as intended. |
Thanks for your reply, Adrian. This is derived from SYS_COUNT_TICK_CONV, as seen in
My SYS_Time_Frequency is 40MHz, I understand the intention of the rounding, but my concern is that the SYS_TMR_TickCounterFrequency value is not actually related to how the task "ticks" are generated. SYS_TMR_CallbackPeriodic() does not specify a number of ticks, rather it specifies a number of milliseconds. Therefore, I think that Obviously, if SYS_COUNT_TICK_CONV was 1000 then 1 SYS_TMR tick = 1 millisecond and there would be no difference. But if SYS_COUNT_TICK_CONV is not 1000, this anomaly occurs. |
I've just seen what may be the critical line of code: You mention a call to SYS_TMR_CallbackPeriodicSetRate() to adjust the result. In my generated code, this call is commented out, so the adjustment is never made. |
The call to the SYS_TMR_CallbackPeriodicSetRate() is commented out as the H3 timer no longer supports it. So it's the same in my code, no problem here. There seems to be a disconnect between the setting of the timer and the result of the SYS_TMR_TickCounterFrequencyGet(). It should match the settings on your system. So practically that "hard coded" value SYS_COUNT_TICK_CONV == 150000 is wrong. |
The issue has been already corrected and it will be part of the next release. The sys_time_h2_adapter should not use the hard coded SYS_COUNT_TICK_CONV but the value returned by the call SYS_TIME_MSToCount(1). Of course the 2nd issue remains (the one caused by the late initialization of the system timer and wrong values for the module timeouts). I can send you a quick snapshot of the fix, if you want to implement it yourself until the release is available. |
Thanks for the update. I'm pleased and impressed you found the "smoking gun" - it's horrendously complex stuff around there! |
Some of the complexity is caused by the need of signaling of RX/TX and TMO events, and running under an RTOS but also bare metal. |
I shall prefix all my other comments by saying that the timing is very complicated, and it's possible that I have misunderstood the intention of the code in places. However, I have used detailed logs from Tracealyzer to analyze this, and I'm fairly sure there is a problem. I'm running on PIC32MX under FreeRTOS.
First Issue
First issue is that
stackTaskRate
is not being calculated properly. The value is set in_TCPIPStackCreateTimer()
based on a complicated rounding calculation involvingSYS_TMR_TickCounterFrequencyGet()
.However, the timer uses
SYS_TMR_CallbackPeriodic()
which is based on a pure millisecond timer, and is not derived from the SYS_TMR_TickCounterFrequency.I am using the following configuration:
Instead of getting a call to
TCPIP_TCP_Task()
every 10ms, I get a call every 7ms (on average).This is because
stackTaskRate
has been set to 7 instead of 5, which means that_TCPIPStackSignalTmo()
is eating away atpSigEntry->currTmo
in larger chunks than it should.Solution
I think the code that sets
stackTaskRate
just needs to be simplified like this:Second (related) Issue
Originally I had a slightly different configuration:
This caused very weird errors because TCPIP_TCP_TASK_TICK_RATE is smaller than
stackTaskRate
, which caused periodic overflows in_TCPIPStackSignalTmo()
aspSigEntry->currTmo
got increasingly negative, and eventually wrapped around to be positive.The end result was that the periodic TCP processsing (e.g. the Nagle algorithm using TCPIP_TCP_AUTO_TRANSMIT_TIMEOUT_VAL) went idle for about 23 seconds every 106 seconds.
When the signal handler is installed by
_TCPIPStackSignalHandlerRegister()
there is a check to make sure the period of the signal handlerasyncTmoMs
is not smaller thanstackTaskRate
.The problem is that, due to the order of initialization,
stackTaskRate
has not been initialized yet, so this test always passes!_TCPIPStackSignalHandlerRegister()
is called during initialization of the TCPIP stack, butTCPIP_STACK_CreateTimer()
is called from_TCPIPStackIsRunState()
which is called fromTCPIP_STACK_Task()
, i.e. AFTER initialization.Solution
One way to address this might be to separate the initialization of
stackTaskRate
from the actual starting of the timer.startTaskRate
can be calculated early during intialization, and the timer started fromTCPIP_STACK_Task()
as currently.The text was updated successfully, but these errors were encountered: