Stack overflow after call to OSStartHighRdy (uC/OS-III) - embedded

I'm in the process of getting uC/OS-III working on an NXP MIMXRT1062 using the MCUXpresso ide with gcc compiler. When the OS starts multitasking it calls the OSStartHighRdy function:
.thumb_func
OSStartHighRdy:
CPSID I # Prevent interruption during context switch
MOVW R0, #:lower16:NVIC_SYSPRI14 # Set the PendSV exception priority
MOVT R0, #:upper16:NVIC_SYSPRI14
MOVW R1, #:lower16:NVIC_PENDSV_PRI
MOVT R1, #:upper16:NVIC_PENDSV_PRI
STRB R1, [R0]
MOVS R0, #0 # Set the PSP to 0 for initial context switch call
MSR PSP, R0
MOVW R0, #:lower16:OS_CPU_ExceptStkBase # Initialize the MSP to the OS_CPU_ExceptStkBase
MOVT R0, #:upper16:OS_CPU_ExceptStkBase
LDR R1, [R0]
MSR MSP, R1
BL OSTaskSwHook # Call OSTaskSwHook() for FPU Push & Pop
MOVW R0, #:lower16:OSPrioCur # OSPrioCur = OSPrioHighRdy;
MOVT R0, #:upper16:OSPrioCur
MOVW R1, #:lower16:OSPrioHighRdy
MOVT R1, #:upper16:OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
MOVW R0, #:lower16:OSTCBCurPtr # OSTCBCurPtr = OSTCBHighRdyPtr;
MOVT R0, #:upper16:OSTCBCurPtr
MOVW R1, #:lower16:OSTCBHighRdyPtr
MOVT R1, #:upper16:OSTCBHighRdyPtr
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] # R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
MSR PSP, R0 # Load PSP with new process SP
MRS R0, CONTROL
ORR R0, R0, #2
BIC R0, R0, #4 # Clear FPCA bit to indicate FPU is not in use
MSR CONTROL, R0
ISB # Sync instruction stream
LDMFD SP!, {R4-R11, LR} # Restore r4-11, lr from new process stack
LDMFD SP!, {R0-R3} # Restore r0, r3
LDMFD SP!, {R12, LR} # Load R12 and LR
LDMFD SP!, {R1, R2} # Load PC and discard xPSR
CPSIE I
BX R1
However, the stack overflows after this line MSR MSP, R1
This is my main function:
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1062.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "../uC-OS3/uCOS-III/Source/os.h"
#include "start_task.h"
#include "../BSP/bsp_clk.h"
#include "../BSP/bsp_int.h"
#include "../BSP/bsp_os.h"
#include "../uC-OS3/uC-LIB/lib_mem.h"
#include "os_app_hooks.h"
/* TODO: insert other definitions and declarations here. */
void PendSV_Handler(void)
{
OS_CPU_PendSVHandler();
}
void SysTick_Handler(void)
{
OS_CPU_SysTickHandler();
}
/*
* #brief Application entry point.
*/
int main(void)
{
OS_ERR err;
/* Init board hardware. */
BOARD_ConfigMPU();
BSP_ClkInit();
SysTick_Config(SystemCoreClock/600000);
BSP_IntInit();
BSP_OS_TickInit();
Mem_Init();
CPU_IntDis();
CPU_Init();
// 1. Call OSInit
OSInit(&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
App_OS_SetAllHooks();
OSSchedRoundRobinCfg(DEF_ENABLED, 10, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// 2. Call OSTaskCreate only once after call to OSInit
OSTaskCreate(&startTaskTCB,
startTaskName,
startTask,
(void *)0,
startTaskPrio,
&startTaskStk[0],
startTaskStkLimit,
startTaskStkSize,
startTaskQSize,
startTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// 3. Call OSStart -- starts multitasking, doesn't return
OSStart(&err);
while (1);
return 0;
}
This are the 3 tasks I have:
#include "start_task.h"
#include "blinky_task.h"
#include "other_task.h"
#include "../BSP/bsp_os.h"
OS_TCB startTaskTCB;
CPU_CHAR* startTaskName = "START TASK";
OS_PRIO startTaskPrio = 2;
CPU_STK_SIZE startTaskStkLimit = START_TASK_STK_SIZE/10;
CPU_STK_SIZE startTaskStkSize = START_TASK_STK_SIZE;
CPU_STK startTaskStk[START_TASK_STK_SIZE];
OS_MSG_QTY startTaskQSize = 0;
OS_TICK startTaskQuanta = 0;
void startTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
BSP_OS_TickEnable();
// Create all tasks needed
OSTaskCreate(&blinkyTaskTCB,
blinkyTaskName,
blinkyTask,
(void *)0,
blinkyTaskPrio,
&blinkyTaskStk[0],
blinkyTaskStkLimit,
blinkyTaskStkSize,
blinkyTaskQSize,
blinkyTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
OSTaskCreate(&otherTaskTCB,
otherTaskName,
otherTask,
(void *)0,
otherTaskPrio,
&otherTaskStk[0],
otherTaskStkLimit,
otherTaskStkSize,
otherTaskQSize,
otherTaskQuanta,
(void *)0,
OS_OPT_TASK_NONE,
&err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
while (DEF_ON)
{
// Just have a small delay
OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
}
}
#include "blinky_task.h"
#include "stdbool.h"
#include "fsl_gpio.h"
OS_TCB blinkyTaskTCB;
CPU_CHAR* blinkyTaskName = "BLINKY TASK";
OS_PRIO blinkyTaskPrio = 3;
CPU_STK_SIZE blinkyTaskStkLimit = BLINKY_TASK_STK_SIZE/10;
CPU_STK_SIZE blinkyTaskStkSize = BLINKY_TASK_STK_SIZE;
CPU_STK blinkyTaskStk[BLINKY_TASK_STK_SIZE];
OS_MSG_QTY blinkyTaskQSize = 0;
OS_TICK blinkyTaskQuanta = 0;
static bool blinkState = true;
void blinkyTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
gpio_pin_config_t ledPinConf = { kGPIO_DigitalOutput, 1, kGPIO_NoIntmode };
GPIO_PinInit(GPIO1, 8U, &ledPinConf);
while (DEF_ON)
{
// Delay between LED toggle
OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
// Toggle LED
if (blinkState)
{
GPIO_PinWrite(GPIO1, 8U, 0U);
blinkState = false;
}
else
{
GPIO_PinWrite(GPIO1, 8U, 1U);
blinkState = true;
}
}
}
#include "other_task.h"
OS_TCB otherTaskTCB;
CPU_CHAR* otherTaskName = "OTHER TASK";
OS_PRIO otherTaskPrio = 4;
CPU_STK_SIZE otherTaskStkLimit = OTHER_TASK_STK_SIZE/10;
CPU_STK_SIZE otherTaskStkSize = OTHER_TASK_STK_SIZE;
CPU_STK otherTaskStk[OTHER_TASK_STK_SIZE];
OS_MSG_QTY otherTaskQSize = 0;
OS_TICK otherTaskQuanta = 0;
void otherTask(void *p_arg)
{
(void)p_arg;
OS_ERR err;
while (DEF_ON)
{
OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err);
if (OS_ERR_NONE != err)
{
while (1); // Hang here
}
}
}
The task header files:
#ifndef START_TASK_H_
#define START_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define START_TASK_STK_SIZE (256U)
extern OS_TCB startTaskTCB;
extern CPU_CHAR* startTaskName;
extern OS_PRIO startTaskPrio;
extern CPU_STK_SIZE startTaskStkLimit;
extern CPU_STK_SIZE startTaskStkSize;
extern CPU_STK startTaskStk[START_TASK_STK_SIZE];
extern OS_MSG_QTY startTaskQSize;
extern OS_TICK startTaskQuanta;
void startTask(void *p_arg);
#endif /* START_TASK_H_ */
#ifndef BLINKY_TASK_H_
#define BLINKY_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define BLINKY_TASK_STK_SIZE (256U)
extern OS_TCB blinkyTaskTCB;
extern CPU_CHAR* blinkyTaskName;
extern OS_PRIO blinkyTaskPrio;
extern CPU_STK_SIZE blinkyTaskStkLimit;
extern CPU_STK_SIZE blinkyTaskStkSize;
extern CPU_STK blinkyTaskStk[BLINKY_TASK_STK_SIZE];
extern OS_MSG_QTY blinkyTaskQSize;
extern OS_TICK blinkyTaskQuanta;
void blinkyTask(void *p_arg);
#endif /* BLINKY_TASK_H_ */
#ifndef OTHER_TASK_H_
#define OTHER_TASK_H_
#include "../uC-OS3/uCOS-III/Source/os.h"
#define OTHER_TASK_STK_SIZE (256U)
extern OS_TCB otherTaskTCB;
extern CPU_CHAR* otherTaskName;
extern OS_PRIO otherTaskPrio;
extern CPU_STK_SIZE otherTaskStkLimit;
extern CPU_STK_SIZE otherTaskStkSize;
extern CPU_STK otherTaskStk[OTHER_TASK_STK_SIZE];
extern OS_MSG_QTY otherTaskQSize;
extern OS_TICK otherTaskQuanta;
void otherTask(void *p_arg);
#endif /* OTHER_TASK_H_ */
I can also include the uC/OS-III code if needed.
At the moment a hardfault occurs after the last task (otherTask) and I'm not sure where to begin looking.
I have increased and decreased the task's stack size but no change.
The mcu's stack is 4k and after the MSR MSP, R1 line, it goes to around 120k

Related

when i want to simulate a adhoc scene,which use 802.11a wifiphy ,i usually get an error

assert failed. cond="m_wifiPhy->m_currentEvent == 0", +23.801712798s 11 file=../src/wifi/model/phy-entity.cc, line=467
terminate called without an active exception
here is my code.I am a freshman in ns3,but i need get my simulation run correctly Eagerly.These days i am really exhausted to find the problem,and sttle it.So I really need someone to help me.
#include <fstream>
#include <iostream>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/aodv-module.h"
#include "ns3/olsr-module.h"
#include "ns3/dsdv-module.h"
#include "ns3/dsr-module.h"
#include "ns3/applications-module.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/animation-interface.h"
using namespace std;
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("constant-position-experiment");
void ReceivePacket (Ptr<Socket> socket)
{
NS_LOG_INFO ("Received one packet!");
Ptr<Packet> packet = socket->Recv ();
SocketIpTosTag tosTag;
NS_LOG_UNCOND (" received a packet!");
if (packet->RemovePacketTag (tosTag))
{
//NS_LOG_UNCOND (" TOS = " << (uint32_t)tosTag.GetTos ());
}
SocketIpTtlTag ttlTag;
if (packet->RemovePacketTag (ttlTag))
{
//NS_LOG_UNCOND (" TTL = " << (uint32_t)ttlTag.GetTtl ());
}
}
static void SendPacket (Ptr<Socket> socket, uint32_t pktSize,
uint128_t pktCount, Time pktInterval ,uint128_t counta)
{
if (pktCount > 0)
{
counta+=1;
socket->Send (Create<Packet> (pktSize));
Simulator::Schedule (pktInterval, &SendPacket,
socket, pktSize,pktCount - 1, pktInterval,counta);
NS_LOG_UNCOND (" send a packet!"<<(uint32_t)counta<<Simulator::Now());
}
else
{
socket->Close ();
}
}
int main(int argc,char*argv[])
{
int n=30;
double totaltime=4000000;
double settime=60;
double distance=35000;
string phyMode ("OfdmRate2_25MbpsBW5MHz");
string dataRate ("300kb/s");
uint64_t packetSize=512;
uint128_t packetCount =6530;
double packetInterval=0.05;
uint128_t counta(0);
uint32_t ipTos = 0;
bool ipRecvTos = true;
uint32_t ipTtl = 0;
bool ipRecvTtl = true;
//OfdmRate1_5MbpsBW5MHz
// OfdmRate2_25MbpsBW5MHz
// OfdmRate3MbpsBW5MHz
// OfdmRate4_5MbpsBW5MHz
// OfdmRate6MbpsBW5MHz
// OfdmRate9MbpsBW5MHz
// OfdmRate12MbpsBW5MHz
// OfdmRate13_5MbpsBW5MHz
// OfdmRate3MbpsBW10MHz
// OfdmRate4_5MbpsBW10MHz
// OfdmRate6MbpsBW10MHz
// OfdmRate9MbpsBW10MHz
// OfdmRate12MbpsBW10MHz
// OfdmRate18MbpsBW10MHz
// OfdmRate24MbpsBW10MHz
// OfdmRate27MbpsBW10MHz
// OfdmRate6Mbps
// OfdmRate9Mbps
// OfdmRate12Mbps
// OfdmRate18Mbps
// OfdmRate24Mbps
// OfdmRate36Mbps
// OfdmRate48Mbps
// OfdmRate54Mbps
CommandLine cmd (__FILE__);
cmd.AddValue ("distance", "the distance bettween nodes", distance);
cmd.AddValue ("settime", "olsr settime", settime);
cmd.AddValue ("phyMode", "olsr settime", phyMode);
cmd.AddValue ("dataRate", "olsr settime", dataRate);
cmd.Parse (argc, argv);
// LogComponentEnable("OnOffApplication",LOG_LEVEL_INFO);
NodeContainer c;
c.Create(n);
NodeContainer n0n23=NodeContainer(c.Get(0),c.Get(23));
NS_LOG_UNCOND ("distance:"<<distance<<"phymode: "<<phyMode<<"dataRate: "+dataRate);
//wifpyh wifchannel
WifiHelper wifi;
wifi.SetStandard (WIFI_STANDARD_80211a);
WifiMacHelper wifiMac;
YansWifiPhyHelper wifiPhy;
YansWifiChannelHelper wifiChannel;
wifiPhy.Set("TxGain",DoubleValue(4.5));
wifiPhy.Set("RxGain",DoubleValue(4.5));
//
wifiPhy.Set("RxSensitivity",DoubleValue(-90));
wifiPhy.Set("Antennas",UintegerValue(2));
wifiPhy.Set ("TxPowerStart",DoubleValue (37));
wifiPhy.Set ("TxPowerEnd", DoubleValue (37));
wifiPhy.Set ("RxNoiseFigure",DoubleValue (0));
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel","Frequency",DoubleValue(1.2e+09));
wifiPhy.SetChannel (wifiChannel.Create ());
wifiMac.SetType ("ns3::AdhocWifiMac");
wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",StringValue (phyMode),
"ControlMode",StringValue (phyMode));
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
//mobility
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (distance),
"DeltaY", DoubleValue (distance),
"GridWidth", UintegerValue (5),
"LayoutType", StringValue ("RowFirst"));
mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-200000, 200000, -200000, 200000)),
"Speed", StringValue ("ns3::ConstantRandomVariable[Constant=39]"),
"Pause", StringValue ("ns3::ConstantRandomVariable[Constant=2]"));
mobility.Install (c);
//internet
OlsrHelper olsr;
Ipv4ListRoutingHelper list;
list.Add (olsr, 10);
InternetStackHelper internet;
internet.SetRoutingHelper (list); // has effect on the next Install ()
internet.Install (c);
Ipv4AddressHelper addressAdhoc;
addressAdhoc.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces;
interfaces = addressAdhoc.Assign (devices);
//application
NS_LOG_INFO ("Create sockets.");
//Receiver socket on n1
TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
Ptr<Socket> recvSink = Socket::CreateSocket (c.Get (1), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 4477);
recvSink->SetIpRecvTos (ipRecvTos);
recvSink->SetIpRecvTtl (ipRecvTtl);
recvSink->Bind (local);
recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
//Sender socket on n0
Ptr<Socket> source = Socket::CreateSocket (c.Get (27), tid);
InetSocketAddress remote = InetSocketAddress (interfaces.GetAddress (1), 4477);
//Set socket options, it is also possible to set the options after the socket has been created/connected.
if (ipTos > 0)
{
source->SetIpTos (ipTos);
}
if (ipTtl > 0)
{
source->SetIpTtl (ipTtl);
}
source->Connect (remote);
//flowmonitor
string s1=phyMode.substr(8,3);
string s2=phyMode.substr(phyMode.length()-4,4);
string s3=dataRate.substr(0,dataRate.length()-2);
string filename=to_string(int(distance/1000))+"_"+s1+"_"+s2+"_"+s3;
Ptr<FlowMonitor> flowmon;
FlowMonitorHelper flowmonHelper;
flowmon = flowmonHelper.InstallAll ();
Ptr<OutputStreamWrapper> routingStream=Create<OutputStreamWrapper>(filename+"routes.tr",std::ios::out);
olsr.PrintRoutingTableAt(Seconds(40.0),c.Get(2),routingStream);
AnimationInterface anim ((filename+".xml"));
anim.SetMaxPktsPerTraceFile(99999999999999);
Time interPacketInterval = Seconds (packetInterval);
Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
Seconds (1.0), &SendPacket,
source, packetSize, packetCount, interPacketInterval,counta);
Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
Seconds (70.0), &SendPacket,
source, packetSize, packetCount, interPacketInterval,counta);
Simulator::ScheduleWithContext (source->GetNode ()->GetId (),
Seconds (30.0), &SendPacket,
source, packetSize, packetCount, interPacketInterval,counta);
Simulator::Stop (Seconds (totaltime));
Simulator::Run ();
Simulator::Destroy ();
flowmon->SerializeToXmlFile (filename+".flowmon", false, false);
// numPackets=0;
return 0;
}
why this problem occur ?
How to settle it?

Do DLLs have a lower priority that may affect ethernet functionality? Experiencing TCP retransmissions

I have some modbus ethernet tcp communications that I'm attempting to do in a DLL. I get numerous TCP Retransmissions from the target device, as seen in WireShark.
(In this image, 192.168.1.5 is the Modbus device. 192.168.1.72 is the computer)
However, when the same code is inserted directly into an application, there are no communication errors.
I'm wondering if DLLs have some sort of lower priority that can cause slower communications, or if anyone may have any insight as to why this code would run without TCP issue in an application, but not in a DLL.
Here is the dll header:
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
typedef void *eioTHandle;
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int __stdcall eioConnect( unsigned short ModelId, char *Ip, eioTHandle *Handle );
#ifdef __cplusplus
}
#endif
#endif
And here is the source file:
#include "main.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdint.h>
#define EIO500_S 0
#define EIO500_MS 1000
#define eioERROR -1
#define eioSUCCESS 0
static uint8_t m_UnitId = 0xff;
static SOCKET m_Sock;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
int __stdcall eioConnect( unsigned short ModelId, char *Ip, eioTHandle *Handle )
{
WSADATA Wsa;
struct sockaddr_in Server;
int Result;
char Buffer[256];
char InBuffer[256];
// CONNECTION --------------------------------------------------------------
if (WSAStartup(MAKEWORD(2,2), &Wsa) != 0)
{
return eioERROR;
}
m_Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_Sock == INVALID_SOCKET)
{
WSACleanup();
return eioERROR;
}
Server.sin_addr.s_addr = inet_addr(Ip);
Server.sin_family = AF_INET;
Server.sin_port = htons(502);
if (connect(m_Sock, (struct sockaddr *)&Server, sizeof(Server))
== SOCKET_ERROR)
{
closesocket(m_Sock);
m_Sock = INVALID_SOCKET;
WSACleanup();
return eioERROR;
}
// -------------------------------------------------------------------------
for (int Ctr = 0; Ctr < 50000; Ctr++)
{
// SEND COMMAND --------------------------------------------------------
// 5 bytes in a Send Read Multiple Coils command.
int NumBytes = 5;
Buffer[0] = 0;
Buffer[1] = 0;
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = NumBytes + 1; // 1 for unit id.
Buffer[6] = m_UnitId;
// 0 = Function code.
Buffer[7] = 0x01;
// 1+2 = Address.
Buffer[8] = 0;
Buffer[9] = 8;
// 3+4 = Number of bits to read.
Buffer[10] = 0;
Buffer[11] = 8;
if (send(m_Sock, Buffer, NumBytes + 7, 0) == SOCKET_ERROR)
{
continue;
}
// ---------------------------------------------------------------------
// WAIT FOR RECEIVE ----------------------------------------------------
WSAEVENT RecvEvent;
int Ret;
RecvEvent = WSACreateEvent();
WSAEventSelect( m_Sock, RecvEvent, FD_READ );
Ret = WSAWaitForMultipleEvents(1, &RecvEvent, TRUE, 1000, FALSE);
WSAResetEvent(RecvEvent);
if (Ret == WSA_WAIT_TIMEOUT)
continue;
// -------------------------------------------------------------------------
// Check for any reply.
recv(m_Sock, InBuffer, 256, 0);
}
// DISCONNECT --------------------------------------------------------------
Result = shutdown(m_Sock, SD_SEND);
if (Result == SOCKET_ERROR)
{
closesocket(m_Sock);
WSACleanup();
m_Sock = INVALID_SOCKET;
return eioERROR;
}
// Receive until the peer closes the connection.
while (recv(m_Sock, Buffer, 256, 0) > 0);
closesocket(m_Sock);
WSACleanup();
m_Sock = INVALID_SOCKET;
// ------------------------------------------------------------------------
return eioSUCCESS;
}
I've simplified the code as much as possible. The communication is in a loop for testing. The original application would poll this data from the device.
No. From the network's perspective there's no difference in TCP segments sent some way or other. There may be a protocol prioritation though (QoS) that may cause packet drops when links are saturated.
A more likely cause could be a problem with the checksums: invalid checksums cause packet drops which in turn cause retransmissions. Possibly the API works slightly different when called from a DLL, so the checksums are calculated (correctly).

vtables - Why does this work(binary compatibility of C and C++ under COM)?

I was trying to test my understanding of COM and realized that when I tried calling a C++ object with a pure C interface(with vtables and this pointer as first argument), it wasn't working as expected because my compiler uses thiscall to pass "this" argument of the method in the ecx register, rather than on the stack(so when C++ tried to call my method through reinterpreted interface, it didn't know what "this" was), so C cannot call C++ methods in x86 without inline assembly to pass/accept the first argument via ecx.
I made a very simple COM component to test this binary compatibility. I made a simple Visual Basic class that I wanted to call with both IDispatch C++ abstract class pointer, and an IDispatch pure C class pointer(with a single member lpVtbl);
<System.Runtime.InteropServices.ComVisible(True)>
Public Class Greeter
Public Sub Greet()
MsgBox("Hey!")
End Sub
End Class
The code goes as follows
stdafx.h:
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <assert.h>
main.cpp
#include "stdafx.h"
typedef struct {
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
__RPC__in struct c_IDispatch * This,
/* [in] */ __RPC__in REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
__RPC__in struct c_IDispatch * This);
ULONG ( STDMETHODCALLTYPE *Release )(
__RPC__in struct c_IDispatch * This);
HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
__RPC__in struct c_IDispatch * This,
/* [out] */ __RPC__out UINT *pctinfo);
HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
__RPC__in struct c_IDispatch * This,
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo);
HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
__RPC__in struct c_IDispatch * This,
/* [in] */ __RPC__in REFIID riid,
/* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
/* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId);
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
struct c_IDispatch * This,
/* [annotation][in] */
_In_ DISPID dispIdMember,
/* [annotation][in] */
_In_ REFIID riid,
/* [annotation][in] */
_In_ LCID lcid,
/* [annotation][in] */
_In_ WORD wFlags,
/* [annotation][out][in] */
_In_ DISPPARAMS *pDispParams,
/* [annotation][out] */
_Out_opt_ VARIANT *pVarResult,
/* [annotation][out] */
_Out_opt_ EXCEPINFO *pExcepInfo,
/* [annotation][out] */
_Out_opt_ UINT *puArgErr);
END_INTERFACE
} c_IDispatchVtbl;
typedef struct c_IDispatch {
c_IDispatchVtbl *lpVtbl;
} c_IDispatch;
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IDispatch *x = nullptr;
CLSID c1;
DISPID dispid_Greeter_Greet;
LPOLESTR name = L"Greet";
assert(SUCCEEDED(CLSIDFromProgID(L"Dmitry.Greeter", &c1)));
CoCreateInstance(c1, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (LPVOID*)&x);
assert(SUCCEEDED(x->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispid_Greeter_Greet)));
DISPPARAMS params;
ZeroMemory(&params, sizeof(params));
assert(SUCCEEDED(x->Invoke(dispid_Greeter_Greet, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params
, NULL, NULL, NULL)));
c_IDispatch *y = *(c_IDispatch **)&x;
assert(SUCCEEDED(y->lpVtbl->Invoke(y, dispid_Greeter_Greet, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params
, NULL, NULL, NULL)));
return 0;
}
to my surprise, both calls succeed even though IDispatch uses thiscall, whereas c_IDispatch doesn't.
Here's the disassembly:
int _tmain(int argc, _TCHAR* argv[])
{
013F1412 add dword ptr [ebx],esi
013F1414 lds ecx,fword ptr [ecx-0B7403BBh]
CoInitialize(NULL);
013F141A push 0
013F141C call dword ptr ds:[13FA360h]
013F1422 cmp esi,esp
013F1424 call __RTC_CheckEsp (013F115Eh)
IDispatch *x = nullptr;
013F1429 mov dword ptr [x],0
CLSID c1;
DISPID dispid_Greeter_Greet;
LPOLESTR name = L"Greet";
013F1430 mov dword ptr [name],13F5858h
assert(SUCCEEDED(CLSIDFromProgID(L"Dmitry.Greeter", &c1)));
013F1437 mov esi,esp
013F1439 lea eax,[c1]
013F143C push eax
013F143D push 13F5868h
013F1442 call dword ptr ds:[13FA364h]
013F1448 cmp esi,esp
013F144A call __RTC_CheckEsp (013F115Eh)
013F144F test eax,eax
013F1451 jge wmain+89h (013F1479h)
013F1453 mov ecx,dword ptr ds:[13F9000h]
013F1459 ?? ??
013F145A ?? ??
013F145B ?? ??
013F145C ?? ??
013F145D ?? ??
013F145E ?? ??
013F145F ?? ??
013F1460 ?? ??
013F1461 ?? ??
013F1462 ?? ??
013F1463 ?? ??
013F1464 ?? ??
013F1465 ?? ??
013F1466 ?? ??
013F1467 ?? ??
013F1468 ?? ??
013F1469 ?? ??
013F146A ?? ??
013F146B ?? ??
013F146C ?? ??
013F146D ?? ??
013F146E ?? ??
013F146F ?? ??
013F1470 ?? ??
013F1471 ?? ??
013F1472 ?? ??
013F1473 ?? ??
013F1474 ?? ??
013F1475 ?? ??
013F1476 ?? ??
013F1477 ?? ??
013F1478 ?? ??
013F1479 ?? ??
013F147A ?? ??
013F147B ?? ??
CoCreateInstance(c1, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (LPVOID*)&x);
013F147C inc ebp
013F147D ?? ??
013F147E ?? ??
013F147F ?? ??
013F1480 ?? ??
013F1481 ?? ??
013F1482 ?? ??
013F1483 ?? ??
013F1484 ?? ??
013F1485 ?? ??
013F1486 ?? ??
013F1487 ?? ??
013F1488 ?? ??
013F1489 ?? ??
013F148A ?? ??
013F148B ?? ??
013F148C ?? ??
013F148D ?? ??
013F148E ?? ??
CoCreateInstance(c1, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (LPVOID*)&x);
013F148F mov dword ptr ds:[F43B013Fh],eax
013F1494 call __RTC_CheckEsp (013F115Eh)
assert(SUCCEEDED(x->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispid_Greeter_Greet)));
013F1499 mov esi,esp
013F149B lea eax,[dispid_Greeter_Greet]
013F149E push eax
013F149F push 800h
013F14A4 push 1
013F14A6 lea ecx,[name]
013F14A9 push ecx
013F14AA push 13F64B4h
013F14AF mov edx,dword ptr [x]
013F14B2 mov eax,dword ptr [edx]
013F14B4 mov ecx,dword ptr [x]
013F14B7 push ecx
013F14B8 mov edx,dword ptr [eax+14h]
013F14BB call edx
013F14BD cmp esi,esp
013F14BF call __RTC_CheckEsp (013F115Eh)
013F14C4 test eax,eax
013F14C6 jge wmain+0FDh (013F14EDh)
013F14C8 mov eax,dword ptr ds:[013F9000h]
013F14CD add eax,0Ah
013F14D0 mov esi,esp
013F14D2 push eax
013F14D3 push 13F5890h
013F14D8 push 13F5A38h
013F14DD call dword ptr ds:[13FA30Ch]
013F14E3 add esp,0Ch
013F14E6 cmp esi,esp
013F14E8 call __RTC_CheckEsp (013F115Eh)
DISPPARAMS params;
ZeroMemory(&params, sizeof(params));
013F14ED push 10h
DISPPARAMS params;
ZeroMemory(&params, sizeof(params));
013F14EF push 0
013F14F1 lea eax,[params]
013F14F4 push eax
013F14F5 call _memset (013F1087h)
013F14FA add esp,0Ch
assert(SUCCEEDED(x->Invoke(dispid_Greeter_Greet, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params
, NULL, NULL, NULL)));
013F14FD mov esi,esp
013F14FF push 0
013F1501 push 0
013F1503 push 0
013F1505 lea eax,[params]
013F1508 push eax
013F1509 push 1
013F150B push 800h
013F1510 push 13F64B4h
013F1515 mov ecx,dword ptr [dispid_Greeter_Greet]
013F1518 push ecx
013F1519 mov edx,dword ptr [x]
013F151C mov eax,dword ptr [edx]
013F151E mov ecx,dword ptr [x]
013F1521 push ecx
013F1522 mov edx,dword ptr [eax+18h]
013F1525 call edx
013F1527 cmp esi,esp
013F1529 call __RTC_CheckEsp (013F115Eh)
013F152E test eax,eax
013F1530 jge wmain+167h (013F1557h)
013F1532 mov eax,dword ptr ds:[013F9000h]
013F1537 add eax,0Fh
013F153A mov esi,esp
assert(SUCCEEDED(x->Invoke(dispid_Greeter_Greet, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params
, NULL, NULL, NULL)));
013F153C push eax
013F153D push 13F5890h
013F1542 push 13F5B20h
013F1547 call dword ptr ds:[13FA30Ch]
013F154D add esp,0Ch
013F1550 cmp esi,esp
013F1552 call __RTC_CheckEsp (013F115Eh)
c_IDispatch *y = *(c_IDispatch **)&x;
013F1557 mov eax,dword ptr [x]
013F155A mov dword ptr [y],eax
assert(SUCCEEDED(y->lpVtbl->Invoke(y, dispid_Greeter_Greet, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params
, NULL, NULL, NULL)));
013F155D mov esi,esp
013F155F push 0
013F1561 push 0
013F1563 push 0
013F1565 lea eax,[params]
013F1568 push eax
013F1569 push 1
013F156B push 800h
013F1570 push 13F64B4h
013F1575 mov ecx,dword ptr [dispid_Greeter_Greet]
013F1578 push ecx
013F1579 mov edx,dword ptr [y]
013F157C push edx
013F157D mov eax,dword ptr [y]
013F1580 mov ecx,dword ptr [eax]
013F1582 mov edx,dword ptr [ecx+18h]
013F1585 call edx
013F1587 cmp esi,esp
013F1589 call __RTC_CheckEsp (013F115Eh)
013F158E test eax,eax
013F1590 jge wmain+1C7h (013F15B7h)
013F1592 mov eax,dword ptr ds:[013F9000h]
013F1597 add eax,14h
013F159A mov esi,esp
013F159C push eax
013F159D push 13F5890h
013F15A2 push 13F7B20h
013F15A7 call dword ptr ds:[13FA30Ch]
013F15AD add esp,0Ch
013F15B0 cmp esi,esp
013F15B2 call __RTC_CheckEsp (013F115Eh)
return 0;
013F15B7 xor eax,eax
}
013F15B9 push edx
013F15BA mov ecx,ebp
013F15BC push eax
013F15BD lea edx,ds:[13F15E8h]
013F15C3 call #_RTC_CheckStackVars#8 (013F10A0h)
013F15C8 pop eax
013F15C9 pop edx
013F15CA pop edi
013F15CB pop esi
013F15CC pop ebx
013F15CD mov ecx,dword ptr [ebp-4]
013F15D0 xor ecx,ebp
013F15D2 call #__security_check_cookie#4 (013F101Eh)
013F15D7 add esp,124h
013F15DD cmp ebp,esp
013F15DF call __RTC_CheckEsp (013F115Eh)
013F15E4 mov esp,ebp
013F15E6 pop ebp
013F15E7 ret
Can someone please explain why both calls succeed despite having different calling conventions(one convention passes this via stack, the second passes this via ecx)?

Creating a RAW UDP connection in lwip ARP

I am currently working to create a simple transfer protocol over Ethernet. I have a SP605 Xilinx evaluation board which I am using to debug the Ethernet portion of our project. I attempted to cannibalize the example but have so far been unsuccessful. Currently, the communication needs to only be one way. Currently, I am trying to see the data being sent with netcat. I also have wireshark open and am seeing the system get stuck repeatedly asking:
2217 1323.697811000 Xilinx_00:01:02 Broadcast
ARP 60 Who has 192.168.1.11? Tell 192.168.1.10
I can see the Host computer reply with:
2217 1323.697811000 Xilinx_00:01:02 Broadcast
ARP 60 Who has 192.168.1.11? Tell 192.168.1.10
I feel like I have some issues with the configuration but cannot figure out how what it is. I think it might have something to do with a not having a recv handler set but I am not sure.
Below is the code I am using. lwip_init() is mimicking the call from the examples provided by Xilinx.
/*
* main.c
*
* Created on: Sep 24, 2013
* Author: Ian
*/
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include "lwip/init.h"
#include "xparameters.h"
#include "netif/xadapter.h"
#include "xenv_standalone.h"
#include "platform_config.h"
#include "xparameters.h"
#include "xintc.h"
#include "xil_exception.h"
#include "mb_interface.h"
#include "xtmrctr_l.h"
#include "lwip/udp.h"
#include "lwipopts.h"
#include "xil_printf.h"
struct ip_addr ipaddr, ipaddr_remote, netmask, gw;
void udp_test(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
void print_ip(char *msg, struct ip_addr *ip)
{
print(msg);
xil_printf("%d.%d.%d.%d\r\n", ip4_addr1(ip), ip4_addr2(ip),
ip4_addr3(ip), ip4_addr4(ip));
}
void print_ip_settings(struct ip_addr *ip, struct ip_addr *mask, struct ip_addr *gw)
{
print_ip("Board IP: ", ip);
print_ip("Netmask : ", mask);
print_ip("Gateway : ", gw);
}
int main()
{
err_t error;
struct netif *netif, server_netif;
struct udp_pcb *udp_1;
struct pbuf *p;
char data[8] = "01234567";
u16_t Port;
Port = 69;
int count = 0;
int n = 0;
int buflen = 8;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
netif = &server_netif;
xil_printf("\r\n\r\n");
xil_printf("-----lwIP RAW Application ------\r\n");
/* initliaze IP addresses to be used */
IP4_ADDR(&ipaddr_remote, 192, 168, 1, 11);
IP4_ADDR(&ipaddr, 192, 168, 1, 10);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 1, 1);
print_ip_settings(&ipaddr, &netmask, &gw);
lwip_init();
if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
xil_printf("Error adding N/W interface\r\n");
return -1;
}
netif_set_default(netif);
netif_set_up(netif);
Xil_ExceptionEnable(); //Setup complete start interrupts
udp_1 = udp_new();
error = udp_bind(udp_1, IP_ADDR_ANY, Port);
if (error != 0)
{
xil_printf("Failed %d\r\n", error);
}
else if (error == 0)
{
xil_printf("Success\r\n");
}
error = udp_connect(udp_1, &ipaddr_remote, Port);
if (error != 0)
{
xil_printf("Failed %d\r\n", error);
}
else if (error == 0)
{
xil_printf("Success\r\n");
}
while(1)
{
count++;
xemacif_input(netif);
if (count == 100000)
{
p = pbuf_alloc(PBUF_TRANSPORT, buflen, PBUF_POOL);
if (!p) {
xil_printf("error allocating pbuf\r\n");
return ERR_MEM;
}
memcpy(p->payload, data, buflen);
udp_send(udp_1, p);
xil_printf("SEND\r\n");
count = 0;
pbuf_free(p);
}
}
data[1] = '2';
}
Ok, so basically here is what I found.
The Xilinx xapp1026 had issues with the sp605_AxiEth_32kb_Cache project when I used it. It was hanging at the start interrupts. I was not able to diagnose the project BUT I switched to the sp605_EthernetLite_32kb_Cache example project. I can only assume that the failure of the MicroBlaze interrupts to initialize caused the ARP to fail to get added and forced the system into the loop repeatedly. It is still unclear why the interrupt failed to initialize in the AxiEth example.
Once here I was able to get a program to work by stripping down the provided system and using the following code:
/*
* Copyright (c) 2007 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <stdio.h>
#include <string.h>
#include "lwip/udp.h"
#include "xparameters.h"
#include "netif/xadapter.h"
#include "platform.h"
#include "platform_config.h"
#include "lwipopts.h"
#ifndef __PPC__
#include "xil_printf.h"
#endif
void print_headers();
int start_applications();
int transfer_data();
void platform_enable_interrupts();
void lwip_init(void);
void tcp_fasttmr(void);
void tcp_slowtmr(void);
#if LWIP_DHCP==1
extern volatile int dhcp_timoutcntr;
err_t dhcp_start(struct netif *netif);
#endif
extern volatile int TxPerfConnMonCntr;
extern volatile int TcpFastTmrFlag;
extern volatile int TcpSlowTmrFlag;
void print_ip(char *msg, struct ip_addr *ip)
{
print(msg);
xil_printf("%d.%d.%d.%d\r\n", ip4_addr1(ip), ip4_addr2(ip),
ip4_addr3(ip), ip4_addr4(ip));
}
void print_ip_settings(struct ip_addr *ip, struct ip_addr *mask, struct ip_addr *gw)
{
print_ip("Board IP: ", ip);
print_ip("Netmask : ", mask);
print_ip("Gateway : ", gw);
}
int main()
{
struct netif *netif, server_netif;
struct ip_addr ipaddr, netmask, gw;
// Added stuff for the creation of a basic UDP
err_t error;
struct ip_addr ip_remote;
struct udp_pcb *udp_1;
struct pbuf *p;
char data[8] = "01234567";
u16_t Port = 12;
int buflen = 8;
int count = 0;
/* the mac address of the board. this should be unique per board */
unsigned char mac_ethernet_address[] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
netif = &server_netif;
if (init_platform() < 0) {
xil_printf("ERROR initializing platform.\r\n");
return -1;
}
xil_printf("\r\n\r\n");
xil_printf("-----lwIP RAW Mode Demo Application ------\r\n");
/* initliaze IP addresses to be used */
#if (LWIP_DHCP==0)
IP4_ADDR(&ipaddr, 192, 168, 1, 10);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 1, 1);
print_ip_settings(&ipaddr, &netmask, &gw);
#endif
lwip_init();
#if (LWIP_DHCP==1)
ipaddr.addr = 0;
gw.addr = 0;
netmask.addr = 0;
#endif
/* Add network interface to the netif_list, and set it as default */
if (!xemac_add(netif, &ipaddr, &netmask, &gw, mac_ethernet_address, PLATFORM_EMAC_BASEADDR)) {
xil_printf("Error adding N/W interface\r\n");
return -1;
}
netif_set_default(netif);
/* specify that the network if is up */
netif_set_up(netif);
/* now enable interrupts */
platform_enable_interrupts();
#if (LWIP_DHCP==1)
/* Create a new DHCP client for this interface.
* Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
* the predefined regular intervals after starting the client.
*/
dhcp_start(netif);
dhcp_timoutcntr = 24;
TxPerfConnMonCntr = 0;
while(((netif->ip_addr.addr) == 0) && (dhcp_timoutcntr > 0)) {
xemacif_input(netif);
if (TcpFastTmrFlag) {
tcp_fasttmr();
TcpFastTmrFlag = 0;
}
if (TcpSlowTmrFlag) {
tcp_slowtmr();
TcpSlowTmrFlag = 0;
}
}
if (dhcp_timoutcntr <= 0) {
if ((netif->ip_addr.addr) == 0) {
xil_printf("DHCP Timeout\r\n");
xil_printf("Configuring default IP of 192.168.1.10\r\n");
IP4_ADDR(&(netif->ip_addr), 192, 168, 1, 10);
IP4_ADDR(&(netif->netmask), 255, 255, 255, 0);
IP4_ADDR(&(netif->gw), 192, 168, 1, 1);
}
}
/* receive and process packets */
print_ip_settings(&(netif->ip_addr), &(netif->netmask), &(netif->gw));
#endif
/* start the application (web server, rxtest, txtest, etc..) */
xil_printf("Setup Done");
IP4_ADDR(&ip_remote, 192, 168, 1, 11);
udp_1 = udp_new();
error = udp_bind(udp_1, IP_ADDR_ANY, Port);
if (error != 0)
{
xil_printf("Failed %d\r\n", error);
}
else if (error == 0)
{
xil_printf("Success\r\n");
}
error = udp_connect(udp_1, &ip_remote, Port);
if (error != 0)
{
xil_printf("Failed %d\r\n", error);
}
else if (error == 0)
{
xil_printf("Success\r\n");
}
while (1)
{
xemacif_input(netif);
count++;
if (count == 80000)
{
p = pbuf_alloc(PBUF_TRANSPORT, buflen, PBUF_POOL);
if (!p) {
xil_printf("error allocating pbuf\r\n");
return ERR_MEM;
}
memcpy(p->payload, data, buflen);
udp_send(udp_1, p);
xil_printf("SEND\r\n");
count = 0;
pbuf_free(p);
}
}
/* never reached */
cleanup_platform();
return 0;
}
----Edit ----
So you know how people figure it out then don't leave an answer. Well here was my problem with the orginal code (I think..) the line of code xemacif_input(netif); gives the Ethernet the ability to process the arp call without it the FPGA will sending out the ARP and then not receiving it will ask repeatedly.
The previous code does appear to have the correct line of code in it. So it might have been a mistake in how the interrupts were configured.
I got this example working and implemented it in my project. If you have questions about this please ask and I will try and give the best answers I can.

simple linux device driver open call crash

I am trying to learn how to write a device driver in linux, following some reference from google and ldd3. i am able to insert the module below but when i tried to open the device in an application the kernel crashed.
The code and build steps followed as below :
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <linux/fs.h>
/* =============== Constant Definitions ============ */
#define SERIAL_IRQ 4
/* =============== Variable Definitions ============ */
static int SER_MAJOR = 0;
int ser_open(struct inode *inode, struct file *filp);
int ser_release(struct inode *inode, struct file *filp);
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var)
{
printk("\n\n ------- INTR raised -----------\n\n");
return 0;
}
int ser_open(struct inode *inode, struct file *filp)
{
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL))
{
printk("\n interrupt req failed\n");
}
else
{
enable_irq(SERIAL_IRQ);
printk("\n!!!! ..obtained the requested interrupt and enabled\n");
}
}
int ser_release(struct inode *inode, struct file *filp)
{
disable_irq(SERIAL_IRQ);
free_irq(SERIAL_IRQ,NULL) ;
}
static struct file_operations ser_fops = {
open: ser_open,
release: ser_release
};
void *p = NULL;
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *);
static int __init hello_start(void)
{
int ret_val=-1;
int result;
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops);
if(result < 0)
{
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR);
return result;
}
if(SER_MAJOR == 0)
{
SER_MAJOR = result;
printk("SER DEV Major Number : %d",SER_MAJOR );
}
return 0;
}
static void __exit hello_end(void)
{
// free_irq(SERIAL_IRQ,NULL);
//release_region(0x0031,1);
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile for module :
obj-m := hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The application used for accesing is as follows :
#include <stdio.h> /* test.c */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int dev;
int main(void)
{
char buff[40];
dev = open("/dev/my_ser_dev",O_RDONLY);
if(dev < 0)
{
printf( "Device Open ERROR!\n");
exit(1);
}
printf("Please push the GPIO_16 port!\n");
//read(dev,buff,40);
// scanf("%s",buff);
printf("%s\n",buff);
close(dev);
return 0;
}
insmod gave
[ 3837.312140] Loading hello module...
[ 3837.312147] Hello world
[ 3837.312218] SER DEV Major Number : 251
Then I created the special file using mknod /dev/my_ser_dev c 251 0
Executing the application caused kernel crash. I am using UBUNTU 3.2.0-23-generic-pae.
The function you are registering as your IRQ handler has the wrong prototype - it should be like
irqreturn_t irq_handler(int, void *);
Maybe you are referring to old documentation.