We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All,
I encountered a strange problem: when stepping over the following line of my code (also highlighted in bold in the code list), the PC goes to DAbt_Handler. I couldn't figure out why. Any help is highly appreciated.
I am using MDK 4.53. RTX is the RTOS being used. The code gives me trouble: fdpMsg->fdpDataLen = 30;
Thanks,
Charles
// FDP.c #include <RTL.H> #include <Net_Config.h> #include <string.h> #include "FDP.h" extern U8 own_hw_adr[]; extern U8 lhost_name[]; extern LOCALM localm[]; /** External function from Ethernet MAC driver It should be threadsafe. */ extern void send_frame (OS_FRAME *frame); typedef struct { U8 dstMacAddr[ETH_ADRLEN]; U8 srcMacAddr[ETH_ADRLEN]; U16 ethType; } ETH_HEADER; typedef struct { ETH_HEADER ethHeader; U8 fdpMsgType; U16 fdpDataLen; U8 data[1]; } FDP_FRAME; enum FDP_MSG_TYPE { REQUEST_IP_INFO = 1, RESPONSE_IP_INFO, CONFIGURE_NEW_IP, MSG_END, }; typedef void (*FDP_MSG_PROC)(void); static void fdpSendIpInfo(void); static void fdpConfigNewIp(void); /* Dummy function for not-need-response message */ static void fdpDummy(void) {}; static const FDP_MSG_PROC fdpMsgProcessor[MSG_END - 1] = { &fdpSendIpInfo, &fdpDummy, &fdpConfigNewIp, }; static U8 fdpBuf[FDP_MAX_FRAME_SIZE]; static BOOL fdpBufEmpty = __TRUE; // Callback function for Ethernet MAC driver BOOL fdpFrameReceived(OS_FRAME *frame) { /* Check the Ethernet frame type */ if ((frame->data[12] == FDP_ETH_TYPE_HIGH) && (frame->data[13] == FDP_ETH_TYPE_LOW)) { if (fdpBufEmpty) memcpy(fdpBuf, frame, (frame->length + 4)); fdpBufEmpty = __FALSE; return __TRUE; } else return __FALSE; } void fdpHandler(void) { OS_FRAME *rxFrame = (OS_FRAME *)fdpBuf; FDP_FRAME *fdpMsg = (FDP_FRAME *)rxFrame->data; if (!fdpBufEmpty && (fdpMsg->fdpMsgType < MSG_END) && (fdpMsg->fdpMsgType > 0) ) (fdpMsgProcessor[fdpMsg->fdpMsgType - 1])(); fdpBufEmpty = __TRUE; } static void fdpSendIpInfo(void) { OS_FRAME *rxFrame = (OS_FRAME *)fdpBuf; FDP_FRAME *fdpMsg = (FDP_FRAME *)rxFrame->data; /* copy source MAC address to destination MAC address */ memcpy(fdpMsg->ethHeader.dstMacAddr, fdpMsg->ethHeader.srcMacAddr, ETH_ADRLEN); /* Copy this machine's MAC address to response frame's source MAC address */ memcpy(fdpMsg->ethHeader.srcMacAddr, own_hw_adr, ETH_ADRLEN); fdpMsg->fdpMsgType = (U8)RESPONSE_IP_INFO; fdpMsg->fdpDataLen = 30; => after this line, the program goes to DAbt_Hnadler memcpy(fdpMsg->data, &localm[NETIF_ETH], 30 /* sizeof(LOCALM) */); /* Ethernet header = 14 bytes, fdpMsgType = 1 byte, fdpDataLen = 2 bytes */ U16 frameLen = 30 /* sizeof(LOCALM) */ + 14 + 1 + 2; if (frameLen < 60) /* Avoid small frame (size less than 64 bytes). send_frame automatically generate CRC (4 bytes) */ rxFrame->length = 60; else rxFrame->length = frameLen; /* Send response */ send_frame(rxFrame); } static void fdpConfigNewIp(void) { }
Forgot to mention that the microcontroller being used is AT91SAM7x256.
Check align of your pointer. You make a 16-bit assign of "fdpDataLen". Is the pointer correctly aligned so the field "fdpDataLen" is correctly aligned?
I didn't follow all your logic, but did the pointer start by pointing to something like?
static U8 fdpBuf[FDP_MAX_FRAME_SIZE];
U8 don't require 16-bit align, but anything typecast to use such a buffer and containing 16-bit or 32-bit fields would expect proper align.
So sometimes better to have
static U32 fdpBuf[(FDP_MAX_FRAME_SIZE+3)/4];
if you want a buffer that have better align in case you then typecast something to it. Or sometimes go all the way to a U64 object for even better align.
Hi Per,
Thank you very much for your help. You're absolutely right. The alignment was the problem. The fdpBuf was assigned with an odd number address, so no wonder it goes into DAbt_Handler.
Thanks again,