How do I determine the locations of the start and end of my code?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How do I determine the locations of the start and end of my code?

3,700 Views
bpaehr
Contributor IV

In Assembler, it was easy to determine the beginning and end of my code.  Since I only had the one source file and I could place a "StartOfCode" label and "EndOfCode" label at the beginning and end of my code, and I could determine the amount of memory used by subtraction.  I need to do this because I want to generate a CRC on only the memory occupied by my code -- not the empty/blank memory locations that follow my code in memory.

 

How do I determine the beginning and end of code programmatically in C?  I'm not sure what other code is added to my code for "Startup", and the linker may place my routines differently than where I may expect them in memory, so trying to place empty functions or simple functions where I think the end of code will be may not always work as I expect.

Labels (1)
0 Kudos
15 Replies

3,260 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi,

I have a demo code that includes __SEG_START_ and __SEG_SIZE_ usage.

see attached. S08_Flash.c


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

3,260 Views
bpaehr
Contributor IV

Jennie:

Thank you for your reply.  I'm quite sure that this will answer my question, however, it appears that you did not attach the "S08_Flash.c" that you mentioned in your reply.  The previous post where you supplied attachments had the attachments just above the "Actions" button.  Your last post has no Attachments in that location.

Thank you for all your help.

Bob

0 Kudos

3,260 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

hi Bob.

the demo is attached.


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

Thank you for the sample code.

I believe I understand how the prefixes work for the "FLASH_ROUTINES" code, where the "__SEG_START_FLASH_ROUTINES" and "__SEG_SIZE_FLASH_ROUTINES" define the beginning and end of the single "Flash_Cmd" function.

But how do I define these prefixes for ALL OF USED MEMORY, especially when my code resides in several different source files?  Can I use a #pragma to define a CODE_SEG over multiple files?

(i.e.: if I put a "#pragma CODE_SEG ALL_FILES" just prior to "main" without declaring any other pragmas, does "ALL_FILES" cover all code generated, to then be able to use "__SEG_START_ALL_FILES" and "__SEG_SIZE_ALL_FILES" in my CRC routine)?

I assume that each #pragma has to have a unique NAME, not that I could place "#pragma CODE_SEG ALL FILES" before EACH function across multiple files so that the compiler concatenates the multiple functions with the same NAME together in a single CODE_SEG.

Bob

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

Thru further investigation, I found part of an answer to a post by you here: https://community.nxp.com/thread/317741

In that post, you mention that "all the source codes and functions are automatically added to segment DEFAULT_ROM unless we use “#pragma CODE_SEG  MY_SECTION” to change it."

So, does this mean that I can use "__SEG_START_DEFAULT_ROM" and "__SEG_SIZE_DEFAULT_ROM" in my CRC routine to solve my problem, or does DEFAULT_ROM refer to the entire available ROM space in the microprocessor, as opposed to only the memory taken by my own code?

Bob

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

I tried using the "DEFAULT_ROM", and this has seemed to work!

I ended up with this for my CRC routine:

extern unsigned char __SEG_START_DEFAULT_ROM[ ];

extern unsigned char __SEG_SIZE_DEFAULT_ROM[ ];

#define StartLocation __SEG_START_DEFAULT_ROM

#define CodeSize __SEG_SIZE_DEFAULT_ROM

unsigned int GenerateCRC(void)

{

      unsigned int crc = 0xFFFF;

      unsigned char *length = CodeSize;

      unsigned char *buffer = StartLocation;

      char j;

      while(length--) {

         crc = crc ^ *buffer++;

          for ( j=0; j < 8; j++) {

               if (crc & 1)

                 crc = (crc >> 1) ^ 0xA051;

               else

                 crc = crc >> 1;

         }

     }

      return crc;

}

The only problem with this is that the StartLocation begins where my own code starts at 0xE092, and does not include the loadByte, Init, and _Startup code, which occupies locations 0xE000 thru 0xE091StartLocation needs to be set to 0xE000, and the CodeSize needs to be adjusted to include the extra memory from 0xE000 to 0xE091, but all calculations I've tried yield errors, probably mostly because I still have not fully grasped what all of the Pointer and Address-Of modifiers do.

How would I change buffer to point to 0xE000, and add the difference between StartLocation and 0xE000 to CodeSize?

Bob

0 Kudos

3,260 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi Bob,

CW for HCS08 has several predefined segments. for example, see my highlight (extract from a prm file):

pastedImage_1.png

here we can see "startup code" and "startup data structures" are defined in segments _PRESTART and STARTUP.

If we this code

extern unsigned char __SEG_START__PRESTART[ ];

extern unsigned char __SEG_SIZE__PRESTART[ ];

 

#define StartLocation __SEG_START__PRESTART

#define CodeSize __SEG_SIZE__PRESTART

we should be able to get StartLocation set as 0xE000


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

Thank you for sticking with me on this.

The "__SEG_START__PRESTART" worked perfectly, getting me to 0xE000.

However, "__SEG_SIZE__PRESTART" only gives me the size of the Preamble section of code that exists before my own code in memory (0x84 bytes), but my own code occupies 0xAD1 bytes.

I need to essentially "add" the values of "__SEG_SIZE__PRESTART" and "__SEG_SIZE_DEFAULT_ROM" for my "length" calculation, but I can't do something like (see error line in red):

extern unsigned char __SEG_START_DEFAULT_ROM[ ];

extern unsigned char __SEG_SIZE_DEFAULT_ROM[ ];

extern unsigned char __SEG_START__PRESTART[ ];

extern unsigned char __SEG_SIZE__PRESTART[ ];

#define StartLocation __SEG_START__PRESTART

#define PrestartSize __SEG_SIZE__PRESTART

#define CodeSize __SEG_SIZE_DEFAULT_ROM

....

   unsigned char *length = CodeSize+PrestartSize//<<<< Gives several errors

   unsigned char *buffer = StartLocation;  //This works just fine, evaluation to 0xE000

 

How do I properly get the PrestartSize plus the CodeSize to represent the full amount of Flash memory that has been programmed, to be used in a statement like:

   unsigned char *length = SizeOfProgrammedFlash;

???

Does "COPY" (found in your sample PRM file) somehow represent this overall value?

Bob

0 Kudos

3,260 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

the method depends on the target and CW version.

what's your CW version?

what chip do you work with?


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,260 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi,

Regarding to @ qualifier usage, see this url

Does the "@" symbol act as a pointer in header files for Registers? 

Regarding to how to determine the beginning and end of a section of code,

The following tree prefixes are supported:

  • __SEG_START_ : start address of the segment
  • __SEG_END_ : end address of the segment
  • __SEG_SIZE_ : size of the segment

for more information, see attached two doc.

if you have doubt after reading these files, please just post it here.


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

Thank you for that information.  Being a novice at "C", I'm not quite sure how to use the "tree prefixes" like "__SEG_START_" in my own code.  I have already found out that I can't do something like:

   int* pStartAddr;            //pointer to StartAddr

   int StartAddr;

   StartAddr = __SEG_START_;   //attempt to set a variable equal to __SEG_START_

and then use StartAddr in my calculations or loops.

How do I use __SEG_START_, __SEG_END_, and __SEG_SIZE_ in my loops while also accessing the memory locations (in FLASH memory) associated with those prefixes.

Being that these are "prefixes", how do I specify any part of my own code using the prefixes?  Like this?

StartAddr = __SEG_START_main;

I need to specify my start address, perform my crc algorithm on that first byte, then increment to the next byte, perform the crc on that byte, ... up to the last byte at the ending address. Upon reaching the last byte (need to be able to detect that I've reached the last byte), my crc is complete.

Is there any advantage to switching to in-line Assembly to do my crc calculation?  Though I would still need to know how to use the above prefixes in Assembler to access the associated memory locations.  I could just brute-force the starting address, knowing that it always resides at 0xE000, but I still need to know the ending memory address, which can vary.

Thank you in advance for your help, and I also apologize for my lack of knowledge on this.

Bob

0 Kudos

3,260 Views
bpaehr
Contributor IV

I already have a sample crc algorithm that I found on-line:

// CCITT CRC-32 (Autodin II) polynomial

uint32_t CalcCRC32(uint32_t crc, uint8_t *buffer, uint16_t length) {

   while(length--) {

       crc = crc ^ *buffer++;

 

       for (uint8_t j=0; j < 8; j++) {

           if (crc & 1)

             crc = (crc >> 1) ^ 0xEDB88320;

           else

             crc = crc >> 1;

       }

   }

 

   return crc;

}

It's just a matter of correlating the address values to the parameters that get passed to this routine.

0 Kudos

3,260 Views
bpaehr
Contributor IV

I tried to follow the C Source Listing 3.24 in that same reference document ("Linker-Defined Objects"), but the MANY cross-defines are hard to understand why they're being done that way.

0 Kudos

3,260 Views
bpaehr
Contributor IV

Jennie:

I am using CW10.6.4, and an MC9S08SH8 device.

Please understand that the CRC will be derived by the processor on its own, with no knowledge of CodeWarrior, so the processor needs to know where the beginning memory location and ending memory location of the programmed code are located.  I intend to send the resulting CRC out of the serial port as part of some test routines when the board is tested so that the Test Technician knows that the Firmware has been programmed correctly.

Bob

0 Kudos

3,260 Views
bpaehr
Contributor IV

Also, is there any special method (using "C") of accessing the memory locations where my code resides, such as the "@00001802" reference to access the SOPT1 register, for example, as used in the mc9s08sh8.h header file?

If I know the starting and ending locations (from what you tell me), can the memory locations of my code be addressed as an array of bytes, such as "startLocation[index]" , where the maximum value of index is the size of my code in memory?

0 Kudos