This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] [参考译文] [常见问题解答]有关 C2000器件闪存 API 用法的常见问题解答

Guru**** 1123190 points
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/951668/faq-faq-on-flash-api-usage-for-c2000-devices

Thread 中讨论的其他器件:C2000WAREcontrolSUITE

下面是这些器件的闪存 API 使用常见问题解答:TMS320F28M35x、TMS320F28M36x、TMS320F2837xD、TMS320F2837xS、TMS320F2807x、 TMS320F28004x、TMS320F28002x、TMS320F2838x。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

请使用以下闪存 API 常见问题解答以及器件特定的闪存 API 参考指南。

(a) F28M35x 和 F28M36x 闪存 API (v1.53)参考指南链接: http://www.ti.com/lit/pdf/spnu595

(b) F2837xS 闪存 API (V1.55)参考指南链接: http://www.ti.com/lit/pdf/spnu630

(C) F28004x 闪存 API (V1.56.01)参考指南链接: http://www.ti.com/lit/pdf/spnu628

(D) F2837xD 和 F2807x 闪存 API (V1.54)参考指南链接: http://www.ti.com/lit/pdf/spnu629

(e) F28002x (V1.57)参考指南链接: http://www.ti.com/lit/pdf/spnu631

(f) F2838x (V1.60)参考指南链接: http://www.ti.com/lit/pdf/spnu632 

(g) F28003x (V 1.58)参考指南链接: https://www.ti.com.cn/cn/lit/pdf/spruj27 (请注意、F28003x 闪存 API 正在针对功能安全标准进行升级、器件 RTM 将提供升级版指南)

F2807x 用户注意事项:SPNU629中提供的示例实现(示例)使用200MHz CPUCLK 频率、因为该文档主要针对 TMS320F2837xD 器件而编写。 如数据手册中所述、TMS320F2807x 用户不应使用超过120MHz 的 CPUCLK。


1.您能简要概述一下如何使用突出的闪存 API 函数吗?

答案。 以下步骤提供了一般概述。 根据您使用的器件、需要进行一些更改。 例如、在 TMS320F2837xS 中、只要目标闪存组发生更改、就应该调用 Fapi_initiataleAPI ()和 Fapi_setActiveFlashBank ()函数、因为有两个闪存(在这个系列的某些器件型号中)。 但是、在 TMS320F28004x 中、更改目标组时不必调用这些函数、因为只有一个 FMC。 有关特定详细信息、请参阅 C2000Ware 中为您的器件提供的闪存 API 参考指南。

a.配置 PLL

b.将闪存初始化代码从闪存复制到 RAM

c.将闪存 API 从闪存复制到 RAM

d.初始化闪存等待状态、回退功率模式、性能特性和 ECC

e.使用泵信标获取闪存泵的所有权(不适用于某些器件-例如 TMS320F28004x)。

f.在调用闪存 API 函数之前、应执行 EALLOW (C28x)或 MWRALLOW (ARM)以允许写入受保护的寄存器。 Concerto、F2837xD 和 F2807x 器件需要执行此操作。

G.EDIS 应在调用闪存 API 函数后执行、以禁止写入受保护的寄存器。 Concerto、F2837xD、F2837xS 和 F2807x 器件需要执行此操作。

h.通过提供闪存寄存器基址和工作频率来初始化闪存 API

Fapi_initializeAPI (F021_CPUx_BASE_ADDRESS、CLK_FREQUENCY);

i.初始化闪存组和 FMC 以进行擦除和编程操作

Fapi_setActiveFlashBank (Fapi_FlashBankX);

J.擦除闪存扇区

Fapi_issueExamplesWithCommandAddress (Fapi_EraseSector、UINT32 * pu32StartAddress);

K.执行空白检查

Fapi_doBlankCheck (uint32 *地址、uint32 u32Length、Fapi_FlashStatusWordType * poFlashStatusWord);

L.使用 AutoEccGeneration 模式对闪存进行编程(也可以根据需要使用其他模式)

fapi_issueProgrammingCommand (uint32 *地址、uint16 *缓冲区、uint16缓冲区长度、0、0、0、 Fapi_AutoEccGeneration)

M.验证闪存是否已正确编程

Fapi_doVerify (uint32 *地址、uint32 u32Length、uint32 * pu32CheckValueBuffer、Fapi_FlashStatusWordType * poFlashStatusWord);

2.为什么上述闪存 API 函数与 F2802x、F2803x、F2805x、F2806x、F2833x 等其他 C2000器件的函数不同?

答案。 闪存包装程序(或者闪存模块控制器、FMC)在这些器件中是不同的。 F28M35x、F28M36x、F2837xD、F2837xS、F2807x、 F28004x 器件支持 ECC、128位编程、更快的擦除和编程等 这些器件的 API 会利用这些功能。


3.当闪存 API 无法擦除或编程时、我们可以考虑哪些常见的调试提示?

答案。 请检查以下项目:

(i)确保 PLL 针对所需的系统频率进行了正确配置

(ii)确保按照数据表正确配置闪存等待状态

(iii)确保闪存初始化例程从 RAM 执行。 将闪存初始化例程从闪存复制到 RAM。

(iv)在调用闪存 API 函数之前、请确保执行 EALLOW (C28x)或 MWRALLOW (Concerto ARM)。 这适用于 F28M35x、F28M36x、F2837xD、F2837xS、F2807x 器件。

(V)确保不要执行闪存 API 和从当前擦除/编程操作所针对的闪存组中调用闪存 API 的函数。 在单组器件中、这些应该从 RAM 中执行。 在双组器件中、这些函数应该从 RAM 或者不针对当前擦除/编程操作的组中执行。 当应用被设计成从 RAM 执行闪存 API (和调用闪存 API 的函数)时、在执行这些函数之前、将它们从闪存复制到 RAM 中。

(vi)以上内容也适用于 Fapi_UserDefinedFuncations.c 文件中的函数。 请注意、该文件不适用于某些器件(例如 F28004x)、因为这些器件不需要该文件。

(VII)确保为内核或 FMC 抓取闪存泵信标(如果适用)。 请注意、F2837xS 单组器件和 F28004x 器件中没有泵信号量。

(VIII)确保为各自的安全区域(如适用)配置 FLSEM 寄存器(在 Concerto 中被称为 SECZONEREQUEST)。

(IX)确保从与当前擦除或编程操作所针对的闪存扇区安全区域相同的安全区域执行闪存 API。

(x)如果此函数用于为看门狗计时器提供服务、请确保在 Fapi_serviceWatchdogTimer()中的 return 语句之前包含 EALLOW (用于 C28x)或 MWRALLOW (Concerto ARM)。

(XI)确保在闪存运行期间、电源能够满足数据手册技术规格的要求。    这可防止器件 耗电。  如果不对此进行处理、则可能会发生闪存/ OTP 损坏。

(XII)确保在每次擦除和编程操作后检查 FMSTAT 寄存器、以识别任何故障。

(XIII)擦除操作结束后,使用 Fapi_doBlankCheck()检查扇区是否被擦除。

(XIV)程序操作结束后,使用 Fapi_doVerify()检查数据是否正确编程。 请注意、32位是可使用此函数检查的最小值。

4.为什么以及何时调用 Fapi_initiatalizeAPI()?

答案。 器件首次上电后、应使用适当的参数调用此函数一次、以便在执行任何其他闪存 API 操作之前初始化闪存 API 内部状态变量。 如果在初始调用此函数后更改了系统频率或 RWAIT、也应调用此函数。 此外、对于 F2837xS 器件、由于单个内核有两个 FMC、因此每当针对闪存操作更改目标组(并因此更改 FMC)时、应调用此函数。 请注意、在调用此函数之前、应配置闪存等待状态。


5.为什么以及何时调用 Fapi_setActiveFlashBank()?

答案。 此函数初始化 FMC、以便在组上执行进一步的操作。 在 Fapi_initiatizeAPI 函数之后以及在执行任何其他闪存 API 操作之前需要调用此函数。 对于给定的 FMC、无需多次调用此函数、除非在最初调用此函数后更改了系统频率或 RWAIT。 此外、对于 F2837xS 器件、由于单个内核有两个 FMC、因此每当更改目标组(组0或组1)时、也必须调用此函数。 对于 F28004x 器件、尽管有两个组、但只有一个 FMC、因此在更改目标组时无需调用此函数。


6.我们是否可以通过单次调用 Fapi_issueODE19 CommandWithAddress()来擦除整个组?

答案。 否、此函数一次只能擦除扇区。 为了擦除多个扇区,必须使用作为参数提供的每个扇区的地址来调用此函数。  请注意、可被擦除的最小存储器范围是一个扇区-不能擦除扇区的一部分。


7. Fapi_issueCommandWithAddress()是否支持 Fapi_EraseSector 以外的任何命令?

答案。 否 此函数仅使用擦除扇区命令(Fapi_EraseSector)。 C2000器件不支持组擦除。

完成扇区擦除操作后、Fapi_issueCommandAppiAddress (Fapi_EraseSector、xx)函数调用是否返回?

答案。 否、这个函数向闪存状态机发出一个擦除命令来获得用户提供的扇区地址。 此函数不会等到擦除操作结束;它只发出命令并返回。 因此、当使用 Fapi_EraseSector 命令时、此函数始终返回成功状态。 在访问执行擦除操作的闪存组之前、用户应用必须等待 FMC 完成擦除操作。 fapi_checkFsmForReady()函数可用于监视已发出命令的状态。

9.如果 Fapi_issue19 CommandWithAddress (Fapi_EraseSector、xx)没有等待擦除操作完成、我们如何知道擦除操作是否成功?

答案。 当 FSM 完成擦除操作时、用户应用程序必须检查 FMSTAT 值。 FMSTAT 指示擦除操作期间是否发生任何故障。 用户应用程序可以使用 fapi_getFSMStatus()函数来获取 fmstat 值。 有关 fmstat 的详细信息、请参阅 C2000Ware 中提供的器件特定闪存 API 参考指南。 此外,用户应用程序应该使用 Fapi_doBlankCheck()函数来验证闪存是否被擦除。

10.可以使用 Fapi_issueProgrammingCommand()一次对多少位进行编程?

答案。 由于架构原因、FSM (FMC 中)一次只能在128位对齐的存储器内编程、而不能跨两个128位对齐的存储器范围进行编程。 因此、

(i)如果地址是128位对齐的、那么一次最多可以编程8个16位字(128位)。

(ii)如果地址为“128位对齐地址+1”,则一次最多可编程7个16位字。

(iii)如果地址为“128位对齐地址+2”,则一次最多可编程六个16位字。

(iv)如果地址为“128位对齐地址+3”,则一次最多可编程5个16位字。

(v)如果地址为“128位对齐地址+4”,则一次最多可编程四个16位字。

(vi)如果地址为“128位对齐地址+5”,则一次最多可编程三个16位字。

(VII)如果地址为“128位对齐地址+6”,则一次最多可编程两个16位字。

(VIII)如果地址为“128位对齐地址+7”,则一次最多可编程一个16位字。


示例:考虑一个128位(8*16位)对齐的地址;例如0x80000 (0x80000 mod 8 = 0)。

(i)如果为编程指定的地址为0x80000、则最多可编程8*16位

(ii)如果为编程指定的地址为0x80001,则最多可以编程7*16位

(iii)如果指定用于编程的地址为0x80002、则最多可编程6*16位……。

(iv)如果为编程指定的地址为0x80007,则最多可以编程1*16位


同样、一次只能对128位对齐存储器范围内的地址进行编程。 为了对多个128位对齐的存储器范围进行编程、应调用此函数来分别对每个范围进行编程。


请注意、可编程的最小位数在任何地址为1。 API 允许对小于64位的位进行编程、从而允许对 DCSM 链路指针位置进行一次编程1位。


尽管 API 允许对小于64位的位进行编程、 务必要知道主阵列闪存编程必须与64位地址边界对齐、并且每个64位字在每个写入或擦除周期只能编程一次-这意味着主阵列闪存给定的64位对齐存储器中的所有位 应一次进行编程。 DCSM OTP 编程必须与128位地址边界对齐、并且每个128位字只能编程一次。 例外情况如下:

–DCSM OTP 中的 DCSM Zx-LINKPOINTER1和 Zx-LINKPOINTER2值应一起编程、并且可以根据 DCSM 操作的要求、一次编程1位(使用 Fapi_DataOnly 模式)。

–DCSM OTP 中的 DCSM ZX-LINKPOINTER3值可以按照 DCSM 操作的要求、一次编程1位(使用 Fapi_DataOnly 模式)。

11.完成程序操作后,Fapi_issueProgrammingCommand()函数调用是否返回?

答案。 否、这个函数向闪存状态机发出一个程序命令来获得用户提供的地址和数据。 此函数不会等到程序操作结束;它只发出命令并返回。 因此、不应将此函数返回的成功状态视为成功的程序操作。 此函数的成功状态返回意味着用户应用程序提供的地址、数据和/或 ECC 满足程序操作的要求、并且程序命令被成功发出。 用户应用程序必须等待 FMC 完成程序操作、然后才能访问发出程序命令的闪存组。 fapi_checkFsmForReady()函数可用于监视已发出命令的状态。


12.如果 fapi_issueProgrammingCommand()函数不等待程序操作完成,我们如何知道程序操作是否成功?

答案。 当 FSM 完成程序操作时、用户应用程序必须检查 FMSTAT 值。 FMSTAT 指示程序运行期间是否发生任何故障。 用户应用程序可以使用 fapi_getFSMStatus()函数来获取 fmstat 值。 有关 fmstat 的详细信息、请参阅 C2000Ware 中提供的器件特定闪存 API 参考指南。 此外,用户应用程序应使用 Fapi_doVerify()函数来验证闪存是否已正确编程。


13.为什么闪存编程函数有不同的编程模式(Fapi_issueProgrammingCommand())?

答案。 提供四种模式:

(i) Fapi_DataOnly:仅对不带 ECC 的数据进行编程

(ii) Fapi_AutoEccGeneration:对64位或128位数据以及 API 生成的正确 ECC 进行编程

(iii) Fapi_DataAndEcc:对用户提供的数据和 ECC 进行编程(必须一次对64位或128位以及它们的 ECC 进行编程)

(iv) Fapi_EccOnly:只对无数据的 ECC 进行编程

C2000Ware 中提供的器件专用闪存 API 参考指南中此函数说明下的表格中提供了上述模式的使用方案。

当对闪存主阵列使用上述任一编程模式(除了 Fapi_EccOnly)时、必须注意的是、应该一次对64位(对齐)或者128位(对齐)进行编程。 当使用 Fapi_EccOnly 模式时、可对2个字节(ECC 存储器中某个位置的 LSB 和 MSB)或者1个字节(ECC 存储器中某个位置的 LSB)进行编程。

当对 DCSM OTP 使用任何上述编程模式(除了 Fapi_EccOnly)时、编程必须与128位地址边界对齐、并且每个128位字只能编程一次。 例外情况如下:

–DCSM OTP 中的 DCSM Zx-LINKPOINTER1和 Zx-LINKPOINTER2值应一起编程、并且可以根据 DCSM 操作的要求、一次编程1位(使用 Fapi_DataOnly 模式)。

–DCSM OTP 中的 DCSM ZX-LINKPOINTER3值可以按照 DCSM 操作的要求、一次编程1位(使用 Fapi_DataOnly 模式)。


14.使用 Fapi_AutoEccGeneration 模式时,可编程的16位字的最小数量是多少?

答案。 四个。 请注意、假设空穴为1、则为整个64位对齐存储器范围生成 ECC。 例如、如果只提供一个16位字、则所有其他三个16位字将被假定为全为1来计算 ECC。 一旦 ECC 被编程到一个指定的64位对齐存储器中、由于 ECC 已经针对64位字编程、在没有扇区擦除的情况下、这个64位字中的未编程位(1)不能在以后进行编程。 因此、始终对64位(对齐)或128位(对齐)进行编程。 这也适用于 Fapi_DataAndEcc 模式。


15、当使用 Fapi_AutoEccGeneration 模式时、对于给定的128位对齐存储器、是否可以一次对低64位进行编程、而对高64位进行编程?

答案。 是的、ECC 仅针对您提供的64位进行编程。


我们可以在执行闪存 API 时启用中断吗?

答案。 是的、闪存 API 是可中断的。 但是、不应对正在进行擦除或编程操作的闪存组进行任何访问(取指令或读取)。 因此、ISR 应该从 RAM 或者闪存组(在每个内核具有双组的器件上)执行、而不针对当前擦除/编程。


17.为什么在 F2837xD CPU2上调用 Fapi_setActiveFlashBank()时会发生 NMI (由于双位错误)?

答案。 此函数访问 TI-OTP 以初始化 FMC。 在启用 ECC 的情况下调用 TI-OTP 的 ECC (ECC_ENABLE 寄存器)、少数器件的 ECC 编程不正确(在有界日期范围内)、因此会发生 NMI (并且 NMIFLG[FLAUNCHERR]将设置为1)。 因此、在调用以下 API 函数之前、请禁用 ECC 检查(ECC_ENABLE = 0)。

a. Fapi_setActiveFlashBank (Fapi_FlashBank0);

b. fapi_getDeviceInfo();

c. fapi_getBankSectors ();


如果 ECC 未被禁用、器件将执行应用 NMI 处理程序(如果被定义)。 如果未定义应用 NMI 处理程序、引导 ROM 中的默认 NMI 处理程序将按照《TMS320F2837xD 双核 Delfino 微控制器技术参考手册》(SPRUHM8)表"引导 ROM 异常和操作"运行。 ECC 检查可在执行上述函数后启用。


除了 CPU2闪存编程之外、在闪存外执行应用程序时、不会影响其他器件功能或正常的主闪存阵列 ECC 检查。 TI 向客户发送了一封 SIBP 信函、对其进行了解释。


下面给出了在使用上述闪存 API 函数之前在 CPU2 TI-OTP 上禁用 ECC 检查的示例代码。

EALLOW;
////复位时启用 ECC。 在调用
F2837xD CPU2上的// Fapi_setActiveFlashBank()函数//

Flash0EccRegs.ecc_enable.bit.enable = 0x0之前禁用 ECC;
//
//刷新 CPU 流水线
//
__asm (" RPT #7 || NOP");
//
// Fapi_setActiveFlashBank 函数设置闪存组和 FMC
//以便在组上执行进一步的闪存操作
//
oReturnCheck = Fapi_setActiveFlashBank (Fapi_FlashBank0);
if (oReturnCheck != Fapi_Status_Success)
{
//
//检查闪存 API 文档以了解可能的错误
//
Example_Error (oReturnCheck);
}
//
//重新启用 ECC
//
Flash0EccRegs.ecc_enable.bit.enable = 0xA;
//
//刷新 CPU 流水线
//
__asm (" RPT #7 || NOP");
EDIS;


如果使用了权变措施、则对闪存编程没有影响、并且材料可完全正常工作。 不存在长期可靠性风险。 在所有情况下,当调用 fapi_setActiveFlashBank()时,闪存 API 使用校验和来验证 TI-OTP 内容(如果校验和失败,将返回错误代码)。 在使用上述列出的闪存 API 函数期间、无需在 CPU2 TI-OTP 上使用 ECC 检查来确保正确的闪存编程。

API Fapi_getDeviceInfo()和 Fapi_getSecitors ()不执行 TI-OTP 的校验和,如果 TI-OTP 中有一个或多个位错误(如果是 Fapi_getBankSecitors (),则在调用 ECC 检查时可能返回错误数据)。 但是、这些函数仅供参考、不会影响闪存编程。 如果担心返回数据的有效性,则可以首先调用 Fapi_setActiveFlashBank()来检查 TI-OTP 的完整性。 如前所述、如果校验和失败、它将返回错误代码。


18.为了擦除或编程某个扇区、我们能否从同一闪存组的不同扇区执行闪存 API?

答案。 不可以、闪存 API 函数和调用闪存 API 的应用程序函数不应从同一组执行。 它们应该从 RAM 或其他闪存组中执行(如果同一个内核存在另一个组)。

19.在 Concerto 和 F2837xD、F2837xS 和 F2807x 器件上、我们如何使用 Fapi_UserDefinedFuncations.c 文件中提供的空 Fapi_serviceWatchdogTimer()函数在闪存 API 执行期间为看门狗提供服务?

答案。 当使用诸如 Fapi_doBlankCheck()和 Fapi_doVerify()的任一闪存读取函数时、这个函数可被用来为安全装置定时器提供服务。 由于这些读取函数需要相当长的时间来读取整个闪存(当用于整个组时)、这个安全装置处理函数由 API 定期调用(每当被读取的地址超过256字(16位字)对齐的地址边界时)。 此函数在 Fapi_UserDefinedFuncations.c 文件中提供。 用户必须为其编写代码并使用应用程序进行编译。 用户可以根据需要修改此函数、但必须确保在该函数末尾的 return 语句之前包含 EALLOW (或 Concerto ARM 的 MWRALLOW)、以便闪存 API 可以根据需要写入受保护的寄存器。


请注意、此函数仅由 API 在读取函数中调用。 由于闪存 API 执行是可中断的、因此用户应用程序可以根据需要配置看门狗并在常规中断(例如、使用计时器 ISR)处对其进行服务、而不是使用此函数。 然而、当一个擦除或编程操作正在进行中时、不应该有任何来自闪存组/OTP 的读取或提取存取。 因此、当一个闪存擦除/编程操作被激活时、ISR 应该从 RAM 中执行。


如果器件是受保护的、请注意、这个功能应该在与当前擦除/编程所针对的闪存扇区安全区域一样的安全区域内执行。 这个函数应该从 RAM 或者不针对当前擦除/编程的组中执行。

20.在 Concerto 和 F2837xD 器件中,我们如何使用 Fapi_UserDefinedFunctions.c 文件中提供的 Fapi_setupBankSectorEnable()和 Fapi_setupBankSectorEnable()?

答案。 用户不应修改这些函数并按原样编译它们、即使这些函数在 Fapi_User 定义的 functions.c 文件中提供。 这些函数不会合并到库中、而是在用户定义部分中提供、以在共享通用代码的 TI 器件之间维护相同的代码。 这些函数会合并到后续器件中的库中。 如果器件是受保护的、请注意、这些功能应该在与当前擦除/编程所针对的闪存扇区相同的安全区域内执行。 这些函数应该从 RAM 或者不针对当前擦除/编程操作的内存组中执行。

21.为什么 C28x Fapi_issueProgrammingCommand()的数据缓冲区大小为16位字,而 Fapi_doVerify()的数据缓冲区大小为32位字?

答案。 由于闪存读取总线宽度为128位、32位验证将平衡性能和灵活性、因此提供了32位验证选项。 当只对16位进行编程时、您可以将数据与闪存的其他16位数据相加、以便在对32位进行编程后进行验证或验证。  请注意、也使用32位字读取来执行空白检查。  因此、用户应用程序应以32位字的形式发送长度以用于验证和空白检查功能。

22.当在 F2837xS 双组器件中使用闪存 API 时、为什么当两组被分配给同一个内核时、我们需要在两组之间切换泵信号量?

答案。 尽管两个组都连接到同一个内核、但每个组都有自己的 FMC (与只有一个 FMC 的 F28004x 双组器件不同)、因此应使用泵信标将泵连接到相应的 FMC 以执行擦除/编程操作。 此外、出于同样的原因、只要 F2837xS 中针对擦除/编程操作更改目标闪存组、就应该使用适当的参数调用 fapi_initiataleAPI ()和 fapi_setActiveFlashBank()函数(F28004x 中不需要此操作、因为只有一个 FMC)。

23.为什么 F2837xS 和 F28004x 器件不支持 Fapi_getDeviceInfo()?

答案。 每一个器件型号(PARTID)的数据手册中都提供了组数、引脚数、存储器大小等信息。 用户应用程序无需此函数即可推断这些详细信息。

24.为什么 F2837xS 和 F28004x 器件不支持 Fapi_getBankSectors ()?

答案。 每个器件型号(PARTID)的数据手册中提供了诸如组/扇区的起始地址和扇区大小等信息。 用户应用程序无需此函数即可推断这些详细信息。

25.为什么 F2837xS 和 F28004x 器件不支持 Fapi_doMargini()? F2837xD API 支持此功能、但建议仅使用正常读取模式–为什么?

答案。 在 F2837xD 中、此函数用于使用用户选择的裕量读取模式返回用户选择的 Flash 存储器范围中的数据。 但是、TI 决定不支持更多器件的读取裕度模式、因为针对这个闪存技术的经验数据显示了可靠的闪存行为。 因此、TI 建议用户在 F2837xD 中使用正常读取模式。 之后、当为 F2837xS 和 F28004x 器件发布闪存 API 时、此函数会被删除、因为用户应用程序可以在正常模式(默认)下自行读取闪存。

26.使用 Fapi_CalculateEcc()获得的 ECC 似乎不正确–为什么?

答案。 对于 C28x、请确保为该函数提供的地址被左移1位位置。 FMC 需要一个字节地址用于 ECC 计算、因此在 F28M35x、F28M36x、F2837xD、F2837xS 和 F2807x 器件中将此函数用于 C28x 时需要左移。 对于其余器件、API 在计算此函数中的 ECC 之前负责将地址左移。


使用 Fapi_DataAndEcc 编程模式时、我知道我可以对64位(对齐)或128位(对齐)进行编程。 如果起始地址是64位对齐但不是128位对齐、那么只能同时对四个16位字进行编程。 在这种情况下、我应该如何提供 ECC 字节(因为 C28x 是16位寻址模式)?

答案。 pu16EccBuffer 的 LSB (Fapi_issueProgrammingCommand()的第4个参数)对应于低64位、而 pu16EccBuffer 的 MSB 对应于128位对齐存储器的高64位。 因此,用 ECC 值填充高位字节,并在传递给 Fapi_issueProgrammingCommand()的16位 ECC 字中将低位字节保留为0xFF。 请注意,u16EccBufferSizeInBytes (Fapi_issueProgrammingCommand()的第5个参数)应初始化为1,因为在这种情况下只提供一个字节的 ECC。

使用 Fapi_EccOnly 编程模式时、能否对较低的 ECC 字节(ECC 对应于128位对齐存储器的低64位)和较高的 ECC 字节(ECC 对应于128位对齐存储器的高64位)进行编程 或者我应该同时对这两种方法进行编程?

答案。 此模式可编程2个字节(ECC 存储器中某个位置的 LSB 和 MSB)或1个字节(ECC 存储器中某个位置的 LSB)。 不能单独对 MSB 进行编程。 如果必须对 MSB 进行编程、则将现有 LSB (存储器中)添加到 ECC 缓冲器中、并将 LSB 和 MSB 一起编程。

29.在 Fapi_issueProgrammingCommand()中使用 Fapi_EccOnly 编程模式时,我们应该提供闪存主阵列地址还是相应的 ECC 地址?

答案。 即使为程序操作提供了 ECC 字节、也应提供闪存主阵列地址(对应于 ECC 地址)。


30.Concerto 和 F28004x API 中提供的 Fapi_issueProgrammingCommandForEccAddresses()函数的用途是什么?

答案。 当您希望通过提供 ECC 空间地址单独对 ECC 数据进行编程时、请使用此函数。 请注意,fapi_issueProgrammingCommand()获取主数组地址,而 fapi_issueProgrammingCommandForEccAddresses()获取 ECC 空间地址。 当对具有单独 ECC 段(由链接器 ECC 选项或任何方法生成)且包含 ECC 地址和 ECC 数据的输出文件进行流式传输时、此功能非常有用。 在这种情况下、此函数可用于直接使用 ECC 地址对流式 ECC 数据进行编程–无需将 ECC 地址转换为主阵列地址。


31.为什么 F2837xD、F2837xD 和 F2807x 器件中没有提供 Fapi_issueProgrammingCommandForEccAddresses()函数?

答案。 这些器件中的 ECC 空间位于较高的地址空间(超过22位的地址)。 为这些器件开发 API 时、far 指针尚不可用、因此不支持此函数。 如果要在已知 ECC 地址对 ECC 数据进行编程,可以使用 Fapi_remapEccAddress()将中的 ECC 地址重新映射到闪存主阵列地址,然后使用 Fapi_issueProgrammingCommand()和 Fapi_EccOnly 模式进行编程。


32。在 F28M35x 和 F28M36x 器件中、我们能否通过在 C28x 内核上执行闪存 API 来对 M3闪存组进行编程?

答案。 不可以、只能通过从 M3 RAM 执行 M3闪存 API 来对 M3闪存组进行编程。


33.在 F28M35x 和 F28M36x 器件中、我们能否通过在 M3内核上执行闪存 API 来对 C28x 闪存组进行编程?

答案。 不可以、只能通过从 C28x RAM 执行 C28x 闪存 API 来对 C28x 闪存组进行编程。


34.在 F2837xD 器件中,我们能否通过在 CPU2内核上执行闪存 API 来对 CPU1闪存组进行编程?

答案。 不可以、CPU1闪存组只能通过从 CPU1 RAM 执行闪存 API 来进行编程。


35.在 F2837xD 器件中、我们能否通过在 CPU1内核上执行闪存 API 来对 CPU2闪存组进行编程?

答案。 不可以、只有通过从 CPU2 RAM 执行闪存 API、才能对 CPU2闪存组进行编程。


36.如何将闪存 API 从闪存复制到 RAM 以从 RAM 执行?

答案。 请查看 C2000Ware 中提供的闪存 API 使用示例(适用于 Concerto 器件的 controlSUITE)。 在示例项目中、您将注意到闪存 API 函数是从 RAM 执行的。 从示例中观察以下内容:

(a)示例中使用的链接器命令文件、将闪存 API 库分配给.TI.ramfunc 段、该段具有闪存加载地址和 RAM 运行地址。

(b)示例的 main 函数调用 memcpy()、在上述段的内容被执行之前将其从闪存复制到 RAM 中。


37.我们可以使用闪存 API 对 OTP 进行编程吗?

答案。 是的、正如闪存 API 参考指南中提到的、OTP 可通过使用闪存 API 进行编程。 编程闪存与 OTP 的 API 函数用法没有任何区别。 但是、请注意 OTP 不能被擦除。 确保查看器件的数据手册和 TRM、以了解 OTP 中的存储器映射以及 OTP 中可供用户编程或使用的字段。 此外、在 F2837xD、F2837xS、F2807x 和 F28002x 器件中、请注意 DCSM OTP 编程必须与128位地址边界对齐、每个128位字只能编程一次。 例外情况如下:

a:DCSM OTP 中的 DCSM Zx-LINKPOINTER1和 Zx-LINKPOINTER2值应一起编程、并且可以在 A 上编程为1位
所需的时间。
b:DCSM OTP 中的 DCSM Zx-LINKPOINTER3值可按照 DCSM 操作的要求、一次编程为1位。

此外、请注意 OTP 中的保留字段不应编程。


38.除了使用闪存 API 库外,还有其他方法可以访问闪存状态机的寄存器,以便在运行时对闪存进行编程或擦除?

答案。 不可以、闪存 API 库是通过应用程序擦除/编程闪存的唯一方法。

39.为什么没有为这些设备提供删除恢复算法?  耗尽是否适用于这些器件中的闪存?  

答案。  在 C2000 F05闪存器件中、擦除期间的功率损耗会导致深度耗尽、从而使器件无法恢复。  这些最新器件不是这种情况-删除不适用于这些新器件中使用的闪存技术。  因此、我们没有提供删除恢复算法。  另请注意、擦除这些器件期间的电源故障不会导致永久锁定(全0密码)。  用户可以重新擦除并继续对闪存进行编程。  但是、如果在程序运行期间发生电源故障、则可能会损坏闪存/ OTP。  如果损坏的发生方式使所有0都在密码位置编程、则器件不可恢复。  如果损坏不会导致所有0密码、则如果尚未对 OTP 中的 PASSWORDLOCK 进行编程、则可以读取器件密码位置。  但是、如果损坏发生在其他 OTP 字段中、例如与引导相关的字段或链接指针(在 DCSM 器件中)等、则器件可能无法使用     

对于 TI 已发布的 PCN20180523001.1 (TMS320F2837x 使用"F65 Process"闪存代替"F021 Process"闪存)、我们是否需要使用新的闪存 API 库?

答案。 否、闪存 API 库不变。 您可以继续使用 C2000Ware 中提供的相同闪存 API 库(F021_API_F2837xD_FPU32.lib)、该库位于 C2000Ware_x_xx_xx_xx\libraries\flash_api\f2837xd\lib。

41.我们如何在用户 OTP 中对字段进行编程?

答案。 如果要将 OTP 中的任何内容(如 BOOTCTRL)作为可执行文件的一部分进行编程、可以使用#pragma DATA_SECTION 指令定义常量变量(如下面显示的 Z1_BOOTCTRL_VALUE)并将该变量分配到段(如下面显示的 Z1_BOOTCTRL_SECTION)。

#pragma DATA_SECTION (Z1_BOOTCTRL_VALUE、"Z1_BOOTCTRL_SECTION);
volatile const long Z1_BOOTCTRL_Value = 0x00000C5A;

在链接器命令文件中、应使用源地址和长度(如下面显示的 Z1_BOOTCTRL_OTP)定义存储器映射段、以便可以将段映射到该段。

内存
{
第1页 :
Z1_BOOTCTRL_OTP  :origin = 0x7801E,length = 0x2
部分
{
Z1_BOOTCTRL_SECTION :> Z1_BOOTCTRL_OTP、PAGE = 1.



如果您希望在开发过程中对其进行一次编程、但还不需要将其作为可执行文件的一部分、则可以使用 CCS 片上闪存插件 GUI (CCS 调试视图->工具->片上闪存)对用户 OTP 字段进行编程。

42.这个问题只适用于 F28M35x 和 F28M36x 器件。  我们错误地在闪存的 DCSM 密码位置对所有的0进行了编程。  是否仍有解锁器件的方法?

答案。 除非您可以从安全 RAM 执行闪存 API 来擦除所有0密码编程所在的扇区、否则无法解锁器件。  它被永久锁定。  

--

Vamsi Gudivada

C2000系统软件工程

C2000培训视频:https://training.ti.com/search-catalog/field_language/ZH-CN?keywords=C2000&start%5Bdate%5D=&end%5Bdate%5D=

C2000培训小程序码