This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RAM code solution and troubles

Mapping externe:
Code:EPROM 00000--01FFF
Code:RAM 12000--1FFFF
Data:RAM 02000--0F6FF

External logic manage the A16 line of RAM chip:
- A16=1 on falling edge of ALE
- A16=0 when RD or WR = 0

My code is stored in 2 I2C eeprom. The Boot code download it in upper RAM (A16 force to 1), then goes in automatic mode described before.

Every things seams ok (sumckeck test works...) BUT I have a very strange behaviour: one program (A prog) works and another one (B prog) doesn't work. The only difference between them is local variable of a function. The A prog has int myVar; and the B has int idata myVar;

My target is a C505CA from infineon and I use the small model. My internal ramsize is 256. I have check in detail the both M51 file the overlay of memory. It seams to be ok.

To be sure that A prog works correctly I need to check two things:
1) my hardware solution
2) why the affectation of idata in local variable generates troubles

  • Your symptoms could be caused by a stack overflow. Have you check for that?

  • gouezel yann wrote:
    one program (A prog) works

    and then:
    To be sure that A prog works correctly

    But you originally said the it's Prog A which does work!
    So which is it?
    Prog A: int myVar - works;
    Prog B: int idata myVar - fails?

    I have check in detail the both M51 file the overlay of memory. It seams to be ok
    Your problem does sound like an Overlay problem.

    Situations like yours (bootloader) often use "Clever Tricks" for things like the transfer of control from the loader to the application.
    The linker may not be able to determine that there is effectively a "call" involved, so may overlay things which shouldn't be overlayed.
    Might be worth checking for such problems?
    If this is the root of your problem, you will need to consult the App Notes & Knowledge base articles on the use of Function Pointers (which can lead to such problems).

  • I check all the time a pattern written at the top of stack and if there is any problem I display a message on terminal
    But I never see that...

  • Prog A: int myVar - works;
    Prog B: int idata myVar - fails;

    In fact I not sure that A prog works correctly... The B prog fails immediatly and the A prog seems to be work, but there some strange troubles sometimes...

    When my applicative program starts and runs, it don't need any data from the boot program.

    I don't use any interrupt in boot program but I use 3 IT in applicative one. My applicative program is compiled with the NOIV derective. The vector process is written in assembler. for each vector the treatment is:

    ORG 002Bh ; vector 5
    PUSH it5addr+1
    PUSH it5addr+0
    RET

    itNaddr is a word in data memory in a fixed memory address. Before enable interrupt, the address of routine interrupts are copy in itNaddr variables.

    Note that my code use bank register0, and each interrupt use other bank resiter 1,2and3. (all local variable of interrupt routines use register, never data memory)

    Do you understand more my trouble or not with these precisions?

  • My applicative program is compiled with the NOIV derective. The vector process is written in assembler.

    Is there any particular reason why you do this?
    Why not just let the Compiler take care of it?

    ORG 002Bh ; vector 5
    PUSH it5addr+1
    PUSH it5addr+0
    RET
    I hope you've remembered to use a RETI (not RET) at the end of your Service Routine(s)...

    itNaddr is a word in data memory in a fixed memory address
    Have you taken care to ensure that the Linker is not putting anything else in those locations?

    Note that my code use bank register0, and each interrupt use other bank resiter 1, 2, and 3.
    Don't forget that the Register Banks occupy the bottom 32 bytes of Data memory - are your itNaddr words clear of these?

  • My applicative program is compiled with the NOIV derective. The vector process is written in assembler.

    Is there any particular reason why you do this? Why not just let the Compiler take care of it? -> 1st to be not dependant of interrupt address in my applicative program (applicative be downloaded by the CAN bus), 2nd to be able may be to use interrupt one day in boot program. With this solution I can use the same fix cod for interrupt in EPROM for my evolutive downloaded applicative code.


    ORG 002Bh ; vector 5
    PUSH it5addr+1
    PUSH it5addr+0
    RET
    I hope you've remembered to use a RETI (not RET) at the end of your Service Routine(s)... -> interrupt routine is written in C with the keyword interrupt. I checked the assembler, and the RTI is used.

    itNaddr is a word in data memory in a fixed memory address. Have you taken care to ensure that the Linker is not putting anything else in those locations? Note that my code use bank register0, and each interrupt use other bank resiter 1, 2, and 3. Don't forget that the Register Banks occupy the bottom 32 bytes of Data memory - are your itNaddr words clear of these?
    -> itNaddr is fixed from address 30H. In M51 linker generated file, I can check the ABSOLUTE segment from address 30H

  • Mapping externe:
    Code:EPROM 00000--01FFF
    Code:RAM 12000--1FFFF
    Data:RAM 02000--0F6FF

    External logic manage the A16 line of RAM chip:
    - A16=1 on falling edge of ALE
    - A16=0 when RD or WR = 0
    ------
    | |
    1 -----------|D Q|------A16
    ALE --------o|CLK |
    | |
    WR or RD ---O|CLR |
    -----

    My EPROM version (A16=0) works very well.

    My download version (boot program copy in upper RAM the applicative code stored in E2PROM) have some strange behaviour. Boot program is from 0 to 1fffH, applicative from 2000H to ffffH.

    Note that the code is compiled to set START entry point at 2000h in both case. It is exactly the same code (same sumcheck, same lenght)!


  • see also "precesion" item added to my main post

  • see also "precesion" item added to my main post

  • See "Tips for Posting Messages".

    You need to use < pre > & < /pre >.

                 ------
                 |    |
    1 -----------|D Q |------A16
    ALE --------o|CLK |
                 |    |
    WR or RD ---O|CLR |
                 -----
    

    With this scheme, the RAM will see the WR strobe before the A16 is valid.

  • Using WR to control A16 causes A16 to go low after WR goes low on the RAM chip, and that will violate the address setup to falling WR timing requirement of the RAM chip. It may work, but I wouldn't do this.

    Maybe you could do it the other way around, where a data access is assumed unless PSEN goes low. In other words, use PSEN to control A16. During bootload A16 will have to be forced to 0. Remember that you can't access any C variables in the usual data portion of this RAM chip during your bootload. The only problem here is that you may need a faster RAM chip, because the address will not be stable until PSEN goes low plus your logic delay.

  • If you have ALE available, you can use a RS flip flop.

    Where:
    Q = A16
    R = ALE and /PSEN
    S = ALE and not /PSEN

    This will set the address line valid at the beginning of the cycle.

  • I use C505CA, 12MHz and RAM 70ns
    The WR pulse minimum time is 250ns with our RAM of 70ns, so what happens if address lines change during the WR pulse which is very large?

  • if we use PSEN as A16, the A16 line will change during the PSEN pulse when reading program code. What happens?

  • I don't understand because ALE and not PSEN/ are never true. Could you precize?