2

I am using Codewarrior 8.3 (IDE version 5.9) to program a 56f8367 DSC.

I am using respected third party software, so I imagine that they know what they are doing and don't want to mess with their code too much, but they are playing around with passing void * parameters and it is something I am not totally familiar with.

So I have this function:

static void T_CALLBACK _transmit(
  void *pContext,
  TX_DATA *pTxDescriptor)
{
  CONTEXT *pLinkContext = (CONTEXT *)pContext;
  ...
}

which is being called through a function pointer. When I stop the processor just before this function call, I can see the address pointed to by pContext is 0x1000, but after it is cast here, the address pointed to by pLinkContext is 0x0800. This, obviously causes problems because we start writing and reading from a different part of memory.

There is something weird going on with the byte addressing/alignment where it is getting "shifted" over 1 bit. I see what is going wrong, I just don't understand why or, more importantly, how to solve the problem.

What should I be looking for?

(Editing to add the call per comment request) - although, I'm not sure how much it will help considering everything is buried in structures and is being called through a function pointer. I can say that "pTprtContext->tmw.pChannel->pLinkContext" is of a different type than CONTEXT, pLinkContext does match up with the beginning of CONTEXT, so I think they are just trying to insert it in there.

static void T_LOCAL _transmitNextFrame(
  D_CONTEXT *pTprtContext)
{
  ...
  /* Transmit frame */
  pTprtContext->t.pChannel->pLink->pLinkTransmit(
    pTprtContext->t.pChannel->pLinkContext, &pTprtContext->linkTxDescriptor);
}
EatATaco
  • 687
  • 7
  • 25
  • 3
    What you describe seems impossible. – David Heffernan Apr 08 '13 at 20:57
  • Could you show us the code that calls `_transmit`? – jwodder Apr 08 '13 at 20:58
  • 3
    What do you mean you stop "just before" the function call? "Just before" the function call `pContext` doesn't exist. – Nik Bougalis Apr 08 '13 at 20:58
  • When you stop the processor and look at variables in memory, byte wide variables look like they have one more bit of addressing than the rest (the processor itself is a 16 bit architecture). When I say "just before" I mean when the function is called and I am looking at the variable passed to pContext. Editing to add the call right now. – EatATaco Apr 08 '13 at 21:00
  • 4
    Once upon a long time ago, in a land far away (before there were `void *` types in the C I was using — that long ago!), I worked on a machine where the `char *` version of an address was a different number altogether from the `anything_else *` version of the same address. I almost hesitate to mention this, but if the DSC is word-addressed (as the machine I worked on was word-addressed), and the words are 2 bytes each, then the switch between the pointer types might be valid. Do I rate this as likely — no, not in the least. It is very much an outside chance. But maybe, just maybe... – Jonathan Leffler Apr 08 '13 at 21:12
  • What type is `pTprtContext->t.pChannel->pLinkContext`? And how is it assigned? – D Krueger Apr 08 '13 at 21:46
  • @Leffler, you are entirely correct. That does happen in compiler/processor. You get an extra bit for char to indicate high/low byte. And I do think this has something to do with it, I'm just not sure how to fix it. I wondering if there is some terminology that I don't know, or a compiler switch for this that I have not heard of. Krueger The type of pLinkContext is a structure. It matches the beginning of CONTEXT, and includes the part that is calling the function that is creating the problem. So the casting should work, it is just that the addressing is off. – EatATaco Apr 09 '13 at 14:20
  • @EatATaco You may want to check J. Leffler's supposition that "the switch between the pointer types might be valid." Have you verified that the CONTEXT object is being read at a different address than it was written. Could that actually be working correctly and the error you are trying to track down lies elsewhere? – D Krueger Apr 09 '13 at 16:09
  • @DKrueger I'm absolutely positive that it is pointing to the wrong address. If I stop right before the function call and do a "view memory" it brings me to the address 0x1558 and I can see the data lining up in the structure. If I stop right after it is cast to the local variable in the function and do a "view memory" it brings me to 0x0AAC and I can see the wrong data lining up in the structure. – EatATaco Apr 09 '13 at 17:08
  • @EatATaco Why isn't there an ampersand before `pTprtContext->t.pChannel->pLinkContext` in the call to `pLinkTransmit`? Aren't you trying to pass the address of that object as the context? Also, does the function type of `pLinkTransmit` take a pointer-to-void or a pointer-to-CONTEXT as the first argument? – D Krueger Apr 09 '13 at 23:34
  • @DKrueger The type of pLinkContext is D_CONTEXT *. I know it is not the same type, but D_CONTEXT is just the first variable of CONTEXT. Also, "pLinkTransmit" is a pointer to the function _transmit. So it takes a pointer-to-void as the first argument. Even if this doesn't solve the problem, I appreciate you helping out so much :) – EatATaco Apr 10 '13 at 00:20
  • I'll keep this question open, but I did a hack fix for now so I can move ahead. I just set void * to CONTEXT *. I got no compiler errors, and I got some basic stuff working, so I'm going to go with it for now. – EatATaco Apr 10 '13 at 16:25

2 Answers2

3

You say "shifted over by 1 byte," but it is actually only one bit, that is, the number is divided by 2.

This is usually the result of using a byte address in one context and a (2-byte) word address in another context. They probably refer to the same address.

Does this help you decipher it?

UncleO
  • 8,299
  • 21
  • 29
  • You are correct, I mean to say shifted by 1 bit, not byte. I have edited it to reflect this change. And I do think the problem is along the lines you are thinking, although it is DEFINITELY treating them as two different addresses. Because when I stop and look at the memory, I can see where they are both pointing. Normally, byte address 0x00010 is the same as word address 0x0001. . .and, I think this is where the problem is arising. I'm just not sure why it passes it as a byte/word address and then interprets it as a word/byte address. – EatATaco Apr 09 '13 at 14:15
1

I use CodeWarrior compiler for an HC12 family's 16-bit microcontroller. With this compiler, I can choose a few memory models which change (among other several things) how many bytes pointers are. More specifically, +small+ memory model uses __near 16-bit pointers, whereas +large+ model makes use of __far 24-bit pointers.

If your code is compiled with a different memory model than your third party software's and the compiler does not warn you, I guess you may get wierd result.

lorcap
  • 173
  • 2
  • 8
  • I have their source code, so I am actually compiling their code as well. So I assume they are all using the same memory model that I have in my project settings. Although, I did play around with them to no avail. – EatATaco Apr 10 '13 at 16:26