チームの皆さん、こんにちは。
S32K3xx で機能リセット後も変数を保持しようとしていますが、うまくいきません。
実装:
__attribute__ ((section(".int_sram_results"))) uint32_t retain_var;
リセット前に値が更新されます(retain_var=0x11223344 のテスト用)。
リセットタイプ:
観察された行動:
参照情報を確認しました:
リクエスト:
ありがとうございます
ユスアップ S32K3 S32DS-ARM S32K31XEVB-Q100
こんにちは、@yusupkhan241 さん。
おそらく、起動コードはリセットのたびにSRAM全体をゼロに初期化する(ECC初期化のため)と思われます。あなたの具体的な起動コードは見ていないので、断言はできません。
リセットが機能するときにECCの初期化をスキップすることも検討できます。
この回答を参照してください。
https://community.nxp.com/t5/S32K/SRAM-ECC-Initialization-for-S32K344/mp/1764143
BR、ダニエル
こんにちは、@yusupkhan241 さん。
「うまくいかない」とはどういう意味ですか?
あなたが投稿したファイルは、最新の変更を反映していないようです。
機能リセット後にスタートアップコードを見てSRAMの変数を観察できますか?これにより、変数がどこで上書きされるかが明確に示されるはずです。
機能リセット後にデバッガーを取り付けるには、スタートコードの冒頭に簡単なループを追加できます。例えば:
Loop:
mov r0, #1
cmp r0, 0 /* Change r0 to 0 in register view */
bne Loop /* Capture after power-on reset */
よろしくお願いいたします。
ダニエル
Any support, information, and technology (“Materials”) provided by NXP are provided AS IS, without any warranty express or implied, and NXP disclaims all direct and indirect liability and damages in connection with the Material to the maximum extent permitted by the applicable law.
NXP accepts no liability for any assistance with applications or product design. Materials may only be used in connection with NXP products. Any feedback provided to NXP regarding the Materials may be used by NXP without restriction.
こんにちは、 @danielmartynek さん。
下記の起動手順を、あなたが共有してくれた変更内容に置き換えてみましたが、うまくいきませんでした。
ご参考までに、関連ファイルをアップロードしました。.s と .ld.c 拡張子のファイルがアップロードされました拡大。内容をご確認いただき、追加情報が必要な場合はお知らせください。
RamInit:
/* SRAM ECCを初期化 */
ldr r0, =__RAM_INIT
cmp r0、0
/* __RAM_INIT が設定されていない場合はスキップします */
beq SRAM_LOOP_END
ldr r0、=MCRGM_DES
ldr r1, [r0]
ldr r2、=MCRGM_DES_F_POR
r1、r1、r2
cmp r1、0
beq NO_INIT_STANDBY_REGION
ldr r2, =__INT_SRAM_START
ldr r3, =__INT_SRAM_END
b ZERO_64B_RAM
上記の手順が更新されました
RamInit: /* Check MC_RGM DES register, if it's non-zero, jump to RAMInit_Start. (RAM init is needed if Destructive reset occurred) */ /* To make it work, customer should clear the MC_RGM DES register in application code. */ ldr r4, =MC_RGM_BASE_ADDR /* 0x4028C000 */ ldr r4, [r4, #0x0] cmp r4, #0x0 bne RamInit_Start /* Check MC_RGM FES register, if the F_EXR bit or ST_DONE bit is set, jump to RAMInit_Start. */ /* RAM init is needed if external reset occurred, or BIST Done functional reset occurred. */ /* To make it work, customer should clear the MC_RGM FES F_EXR register bit in application code. */ ldr r4, =MC_RGM_BASE_ADDR ldr r4, [r4, #0x8] ldr r5, =MC_RGM_FES_MASK_RAM_INIT and r4, r4, r5 cmp r4, #0x0 bne RamInit_Start b SRAM_LOOP_END RamInit_Start: /* Initialize SRAM ECC */ ldr r0, =__RAM_INIT cmp r0, 0 /* Skip if __SRAM_INIT is not set */ beq SRAM_LOOP_END ldr r1, =__INT_SRAM_START ldr r2, =__INT_SRAM_END
ありがとうございます
ユスプ
こんにちは、 @danielmartynek さん。
RAM保持動作を分離するために、設定を簡略化しました。
私はその変数を専用のSRAM領域に配置し、LED表示とウォッチドッグによるリセット機能を備えた最小限のメイン関数を使用しました。その考え方は次の通りです:
以下に、使用されているテストコードを示します。
C
__attribute__ ((section(".int_sram_results"), used))
volatile uint32_t retain_var;
int main(void)
{
Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);
DIO_Init();
WDT_Init();
if (retain_var == 0xAABBCCDD)
{
Siul2_Dio_Ip_SetPins(LED_GREEN_PORT, (1UL << LED_GREEN_PIN));
Siul2_Dio_Ip_ClearPins(LED_RED_PORT, (1UL << LED_RED_PIN));
}
そうでない場合、
{
Siul2_Dio_Ip_SetPins(LED_RED_PORT, (1UL << LED_RED_PIN));
Siul2_Dio_Ip_ClearPins(LED_GREEN_PORT, (1UL << LED_GREEN_PIN));
}
retain_var = 0xAABBCCDD;
while(1)
{
/* ウォッチドッグリセット */
}
}
表示を減らす
観察:
参考までに、最新のリンカーファイルとスタートアップファイルを添付しました。
起動処理やリセット処理に関して何か不足している点があればお知らせください。
ありがとう、
ユスプ
テストプロジェクト全体を共有してもらえますか?そうすれば自分の側でも簡単にテストできます。
ありがとうございました。
ダニエル
こんにちは、 @danielmartynek さん。
以下は、当社のテスト結果から得られた所見です。
デバッグモードの動作:
これは、デバッガで実行している場合でも、機能リセット後のRAM保持機能が正常に動作していることを確認するものです。
ただし、スタンドアロン(デバッガーなし)で実行する場合:
この行動の原因を特定する手助けをしてもらえますか?また、完全な.int_sram_resultsを使用する予定です。機能リセット後も複数のパラメータを保持するためのセクション。確実なデータ保持のために、他に何か変更が必要かどうかご提案ください。
さらに、 ウォッチドッグの代替として機能リセットをトリガーするAPIや推奨方法があれば教えていただけますか?
参考までに、スタートアップファイルとリンカーファイルに加えた変更は共有プロジェクトで検証可能です。
起動ファイル(旧コード)
RamInit:
/* SRAM ECCを初期化 */
ldr r0, =__RAM_INIT
cmp r0、0
/* __RAM_INIT が設定されていない場合はスキップします */
beq SRAM_LOOP_END
ldr r0、=MCRGM_DES
ldr r1, [r0]
ldr r2、=MCRGM_DES_F_POR
r1、r1、r2
cmp r1、0
beq NO_INIT_STANDBY_REGION
ldr r2, =__INT_SRAM_START
ldr r3, =__INT_SRAM_END
b ZERO_64B_RAM
起動ファイル(新規コード)
.equ MC_RGM_BASE_ADDR、0x4028C000
.equ MC_RGM_FES_MASK_RAM_INIT、0xFFFFFFFF
RamInit:
/* MC_RGM DESレジスタをチェックし、ゼロでない場合はRAMInit_Startにジャンプします。(破壊的リセットが発生した場合は、RAM初期化が必要です)
/* 動作させるには、お客様がアプリケーションコードの MC_RGM DES レジスタをクリアする必要があります。*/
ldr r4, =MC_RGM_BASE_ADDR /* 0x4028C000 */
ldr r4、[r4、#0x0]
cmp r4、#0x0
bne RamInit_Start
/* MC_RGM FESレジスタをチェックし、F_EXRビットまたはST_DONEビットが設定されている場合は、RAMInit_Startにジャンプします。*/
/* 外部リセットが発生した場合、または BIST 完了機能リセットが発生した場合は、RAM 初期化が必要です。*/
/* 動作させるには、お客様はアプリケーションコード内のMC_RGM FES F_EXRレジスタビットをクリアする必要があります。*/
ldr r4、=MC_RGM_BASE_ADDR
ldr r4、[r4、#0x8]
ldr r5、=MC_RGM_FES_MASK_RAM_INIT
r4、r4、r5
cmp r4、#0x0
bne RamInit_Start
b SRAM_LOOP_END
RamInit_Start:
/* SRAM ECCを初期化 */
ldr r0, =__RAM_INIT
cmp r0、0
/* __SRAM_INITが設定されていない場合はスキップします */
beq SRAM_LOOP_END
ldr r1, =__INT_SRAM_START
ldr r2, =__INT_SRAM_END
b ZERO_64B_RAM
リンカーファイルの変更
古いコード:
.int_results (NOLOAD):
{
。= ALIGN(4);
KEEP(*(.int_results))
。+= 0x100;
} > int_sram_results
新しいコード:
.int_results(NOLOAD):
{
。= ALIGN(4);
KEEP(*(.int_results))
} > int_sram_results
ありがとう、
ユスプ
こんにちは、@yusupkhan241 さん。
デバッグを行った結果、以下のコードに誤りがあることがわかりました。
R2とR3の代わりにR1とR2を使用しました。
R2とR3が必要な理由は以下のとおりです。
この起動コードはどこで入手したのですか?
デバッガが接続された状態で、デバッガはSRAM ECCを初期化します。
デバッガーを使用しない場合、0x20400090でハードフォルトが発生しました。
よろしくお願いいたします。
ダニエル