Jump to content

gbgb

EstablishedMember
  • Content Count

    60
  • Joined

  • Last visited

Everything posted by gbgb

  1. If this can already be done, I did not find any reference to it in the manual. 1. When you build a program that does not use any interrupts, and do not use the "-rb" flag to relocate it, the resulting code starts immediately after the reset entry point, and uses th area that is otherwise reserved for interrupts. Even if using #pragma sentences that try to force data into this area is disregarded. Suggestion - add a flag to tell the linker to start code after the reserved memory space 2. When using the "-rb address" flag the reset/interrupt vector area is left blank. One has to manually place the correct data (using "#pargama DATA" or other method) so that the code is invoked correctly on reset/interrupt. Suggestion - add a sub-flag to the -rb flag that will tell it to automatically add the correct "goto" commands. e.g (for 18F family) - if using -rb 0x300" than the reset entry point of the program is at 0x300, interrupt entry is at 0x308 and low priority interrup entry is at 0x318. Have the linker add a "goto 0x300" at location 0x0000, "goto 0x308" at location 0c0008 and "goto 0x318" at location 0x0018.
  2. Much clearer now. Rough idea for implementation (a bit awkward, I admit): Split the project and have the interperter section as a separate project. Use the linker -rb flag to define the bottom of program memory range when building the iterperter. Static program will be in low memory, interperter in high memory. Use a "goto address" in the program whenever it has to call the iterperter, and another "goto" to return to a known point in the program (probably write a "gateway" function in the program if this interperter is called from several points). When you have to write a new interperter you know where to put it.
  3. Although they both use the same pins, they are a bit different. I have them in two separate modules (I do not use the boostc bulit in I2C functions) , so probably write your own from scratch. It is not complicated.
  4. I am still on the bootloader project. My bootloader now is designed to reside in low memory. The bootloader itself does not have any interrupt routines. To support the application (that does have interrupt routines) I added in the bootloader code the following: #pragma DATA 0x0008, 0x84, 0xEF, 0x01, 0xF0 This is a "goto 0x308" command that should be in memory location 0x0008. The application itself is built with "-rb 0x300" flag. This means that the application statrts at 0x300, and it's interrupt entry point is located at 0x308. Every time there is an interrupt, the interrupt entry point at 0x0008 is invoked and this jumps to the correct location. However, when I build the bootloader (no linker flags at all) it uses the memory area that is otherwise allocated for interrupts and my #pragma command is disregarded. I could not find any linker flag that would specify that the application should start at memory 0x0000, but not write over the interrupt entry points. I guess I could also use the "-rb" flag to shift the location of the bootloader (e.g - have it satrt at addrress 0x0020, past the low priority interrupt entry point), and using a #pragma DATA build the reset vector to it (same as I did for the interrupt vector), but is there a simpler way?
  5. I don't htink it is a matter of this compiler/language or another, but rather the design philosophy of the program. I am sure there are many ways to implement this requirement. Most simply use the first bytes as an identifier to what follows. example: <stx><command><address><length><data>..........<data><cs> <stx> - one or two bytes that identify that this is a new "packet" (I like to use valuse that have alternating bits - eg A5, AA55, A5A5) <command> - a byte identifying if this is an interperter program or a mini program (or any extended set of commands as you need) <address> - optional, in case the address where the data is to be loaded is variable and not hard coded <length> - optional, in case the length of the interperter or the programs is variable andnot not hard coded <cs> - some kind of checksum or crc to make sure that the whole packet came through OK. You could use the Intel hex format (as used by most programmers) or the Modbus protocol as a basis and modify it for your needs (using known protocols simply gives you access to some available code as a basis for your ideas). As in bootloders you can also decide whether all the "processing" is done on the PIC side (so on the PC side you simply use a terminal program) or you do most of the processing on the PC side and the PIC side does not know what it does but simply given bytes and told to place them at a certain memory location. Another option - exactly like a bootloader and application - the interperting application and the reloader are totaly separate programs (you also manage them as two separate projects). Something - a hardware/software reset or, a command causes the reloader to be invoked. If within a certain time it receives a new interperter to load it does so, otherwise it jumps back to the interperter starting address. All the above can be implemted in C/Basic/Asm etc..
  6. If you use the ICD for debugging then MPLAB is the way to go. If you only use a programmer than probably the BoostC IDE is preferable. One limitation with MPLAB/BoostC interface is that MPLAB will alway compile/link your project from scratch and this is annoying with large projects. I typically use BoostC to the stage that I eliminate all comipling errors and then switch to MPLAB. I go through this cycle every time I add substantial code to the project.
  7. Thanks for both. Reading the fine print it is understood that one must write in 64 bytes boundaries. Misunderstanding may happen due to the fact that the various bits of TBLPTR point to different entities in erase/write operations. While bits 0-5 of TBLPTR point to the program memory holding registers, bits 6-21 point to the memory space. This is briefly mentioned in the section that covers the TBLPTR (and ends with "for details see section - writing to flash program memory"). When describing in detail the write operation this is not mentioned at all and the only "warning" given is that code must be aligned to even bytes. I do not like the idea of the application "stepping over" the boot vector area because any problem during this operation, or corrupt data, will leave you with a dead PIC. I guess I will opt for remapping the application and having the bootloader at low memory.
  8. Although this is not specifically related to BoostC but rather to the PIC itself, I hope somebody here can provide the answer. I am writing a bootloader and having some trouble with writing the application into the memory. The PIC is 18F6527 (18F8772 family). The bootloader itself resides in the top of the eeprom (using the -rb flag) with only the two boot vector bytes at 0000 having a GOTO instruction to invoke it on reset. The intention is that the application will not be remapped and will reside at the bottom of the memory (i.e - excluding the two boot vector bytes it will effectively start at location 0004). Note: - In the programming area of this site there is a bootloader for the 16F family following this concept. According to the PIC datasheet, you can only prgram 64 bytes at a time. As long as I program the application to a location statrting at address greater than 64 it seems to be programmed OK, but if I try to program it to starting at address 0004 nothing is programmed, and it also erases the two bytes at location 0000. Except for writing in 64 bytes blocks, do you also have to write at address starting on 64 bytes boundries? How would one program the application into the lowest memory range? Or - must I relocate the application to higher memory and have the bootloader reside in the bottom of the memory?
  9. Found it - did not operate the ICD correctly and therfore did not read the true contents of the program memory after running the program. The code seems to be OK.
  10. I wrote a stripped down program. All it should do is write test data (values 0-63) into 64 bytes starting at address 0x300 (the program itself is well below 0x100). I use the ICD2 as a programmer only and to look into the memory. As in your code I do not do an erase, since I know the memory is FF. It does not work! What am I missing? Configuration bits? Improper operation of ICD2? ???? #include <system.h> #include "pic.h" // Set the PIC configurion registers #pragma DATA _CONFIG1H, _OSC_HS_1H // hightspeed crystal oscilator #pragma DATA _CONFIG2L, _PWRT_OFF_2L // Turn PWRT (PoWer-up Reset Timer) off #pragma DATA _CONFIG2H, _WDT_OFF_2H // watchdog timer off void main( ) { unsigned char buffer[64]; //memory write operations are done as 64 byte blocks unsigned char i; //Initialize Serial Port 1 rTXSTA1 = 0X24; //ENABLE TX, BRGH=1 rRCSTA1 = 0X90; //ENABLE SPORT, ENABLE RX rSPBRG1 = 129; //9600 Baud @ 20Mhz //Send Prompt to indicate Start. while( ( rTXSTA1 & 0x02 ) == 0 ); rTXREG1 = '>'; //build some test data for (i=0; i<64; i++) buffer[i]=i; //write to flash 64 bytes starting at 0x0000300 tblptru = 0x00; tblptrh = 0x03; tblptrl = 0x00; //read data into TABLAT, modify and write back for (i=0; i<64; i++) { asm tblrd* tablat &= buffer[i]; asm tblwt*+ } asm tblrd*- //dummy read - backup into the correct block //program block bEEPGD = 1; //point to flash program memory bCFGS = 0; //access program memory bWREN = 1; //enable write to memory bGIE = 0; //disable interrupts //required write sequence eecon2 = 0x55; eecon2 = 0xaa; bWR = 1; //bWR is reset by the internal programming timer bGIE=1; //enable interrupts ///end of write sequence //keep the program here after the writing is complete while(1) { while( ( rTXSTA1 & 0x02 ) == 0 ); rTXREG1 = '!'; } }
  11. Now I am a bit confused. Looking into the datasheets this family is identical to the one I use (regarding flash program memory) with the only difference is that the minimum writing block is 32 bytes vs. 64. The relevant chapter is identical almost word by word and the asm examples that are provided are identical and show a read-modify-erase-write-program sequence. Therefore I do not understand how you can get away without the erasing procedure. Do you use your bootloader on chips where the program area is known to be blank? After programming once you get arbitrary bit combinations that may require a switch from 0 to 1 on the next program load. GB
  12. Thanks, I will try it out. Looking again into the datasheet I see that although it is not mentioned in the descripption of the programming sequence, there is a tblrd in the code example that is supplied. I understand from your code that your PIC does not require an erase before the write operation (what PIC do you use - maybe I could compare the two and see where I went wrong).
  13. It seems that when using the ICD2 as a debugger program flas cannot be accessed, however even when working with it as a programmer only this does not work. I used the #pragma DATA to load some data into a section of memory that I know I should erase, but this did not work.
  14. I am writing a bootloader for the 18F6527 (18F8722 family). The firmware is nothing special since most work is done on the host PC which feeds it 64 bytes at a time and indicates the starting address for these bytes. It seems that my flash writing procedure is not working, although I think I followed the sequence as described in the Microchip datasheet. The code is below. 1. I am using the ICD2 for debugging - is it possible that the ICD blocks access to the program flash when in debugger mode? 2. I tried erasing only (quoted out the writing section) but this does not work either. 3. most variables are self explenatory. buffer[] holds the program data and addr_x are the 3 bytes for the starting address. Does anybody see something wrong in this function? Thanks, GB void WriteFlash(void) { unsigned char i=0; //load begin address rTBLPTRU = addr_u; rTBLPTRH = addr_h; rTBLPTRL = addr_l; //erase the row bEEPGD = 1; //point to flash program memory bCFGS = 0; //access program memory bWREN = 1; //enable write to memory bFREE = 1; //enable erase bGIE = 0; //disable interrupts //required write sequence rEECON2 = 0x55; rEECON2 = 0xAA; bWR = 1; nop(); bWR = 0; bGIE=1; //enable interrupts //read data into TABLAT for (i=0; i<64; i++) { rTABLAT = buffer[i]; asm tblwt+* } //program row bEEPGD = 1; //point to flash program memory bCFGS = 0; //access program memory bWREN = 1; //enable write to memory bGIE = 0; //disable interrupts //required write sequence rEECON2 = 0x55; rEECON2 = 0xAA; bWR = 1; nop(); bWR = 0; bGIE=1; //enable interrupts return; }
  15. The reply is a bit cryptic, but I understand from it that you can not use the GOTO stement to jump to a specific address and I must do it by altering the value of the PC (as in chips that do not support the GOTO staement). Correct?
  16. Well, the problem seems to be something with ICD2 working in debugger mode. Once I switched to programmer mode everything works. However I am still a bit puzzled - the first two bytes in memory are filled with FEBC FF00 I can not find how this causes a jump to BC00 to start the program - this does not translate to any valid command. Any explanations to this?
  17. BE72 is actually the correct address (originally the GOTO pointed to 0x272. 0x272 + 0xBC00 = 0xBE72), however, it seems that the end part of the main program was simply not loaded to memory (two memory map files and two hex files attached). While the hex files seem ok - both are similar with the ofset file having the appropriate line for my #pragma command. So now the question is "what went wrong with the upload? what happened to the end of my program, why was it not loaded correctly (bothin length and not putting the correct data in location 0 of the memory"? Is this an ICD2 bug? memory_no_offset.TXT memory_with_offset.TXT Bootloader_no_offset_hex.txt Bootloader_with_offset_hex.txt
  18. The PIC18F8722 family supports the assembler command GOTO. However the following inline assembly command generates an error: asm goto 0x1234 seems to me that since goto is also a recognized C command the compiler gets confused and generates this error. A bug, or am I doing something wrong?
  19. I am trying to build a bootloader for a 18F6527. The idea is to have it work in a similar way as EKBoostloader (source is somewhere on this site) and many other bootloaders - it will be in upper memory region, so that the application program is not relocated and resides in lower memory and only the boot vector of the application is relocated. I still did not go into debugging the details, and decided first to make sure that the bootloader can be relocated. When I compile it as a regular application (no switches given to the linker) it seems to work OK (at the moment just sending a prompt to a terminal, timing out after several seconds and reseting to begin the same sequence). I then add the following line: #pragma DATA 0x0000, 0x0EBC, 0x6EFA, 0x0E00, 0x6EF9 which is the equivalent of putting in address 0 the following: movlw 0xBC movwf _pclath movlw 0x00 movwf _pcl and which to my understanding would force a jump to address 0xBC00, where the beginning of the bootloader code is located. and I build it with the linker having "-rb 0xBC00" This does not seem to work. I looked into the memory map (MPLAB IDE). In the first case the first bytes contain a GOTO instruction which points to an address where another GOTO instruction is located and which correctly points to the begining of main(). In the second case I find the following: 1. starting at address 0 I see FEBC FF00 FFFF FFFF ..... (it seems that my #pragma DATA was overwritten with some data which has no meaning). 2. At address BC00 I find the following EF39 F05F - this is as GOTO 0xBE72 and it points to an empty area of the program memory (the bootloader program occupies about 600 bytes from 0xBC00). Any ideas what is going on?
  20. The following function gives the following warning during compilation warning: dereferencing of non pointer. Althoughit is "just" a warning and to this moment I have not found any problems during execution of the code, I would like to know what this means and how (if possible) to avoid it. Basically this code retreives integer type parameters stored in the eeprom and puts them into their relevant structure elements by using a pointer (instead of structure.elemet). The warning is given for the last line in the function void Init(unsigned int * sp) { unsigned char i; unsigned int p_val; unsigned int sp_p; for (i=0; i<SP_NUM; i++) { //retreive the parameter from the EEprom p_val=(unsigned int)(EeRead(SP_OFFSET +i*2))<<8; //load hi byte of value p_val= p_val | (unsigned char)(EeRead(SP_OFFSET +i*2+1)); //load lo byte of value //write the parameter into the structure sp_p = sp + i; * (sp_p) = p_val; } }
  21. Thanks, Have not tested yet but this seems to be the solution. uiptr=&st.a was my missing link (in my trials I provided a pointer to the structure instead of the first element of the structure). My structure is all ints so no problem with jumping around.
  22. I have a structure - e.g typdef struct { unsigned int a; unsigned int b; unsigned int c; etc...... } Structype Structype st; while throughout the code it is very convenient to access the structure elements as st.a, st.b (or st->a, st-> etc., I have a section where I would like to read/write the values of the structure to/from the eeprom, where they are stored sequencially. This would be more conveniently done as a loop like for (i=start, i<end, i++) { x = compute address in eeprom based on value of i and some kind of offset; element i in the structure = read value from eeprom address x ; } I simply cannot figure out the way to implement the left side of this last statement. Obviously if instead of a structure I would have used an array it would be a simple matter, but I am still trying to do it as a structure. All my attempt to do it by supplying the pointer to the structure and performing some kind of arihtmetics to produce a pointer to the correct address failed (failed already during compilation - I could not generate a statement that will be accepted). Any ideas how this would be done?
  23. In this case should'nt it be x=45? OOps, I see youir point - my mistake
×
×
  • Create New...