説明しているデータ(データを格納するためのプログラムメモリの完全な24ビット使用)は、Cで定義および初期化できず、Cを介して直接読み取ることもできません。これにアクセスする唯一の方法は、C呼び出し可能なアセンブリ関数または組み込み関数にカプセル化することです。
ここには本当に2つの質問があります。
コンパイラー、アセンブラー、およびリンカーを適切に使用する方法。これにより、アセンブリーファイルで24ビットD1
データを、固定アドレスの名前のないデータではなく、シンボル名で再配置可能なデータとして定義すると、コンパイラーはこの変数を認識できます。そのアドレスを決定する
データにアクセスする方法
(どのようにデータにアクセスする)第2の質問はで33EP部分に対して応答されDS70613Cとに33FJ部品に答えなければならないDS70204C(しかしマニュアル33FJの例では、下位16ビットを使用します)。以下は、33EPパーツに対して機能する33EPリファレンスマニュアルからのコードスニペットの例です。
(注:コードはint
を使用しますがuint16_t
、and を使用する方が良いでしょう#include <stdint.h>
)
int prog_data[10] __attribute__((space(prog))) =
{0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999};
unsigned int lowWord[10], highWord[10];
unsigned int tableOffset, loopCount;
int main(void){
TBLPAG = __builtin_tblpage (prog_data);
tableOffset = __builtin_tbloffset (prog_data);
/* Read all 10 constants into the lowWord and highWord arrays */
for (loopCount = 0; loopCount < 10; loopCount ++)
{
lowWord[loopCount] = __builtin_tblrdl (tableOffset);
highWord[loopCount] = __builtin_tblrdh (tableOffset);
tableOffset +=2;
}
while(1)
;
}
組み込み関数__builtin_tblrdl()
と__builtin_tblrdh()
は、プログラムメモリ位置からデータの下位16ビットワードと上位16ビットワードを読み取るため __builtin_tblpage() and __builtin_tbloffset()
に使用され、ページとアドレスのオフセットを抽出するために使用できることに注意してください。この特定の例では、highWord配列は常に0であり、lowWord配列はCで定義および初期化されたprog_dataと一致します。
ここではポインタは使用されていません。でタグ付けされた通常の変数を使用const
して、リンカーが読み取り専用プログラム空間に配置し、標準のCポインター技術を使用してメモリを読み取ることができるようにしますが、コンパイラーがページングレジスタを自動的に管理します。あなたのために、あなたは16ビットデータだけを保存することができます。24ビットのデータをすべて取得するには、TBLRDLおよびTBLRDH組み込み関数にアクセスする必要があります。
コンパイラー/リンカー/その他をうまく操作する方法については、コンパイラーをだまして、16ビットのデータしか見えないことを伝える必要があります。以下は、別の場所で宣言された変数D1を取得するために機能した例です。
#define D1_SIZE 18
extern uint16_t __attribute__((space(prog))) D1[D1_SIZE];
#define READ_DATA(dst, v, len) readData(dst, __builtin_tblpage(v), __builtin_tbloffset(v), len)
void readData(uint32_t *pdst, uint16_t page, uint16_t offset, uint16_t len)
{
TBLPAG = page;
while (len-- > 0)
{
uint16_t lo = __builtin_tblrdl (offset);
uint16_t hi = __builtin_tblrdh (offset);
*pdst++ = (((uint32_t)(hi)) << 16) | ((uint32_t)(lo));
offset += 2;
}
}
...
uint32_t d1copy[D1_SIZE];
READ_DATA(d1copy, D1, D1_SIZE);
これにより、24ビット値が正しく読み取られ、uint32_tの下位24ビットに格納されます。Cで宣言されたextern D1変数は、コンパイラー/アセンブラー/リンカーの連携方法を利用して開始アドレスに到達するためにのみ使用されるダミー変数です。組み込み関数が残りの作業を処理します。
それが定義されている+アセンブリで初期化されているため、データのサイズを自動的に取得する方法はわかりません。