Did not know how to call the Title properly. However, I am trying to understand how the data pages are stored. I've created simple table:
CREATE TABLE testFix
(
id INT,
v CHAR(10)
);
INSERT INTO dbo.testFix
(
id,
v
)
VALUES
( 1, -- id - int
'asdasd' -- v - varchar(100)
)
GO 2
DBCC TRACEON(3604);
Then I got PageFID and PagePID by following command:
DBCC IND(tempdb, testFix, -1)
GO
Then the actual data pages:
DBCC PAGE (tempdb, 1, 368, 3)
So now I see:
Slot 0 Offset 0x60 Length 21
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Record Size = 21
Memory Dump #0x000000287DD7A060
0000000000000000: 10001200 01000000 61736461 73642020 20200200
........asdasd .. 0000000000000014: 00
.
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
id = 1
Slot 0 Column 2 Offset 0x8 Length 10 Length (physical) 10
v = asdasd
Slot 1 Offset 0x75 Length 21
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Record Size = 21
Memory Dump #0x000000287DD7A075
0000000000000000: 10001200 01000000 61736461 73642020 20200200
........asdasd .. 0000000000000014: 00
.
Slot 1 Column 1 Offset 0x4 Length 4 Length (physical) 4
id = 1
Slot 1 Column 2 Offset 0x8 Length 10 Length (physical) 10
v = asdasd
Slot 2 Offset 0x8a Length 21
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP
Record Size = 21
Memory Dump #0x000000287DD7A08A
0000000000000000: 10001200 01000000 61736461 73642020 20200200
........asdasd .. 0000000000000014: 00
So the length of the record is 21 byte. However INT is 4 bytes and CHAR(10) is 10 bytes. 4+10=14. What for the other 7 bytes are used?
Here is the "anatomy" of data row
In red there are 7 bytes you are missing: Status Bits A (1), Status Bits B (1), Fdata length (2), Ncols (2), NullBits (1)
From this book: Pro SQL Server Internals by Korotkevitch D.
Related
I have a block of hex data which inicludes settings of a sensor, I will include the beginning snippet of the hex (LSB first):
F501517C 8150D4DE 04010200 70010101
05F32A04 F4467000 00000AFF 0502D402
This comes straight from the documentation to decode this hex to dec:
3.1. Full identifier and settings record (0x7C)
Offset Length (bytes) Field description
0x00 6 Full identifier
0x06 40 Settings
3.1.1 Full identifier
Offset Field description
0x00 Product Type
0x01 Device Type
0x02 Software Major Version
0x03 Software Minor Version
0x04 Hardware Major Version
0x05 Hardware Minor Version
3.1.2 Settings
Offset Length(bit) Offset(bit) Default value Min Max Field Description
0x00 8 0 0 0 255 Country number
0x01 8 0 0 0 255 District number
0x02 16 0 0 0 9999 Sensor number
...
0x27
This being the only information I have to decode this. The offset column must be the trick to understanding this.
What are the hex values offset from?
I see 7C in the first hex string.
The Settings section goes to 0x27 = 39 in decimal which is stated in the 3.1 section as the length being 40.
The given hex bytes are byte offset from the beginning of the data.
Assuming that your given dump is little endian 32-bit, let's have a look:
Value in dump - separated in bytes - bytes in memory
F501517C - F5 01 51 7C - 7C 51 01 F5
8150D4DE - 81 50 D4 DE - DE D4 50 81
04010200 - 04 01 02 00 - 00 02 01 04
Now let's assign them to the fields. The next list has both records concatenated.
Byte Offset Field description
7C 0x00 Product Type
51 0x01 Device Type
01 0x02 Software Major Version
F5 0x03 Software Minor Version
DE 0x04 Hardware Major Version
D4 0x05 Hardware Minor Version
Byte Offset Length(bit) Offset(bit) Default value Min Max Field Description
50 0x00 8 0 0 0 255 Country number
81 0x01 8 0 0 0 255 District number
00,02 0x02 16 0 0 0 9999 Sensor number
Whether the result makes sense, is your decision:
Product Type = 0x7C
Device Type = 0x51 = 81 decimal (could also be ASCII 'Q')
Software Major.Minor Version = 0x01.0xF5 = 1.245 decimal
Hardware Major.Minor Version = 0xDE.0xD4 = 222.212
Country number = 0x50 = 80 decimal (could also be ASCII 'P')
District number = 0x81 = 129 decimal (perhaps 0x01 = 1 with bit 7 set?)
Sensor number = 0x0002 = 2 decimal (big endian assumed)
I am trying to understand the structure of the Sql Server data pages. This is the screenshot from the Pro SQL Server Internals by Dmitri Korotkevitch
I've created 3 tables:
1 INT Column
2 INT Columns
4 INT Columns
All columns are NOT NULL
Then I run
dbcc traceon(3604);
dbcc page
(
'DbName'
,1 /*File ID*/
,368 /*Page ID*/
,3 /*Output mode: 3 - display page header and row details */
);
and getting following values for Fdata length:
With 1 Column - 0800 = 0008 = 8 = 4 + 1x4
With 2 Columns - 0c00 = 00c0 = 12 = 4 + 2x4
With 4 Columns - 1400 = 0014 = 20 = 4 + 4x4
Here I've listed "value in the output" = "swapped value" = "decimal value"
EDITED:
So far as I understand it is Const_4 + Nbr_of_Columns * Size_Of_Columns. What is this Const_4?
"Fdata length" in the picture is the offset where the fixed-length data part of the row ends.
In your example the data occupie 4, 8 and 16 bytes, and the row starts with another 4 bytes (1+1+2: status bits A, status bits B, Flength), so the "end" (offset) of storing fixed length data is 8, 12 and 20 respectively.
I noticed the online page about SQLite's query optimizer guarantees that queries of the form SELECT MAX(colA) FROM TABLE can be optimized if there is an index whose leftmost column is colA.
However, I'm less clear about what happens when an index is used to narrow the table based on an equality in WHERE clause, such that the next column in the index is the one that I'm taking a MAX on. Based on the structure of the index, the maximum value should be quickly accessible as the last row in the subset of the index satisfying the WHERE clause. For example, given an index on colA and colB, it should be possible to find SELECT MAX(colB) FROM SillyTable WHERE colA = 1 without scanning all 6 rows associated with colA = 1:
Index of SillyTable on colA, colB:
colA colB rowid
1 1 4
1 2 5
1 4 2
1 5 8
1 6 3 # This is the one
2 1 1
2 5 6
2 8 7
Does SQLite actually optimize a query like this, or will it scan all the rows that satisfy the WHERE clause? If it does a scan, how can I change the query to make it run faster?
My specific use case is similar to the SillyTable example. I created the following table:
CREATE TABLE Product(
ProductTypeID INTEGER NOT NULL,
ProductID INTEGER NOT NULL,
PRIMARY KEY(ProductTypeID, ProductID),
FOREIGN KEY(ProductTypeID)
REFERENCES ProductType(ProductTypeID)
);
ProductTypeID is not particularly selective for the table; I might have many rows with the same ProductTypeID but different ProductID. EXPLAIN QUERY PLAN tells me that my query uses an index automatically built for the composite primary key, but that is true whether it scans or binary-searches the subset of rows found with the index:
EXPLAIN QUERY PLAN SELECT MAX(ProductID) FROM Product
WHERE ProductTypeID = ?;
=>
SEARCH TABLE Product USING COVERING INDEX sqlite_autoindex_Product_1(ProductTypeID=?)
This is shown in the EXPLAIN output:
sqlite> EXPLAIN SELECT MAX(ProductID) FROM Product WHERE ProductTypeID = ?;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 17 0 00 Start at 17
1 Null 0 1 2 00 r[1..2]=NULL
2 OpenRead 1 3 0 k(2,,) 02 root=3 iDb=0; sqlite_autoindex_Product_1
3 Variable 1 3 0 00 r[3]=parameter(1,)
4 IsNull 3 13 0 00 if r[3]==NULL goto 13
5 Affinity 3 1 0 D 00 affinity(r[3])
6 SeekLE 1 13 3 1 00 key=r[3]
7 IdxLT 1 13 3 1 00 key=r[3]
8 Column 1 1 4 00 r[4]=Product.ProductID
9 CollSeq 0 0 0 (BINARY) 00
10 AggStep0 0 4 1 max(1) 01 accum=r[1] step(r[4])
11 Goto 0 13 0 00 max() by index
12 Prev 1 7 0 00
13 AggFinal 1 1 0 max(1) 00 accum=r[1] N=1
14 Copy 1 5 0 00 r[5]=r[1]
15 ResultRow 5 1 0 00 output=r[5]
16 Halt 0 0 0 00
17 Transaction 0 0 1 0 01 usesStmtJournal=0
18 Goto 0 1 0 00
To make the code generator simpler, SQLite always creates a loop for the aggregation (lines 6 to 12). However, for max(), this loop aborts after the first successful step (line 11).
I'm running the following simple script:
create table MyTable (filler char(10))
go
insert into MyTable (filler) values ('a')
go 1
exec sp_spaceused MyTable
go
drop table MyTable
go
and get the following result:
rows reserved data index_size unused
------ ---------- ------ ----------- -------
1 72 KB 8 KB 8 KB 56 KB
My questions:
Why 72 KB were reserved?
Why index_size is 8 KB if the table is not even indexed?
EDIT:
I'd like to add a follow-up:
When changing the script a little:
create table MyTable (filler char(69))
go
insert into MyTable (filler) values ('a')
go 100
I get:
rows reserved data index_size unused
------ ---------- ------ ----------- -------
100 72 KB 16 KB 8 KB 48 KB
Note that defining filler's size to 68 bytes (and inserting 100 rows) still gives 8KB as the data value (we can continue and set it to 148 bytes, which will result in another 8KB increment, i.e. to 24KB).
Can you help me break down the calculation? If (apparently) only 6,900 bytes are used, What is the cause for the 8KB addition?
EDIT #2:
Here's the results of DBCC PAGE:
PAGE: (1:4392)
BUFFER:
BUF #0x00000000061A78C0
bpage = 0x00000001EF3A8000 bhash = 0x0000000000000000 bpageno = (1:4392)
bdbid = 6 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 18482 bstat = 0x9
blog = 0x15ab215a bnext = 0x0000000000000000 bDirtyContext = 0x0000000000000000
bstat2 = 0x0
PAGE HEADER:
Page #0x00000001EF3A8000
m_pageId = (1:4392) m_headerVersion = 1 m_type = 1
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x8200
m_objId (AllocUnitId.idObj) = 260 m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594054967296
Metadata: PartitionId = 72057594048151552 Metadata: IndexId = 0
Metadata: ObjectId = 1698105090 m_prevPage = (0:0) m_nextPage = (0:0)
pminlen = 72 m_slotCnt = 100 m_freeCnt = 396
m_freeData = 7596 m_reservedCnt = 0 m_lsn = (55:8224:2)
m_xactReserved = 0 m_xdesId = (0:0) m_ghostRecCnt = 0
m_tornBits = -2116084714 DB Frag ID = 1
Allocation Status
GAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED PFS (1:1) = 0x44 ALLOCATED 100_PCT_FULL
DIFF (1:6) = CHANGED ML (1:7) = NOT MIN_LOGGED
Slot 0 Offset 0x60 Length 75
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP Record Size = 75
Memory Dump #0x0000000012A3A060
0000000000000000: 10004800 61202020 20202020 20202020 20202020 ..H.a
0000000000000014: 20202020 20202020 20202020 20202020 20202020
0000000000000028: 20202020 20202020 20202020 20202020 20202020
000000000000003C: 20202020 20202020 20202020 010000 ...
Slot 0 Column 1 Offset 0x4 Length 68 Length (physical) 68
filler = a
-- NOTE: The structure of each Slot is identical to that of Slot #0, so we can simply jump to slot 99:
Slot 99 Offset 0x1d61 Length 75
Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP Record Size = 75
Memory Dump #0x0000000012A3BD61
0000000000000000: 10004800 61202020 20202020 20202020 20202020 ..H.a
0000000000000014: 20202020 20202020 20202020 20202020 20202020
0000000000000028: 20202020 20202020 20202020 20202020 20202020
000000000000003C: 20202020 20202020 20202020 010000 ...
Slot 99 Column 1 Offset 0x4 Length 68 Length (physical) 68
filler = a
So we can see the last slot starts after 7521 bytes, and adding its size gives us 7,596 bytes. If we add the size of the slot array (in which each pointer is 2 bytes), we get 7,796 bytes.
However, we need to get to 8,192 bytes to fill the page. What's missing?
The 72K of reserved space includes a 64K extent (8 pages of 8K each) plus the 8K IAM page overhead. Of this 72K, only the IAM page and a single data page is actually used. sp_space_used reports the IAM page in the index_size, albeit not technically an index. You can see these details with the undocumented sys.dm_db_database_page_allocations TVF (use only on a test system):
SELECT extent_file_id, extent_page_id, page_type_desc
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.MyTable'), 0, 1, 'DETAILED');
This database apparently has the MIXED_PAGE_ALLOCATION database option set to OFF so a full 64K extent is allocated a initially. If the option were ON, the single data page would be allocated from a mixed extent instead of a 64K extent dedicated to the table. The space allocated in that case would be 16K - a 8K single data page plus the IAM page.
Although mixed extents do reduce space requirements for small tables (under 64K), mixed extents have more overhead and can cause allocation contention in a high concurrency workload so it is off by default in SQL 2016 onwards. In older SQL versions, mixed extent allocation was on by default and can be turned off at the server level with trace flag 1118.
You can see the mixed extent setting in sys.databases:
SELECT name, is_mixed_page_allocation_on
FROM sys.databases;
To toggle the setting:
ALTER DATABASE Test
SET MIXED_PAGE_ALLOCATION ON;
EDIT 1:
Space within a data page includes overhead for the page itself as well as records within the page. This overhead, plus the space needed for user data, will determine how many rows can fit on a page and number of data pages required to store a given number of rows. See Paul Randal's anatomy of a page and anatomy of a record articles for details of that overhead.
EDIT 2:
From your follow-up comment:
7998 bytes, so there are more 194 bytes to go for the next allocation.
What am I missing?
I almost never use heaps but as you can see in the page dump, the associated PFS (page free space) allocation status for this page is 100 percent full. According to Kalen Delaney's Microsoft SQL Server 2012 Internals book, the PFS status is actually a 3-bit mask of these ranges:
000: empty
001: 1-50% full
010: 51-80% full
011: 81-95% full
100: 96-100% full
So it looks like once heap page fullness crossed the 96% percent threshold it was considered 100% full and a new page was allocated. Note this does not happen on a table with a clustered index because the page for a new row is first determined by the CI key and a new page allocated only if it can't fit in that page at all. Yet another reason to avoid heaps.
In CC2541 (IAR EW51/7.20) project I need to store few large const arrays (~30KB each).
I define the first array:
const uint8 demo_signal_1[30000] = {
0X00,
0X01,
0X10,
// rest of the data
};
It links in XDATA_ROM_C segment and runs just fine.
Then I add another 30KB array in another segment to overcome 32KB limitation:
const uint8 demo_signal_2[30000] = {
0X22,
0X33,
0X44,
// rest of data
}
The linker throws an error:
Error[e104]: Failed to fit all segments into specified ranges. Problem discovered in segment XDATA_ROM_C. Unable to place 96 block(s) (0xe37e byte(s) total) in 0x8000 byte(s) of memory.
Can anyone guide how to locate the second array on its own segment so linking should pass ?
I tried to follow the documentation and the forum but I seem to fail grasp something.
many thanks for any support
Thanks.
UPDATE (pretty long but please bear with me):
I played a little with segments definitions -
I've added two new (CONST)segments to the xcl file:
// Define segments for const data in flash.
// First the segment with addresses as used by the program (flash mapped as XDATA)
-P(CONST)XDATA_ROM_C=0x8000-0xFFFF
-Z(CONST)XDATA_ROM_C2=0x28000-0x2FFFF // Added
-Z(CONST)XDATA_ROM_C3=0x38000-0x3FFFF // Added
//
And defined the arrays to locate in these segments
// Array 1 in it own segment
const uint8 demo_signal_1[28800] # "XDATA_ROM_C2"= {
0X00,
0X00,
0X01,
0X01,
// ...rest of initialization data
}
// Array 2 in it own segment
const uint8 demo_signal_2[28800] # "XDATA_ROM_C3" = {
0X00,
0X00,
0X02,
0X02,
// ...rest of initialization data
}
This time it does link fine and generate the following map file
****************************************
* *
* SEGMENTS IN ADDRESS ORDER *
* *
****************************************
SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN
======= ===== ============= =========== ==== ==== =====
INTVEC CODE 00000000 - 00000085 86 com 0
CSTART CODE 00000086 - 00000136 B1 rel 0
BIT_ID CODE 00000137 dse 0
BDATA_ID CODE 00000137 dse 0
IDATA_ID CODE 00000137 dse 0
IXDATA_ID CODE 00000137 dse 0
PDATA_ID CODE 00000137 dse 0
DATA_ID CODE 00000137 dse 0
XDATA_ID CODE 00000137 - 0000057A 444 rel 0
BANK_RELAYS CODE 0000057B - 0000151C FA2 rel 0
RCODE CODE 0000151D - 00001C4F 733 rel 0
CODE_N CODE 00001C50 dse 0
DIFUNCT CODE 00001C50 dse 0
NEAR_CODE CODE 00001C50 - 00002C14 FC5 rel 2
<BANKED_CODE> 1 CODE 00002C15 - 00002C17 3 rel 0
<BANKED_CODE,CODE_C> 1
CODE 00002C18 - 00007FFB 53E4 rel 2
<BANKED_CODE,XDATA_ROM_C_FLASH> 1
CODE 00008000 - 0000FFFD 7FFE rel 2
<BANKED_CODE> 2 CODE 00010000 - 00017FF9 7FFA rel 0
<BANKED_CODE> 3 CODE 00018000 - 0001DE08 5E09 rel 0
BLENV_ADDRESS_SPACE
CODE 0003E800 - 0003F7FF 1000 rel 0
REGISTERS DATA 00000000 - 00000007 8 rel 0
VREG DATA 00000008 - 00000017 10 rel 0
PSP DATA 00000018 dse 0
XSP DATA 00000018 - 00000019 2 rel 0
DATA_I DATA 0000001A dse 0
BREG BIT 00000020.0 - 00000020.7 8 rel 0
DATA_Z DATA 00000021 - 00000028 8 rel 0
SFR_AN DATA 00000080 - 00000080 1 rel 0
DATA 00000086 - 0000008A 5
DATA 0000008C - 0000008D 2
DATA 00000090 - 00000091 2
DATA 00000094 - 00000097 4
DATA 0000009A - 000000A9 10
DATA 000000AB - 000000AF 5
DATA 000000B3 - 000000B4 2
DATA 000000B6 - 000000B6 1
DATA 000000B8 - 000000B9 2
DATA 000000BB - 000000C7 D
DATA 000000C9 - 000000C9 1
DATA 000000D1 - 000000DB B
DATA 000000E1 - 000000E9 9
DATA 000000F1 - 000000F5 5
DATA 000000F8 - 000000FA 3
DATA 000000FC - 000000FF 4
XSTACK XDATA 00000001 - 00000280 280 rel 0
XDATA_Z XDATA 00000281 - 00000BE4 964 rel 0
XDATA_I XDATA 00000BE5 - 00001028 444 rel 0
<XDATA_N> 1 XDATA 00001029 - 00001C2A C02 rel 0
XDATA_AN XDATA 0000780E - 00007813 6 rel 0
<XDATA_ROM_C> 1 CONST 00008000 - 00008805 806 rel 2
XDATA_ROM_C2 XDATA 00028000 - 0002F07F 7080 rel 0
XDATA_ROM_C3 XDATA 00038000 - 0003F07F 7080 rel 0
IDATA_I IDATA 00000029 dse 0
IDATA_Z IDATA 00000029 - 0000002A 2 rel 0
ISTACK IDATA 00000040 - 000000FF C0 rel 0
****************************************
* *
* END OF CROSS REFERENCE *
* *
****************************************
126 461 bytes of CODE memory
34 bytes of DATA memory (+ 86 absolute )
7 210 bytes of XDATA memory (+ 6 absolute )
194 bytes of IDATA memory
8 bits of BIT memory
59 654 bytes of CONST memory
Errors: none
Warnings: none
Two observations (scroll to the bottom of the map file):
The CODE size reduced by the 28803 bytes as the size of the original
array located in the original segment, similarly
segment size reduced by same 28803 bytes. and;
Newly added CONST segment (in xcl file) appear as XDATA in the map file
This all would be fine if I could download the generated binary into the chip, but when I try to 'download and debug' I receive the following message:
Fatal Error: Everything you want to place in flash memory must be placed with Xlink CODE memory segment type.
I tried to circumvent and generate intel-extended hex file to flash it standalone but the IDE returns the following error:
Error[e133]: The output format intel-extended cannot handle multiple address spaces. Use format variants (-y -O) to specify which address space is wanted
Reaching so far I tried one more thing and changed the new segments definition to (CODE) as advised by the error message.
// Define segments for const data in flash.
// First the segment with addresses as used by the program (flash mapped as XDATA)
-P(CONST)XDATA_ROM_C=0x8000-0xFFFF
-Z(CODE)XDATA_ROM_C2=0x28000-0x2FFFF // Modified to (CODE)
-Z(CODE)XDATA_ROM_C3=0x38000-0x3FFFF // Modified to (CODE)
Once again it links fine and the map file shows (scroll to the bottom):
****************************************
* *
* SEGMENTS IN ADDRESS ORDER *
* *
****************************************
SEGMENT SPACE START ADDRESS END ADDRESS SIZE TYPE ALIGN
======= ===== ============= =========== ==== ==== =====
INTVEC CODE 00000000 - 00000085 86 com 0
CSTART CODE 00000086 - 00000136 B1 rel 0
DATA_ID CODE 00000137 dse 0
BDATA_ID CODE 00000137 dse 0
BIT_ID CODE 00000137 dse 0
IDATA_ID CODE 00000137 dse 0
IXDATA_ID CODE 00000137 dse 0
PDATA_ID CODE 00000137 dse 0
XDATA_ID CODE 00000137 - 0000057A 444 rel 0
BANK_RELAYS CODE 0000057B - 0000151C FA2 rel 0
RCODE CODE 0000151D - 00001C4F 733 rel 0
DIFUNCT CODE 00001C50 dse 0
CODE_N CODE 00001C50 dse 0
NEAR_CODE CODE 00001C50 - 00002C14 FC5 rel 2
<BANKED_CODE> 1 CODE 00002C15 - 00002C17 3 rel 0
<BANKED_CODE,CODE_C> 1
CODE 00002C18 - 00007FFB 53E4 rel 2
<BANKED_CODE,XDATA_ROM_C_FLASH> 1
CODE 00008000 - 0000FFFD 7FFE rel 2
XDATA_ROM_C2 CODE 00010000 - 0001707F 7080 rel 0
<BANKED_CODE> 2 CODE 00017080 - 00017FF3 F74 rel 0
XDATA_ROM_C3 CODE 00018000 - 0001F07F 7080 rel 0
<BANKED_CODE> 3 CODE 0001F080 - 0001FFF0 F71 rel 0
<BANKED_CODE> 4 CODE 00020000 - 00027FF9 7FFA rel 0
<BANKED_CODE> 5 CODE 00028000 - 0002BF23 3F24 rel 0
BLENV_ADDRESS_SPACE
CODE 0003E800 - 0003F7FF 1000 rel 0
REGISTERS DATA 00000000 - 00000007 8 rel 0
VREG DATA 00000008 - 00000017 10 rel 0
PSP DATA 00000018 dse 0
XSP DATA 00000018 - 00000019 2 rel 0
DATA_I DATA 0000001A dse 0
BREG BIT 00000020.0 - 00000020.7 8 rel 0
DATA_Z DATA 00000021 - 00000028 8 rel 0
SFR_AN DATA 00000080 - 00000080 1 rel 0
DATA 00000086 - 0000008A 5
DATA 0000008C - 0000008D 2
DATA 00000090 - 00000091 2
DATA 00000094 - 00000097 4
DATA 0000009A - 000000A9 10
DATA 000000AB - 000000AF 5
DATA 000000B3 - 000000B4 2
DATA 000000B6 - 000000B6 1
DATA 000000B8 - 000000B9 2
DATA 000000BB - 000000C7 D
DATA 000000C9 - 000000C9 1
DATA 000000D1 - 000000DB B
DATA 000000E1 - 000000E9 9
DATA 000000F1 - 000000F5 5
DATA 000000F8 - 000000FA 3
DATA 000000FC - 000000FF 4
XSTACK XDATA 00000001 - 00000280 280 rel 0
XDATA_Z XDATA 00000281 - 00000BE4 964 rel 0
XDATA_I XDATA 00000BE5 - 00001028 444 rel 0
<XDATA_N> 1 XDATA 00001029 - 00001C2A C02 rel 0
XDATA_AN XDATA 0000780E - 00007813 6 rel 0
<XDATA_ROM_C> 1 CONST 00008000 - 00008805 806 rel 2
IDATA_I IDATA 00000029 dse 0
IDATA_Z IDATA 00000029 - 0000002A 2 rel 0
ISTACK IDATA 00000040 - 000000FF C0 rel 0
****************************************
* *
* END OF CROSS REFERENCE *
* *
****************************************
184 061 bytes of CODE memory
34 bytes of DATA memory (+ 86 absolute )
7 210 bytes of XDATA memory (+ 6 absolute )
194 bytes of IDATA memory
8 bits of BIT memory
2 054 bytes of CONST memory
Errors: none
Warnings: none
Voilla, CONST has shrunk and CODE expanded by exactly 57600 bytes as expected.
It even download and debug and generates hex file.
BUT when debugging the code it appears that instead of accessing 0x28000/0x38000, the memory controller access the data at 0x8000 which is the 'original' (CONST)XDATA_ROM_C segment.
To summarize:
when defining the two new segments as (CONST), the code links but can not debug nor generate hex file and
when defining the two new segments as (CODE), the code links, loads and run but the memory is not accessed correclty.
phew, this was long description. Any ideas someone ????
Note that this thread is duplicated at TI e2e forum as well here
I have the same problem. Seems all data constants need to be in a single 32K segment that gets mapped into the Xdata region. I did a weak work around by using the -Z(CODE)XDATA_ROM_C2=0x38000-0x3FFFF declaration in your second attempt to map my 2nd array of 32K data into BANK6. In my code access routine I cheated by using the HalFlashRead routine to pull 32 bytes chunks into a local array and then index into the local array -- lots of bits missing, but the HaFlash routine expects a 2k page number, offset into page, buffer to place the data, and byte count. This is hardly a solid portable solution but allowed me to move forward. -- hope it helps or gives you more insight
rd_addr = 0x38000 + offset;
HalFlashRead((rd_addr>>0x11)&0xff), (rd_addr & 0x7ff), *ptr32bytes, 32);
realdata = ptr[0]; // offset == [0], offset+1= [1], ....