5
\$\begingroup\$

I'm currently having a bad time trying to use an external RAM chip (512 kB) with a PIC18F8720 and the Microchip XC8 compiler (v1.35, PRO mode).

Whenever I try to write some code to modify a variable in the external memory, the linker throws an error (712): "can't generate code for this expression". This doesn't happen when reading far variables: only when writing into them.

This error is reproducible, even in this small example program:

#include <xc.h>
#include <stdio.h>

far int intArray[10];
far int intVariable;

void main(void) {
    intVariable = 2; // --> ERROR 712
    intArray[1] = 3; // --> ERROR 712
    printf("%d\n", intVariable);
    printf("%d\n", intArray[0]);
}

The compilation+linking commands are generated by MPLAB X v3.20:

"/opt/microchip/xc8/v1.35/bin/xc8" --pass1 --chip=18F8720 -Q -G --double=24 --float=24 --emi=byteselect --ram=default,+20000-9FFFF --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=require --mode=pro -P -N255 --warn=-3 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib,-plib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" -obuild/default/production/main.p1 main.c

"/opt/microchip/xc8/v1.35/bin/xc8" --chip=18F8720 -G -mdist/default/production/Test01.X.production.map --double=24 --float=24 --emi=byteselect --ram=default,+20000-9FFFF --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=require --mode=pro -P -N255 --warn=-3 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,-download,+config,+clib,-plib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto:auto "--errformat=%f:%l: error: (%n) %s" "--warnformat=%f:%l: warning: (%n) %s" "--msgformat=%f:%l: advisory: (%n) %s" --memorysummary dist/default/production/memoryfile.xml -odist/default/production/Test01.X.production.elf build/default/production/main.p1

Compilation output:

main.c:9: error: (712) can't generate code for this expression
main.c:10: error: (712) can't generate code for this expression
Microchip MPLAB XC8 C Compiler (PRO Mode) V1.35
Build date: Jul 7 2015
Part Support Version: 1.35
Copyright (C) 2015 Microchip Technology Inc.
License type: Node Configuration

What am I doing wrong? The compiler output doesn't help much, as the error is way too generic to give any clue.

\$\endgroup\$
  • \$\begingroup\$ If I quickly look at the datasheet, the external memory is not integrated into the device SRAM bus. Instead it must be accessed via tblrd and tblwr instructions. I am not sure how to do this with XC8, but I saw the addition of "rom" for an older compiler. Normally tblrd is used to access FLASH. \$\endgroup\$ – Hans Jan 20 '16 at 11:49
  • \$\begingroup\$ try replacing far with __far \$\endgroup\$ – Icy Jan 20 '16 at 11:55
  • \$\begingroup\$ Thanks, but using "__far" yields same results. \$\endgroup\$ – equalizer Jan 20 '16 at 13:23
  • 1
    \$\begingroup\$ I would recommend asking microchip. they have a support case system for that stuff here: microchip.com/support/hottopics.aspx (you have to register a microchip direct account first). \$\endgroup\$ – jwsc Feb 2 '16 at 12:18
3
+50
\$\begingroup\$

I was just having a play around with this and it seems like something you should report to Microchip but I have found a workaround that might be useful in the interim. The problem only seems to occur with multi-byte variables outside an array or when trying to access the first element of an array. The following code compiles OK and seems to generate plausible assembler output although I didn't have a chip with external RAM to test:

#include <xc.h>
#include <stdio.h>
#include <stdint.h>

far uint8_t intVariable;
far int intArray[1000];

void main(void) {
    intVariable = 1;
//    intArray[0] = 3; <<- Causes an error
    intArray[1] = 3;
    intArray[999] = 3;
    printf("%d\n", intVariable);
    printf("%d\n", intArray[1]);
}

I suspect based on that it tries to perform some optimization on writing to a multi-byte variable that falls down, but when inside an array it generates the full code to calculate the offset that seems to work OK. Note that I only have the free compiler so the pro edition may optimize out the constant array access, but I'd imagine changing the index to a variable would fix that if it does happen.

When I compared my compiler / linker options to yours under the XC8 compiler optimizations I also had to enable "Instruction Invariant Mode" for it to work. Hopefully that might get you up and running and it might be a good additional test case to submit to Microchip.

\$\endgroup\$
  • \$\begingroup\$ Thanks, but how did you manage to compile that code? My compiler keeps saying "error 712" at lines 11 and 12 of your code (both in Free and PRO modes). However, it is true what you say about single-byte variables and arrays: the do always work fine. The problem arises when using multi-byte ones. \$\endgroup\$ – equalizer Feb 3 '16 at 13:48
  • \$\begingroup\$ @equalizer just compared compiler options and I had "Instruction Invariant Mode" enabled as updated above, I forgot I'd enabled that and just tried with it disabled and got the same error as above. \$\endgroup\$ – PeterJ Feb 3 '16 at 14:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.