主题中讨论的其他器件:TMS320F28069、 TMS320C28346、 SYSBIOS
您能否解释 TI-RTOS 内核中任何特定于 C28器件的项目?
C2000培训小程序码
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.
主题中讨论的其他器件:TMS320F28069、 TMS320C28346、 SYSBIOS
您能否解释 TI-RTOS 内核中任何特定于 C28器件的项目?
C2000培训小程序码
下面显示了大多数使用*。cfg 源代码片段的 SYS/BIOS 配置设置。 您还可以使用 XGCONF 图形配置工具配置28x 应用程序。 例如、当您打开该工具时、您会看到欢迎屏幕。 您可以单击 系统概述 按钮来查看可用 SYS/BIOS 模块的方框图。 您的应用使用的模块有一个绿色复选标记。 请注意下图中用红色圆圈标出的模块;它们具有特定于28x 器件的配置设置。
如果你单击 XGCONF 页面顶部的 Device Support 按钮、你会看到一个适用于28x 的 SYS/BIOS 模块列表。 您可以单击这些链接以查看每个模块的配置页。
请注意、某些28x 器件没有足够的内存来运行 SYS/BIOS 应用。 请参阅 SYS/BIOS 安装中的发行说明、以获得支持器件的详细、最新的列表。
如果您使用的是 Concerto 器件、本页介绍了如何将 SYS/BIOS 与 Concerto 的28x 部分结合使用。
首先、请查看具有 TI-RTOS 的器件的常规启动: https://e2e.ti.com/support/processors/f/791/p/953161/3521880。
对于28x 器件、SYS/BIOS 会安装一个名为 ti_catalog_c2800_init_Boot_init ()的可配置启动复位函数、该函数由 XDCtools 提供。 根据 ti.catalog.c2800.init.Boot 模块的配置、此函数执行以下操作:
您可以使用 C28x 引导模块配置启动复位功能的功能。 首先、在 XGCONF 中、从 SYS/BIOS 系统概述页面中选择引导模块:
您将看到28x 引导模块的配置页面。
看门狗计时器: 默认情况下、看门狗计时器处于启用状态、这意味着如果系统挂起时间足够长、看门狗计时器的8位计数器达到其最大值、则会触发系统复位。 为了防止这种情况的发生、您可以在 XGCONF 中选中"Disable the watchdog timer"(禁用看门狗计时器)框、或者使用以下配置语句:
VAR Boot = xdc.useModule('ti.catalog.c2800.init.Boot'); Boot.disableWatchdog = true;
从闪存引导: 如果您希望能够从闪存引导此应用程序、请选中 XGCONF 中的"Enable boot from FLASH"框或使用以下配置语句:
VAR Boot = xdc.useModule('ti.catalog.c2800.init.Boot'); Boot.bootFromFlash = true;
如果您将应用配置为从闪存引导、则到 c_int00入口点的长分支(lb)将放置在链接器命令文件中定义的起始段地址处。
PLL 配置: 28x 器件上的锁相环(PLL)用于保持正确的时钟速率。
注意: 在280x 和281x 器件上、XDCtools 和 SYS/BIOS 不配置 PLL。 在您的应用程序完成引导后、PLL 处于其默认状态-已绕过但未关闭。 如果您想修改这些器件上 PLL 的配置、您可以添加一个复位功能、如本步骤(2)末尾所述。
默认情况下、XDCtools 会自动为您的2802x、2803x、2806x、282xx、283xx、 或2834x 器件。 如果您想覆盖默认 PLL 配置、您可以在 XGCONF 中选中"Configure the PLL"(配置 PLL)框、并为以下参数设置值:
Boot.pllOSCCLK * Boot.pllcrDIV * 1000000) / divider
,如果 Boot.pllstsDIVSEL 为2,则分频器为2;如果 Boot.pllstsDIVSEL 为0或1,则分频器为4。 例如、以下配置语句将 PLL 配置为较低的速率。
VAR Boot = xdc.useModule('ti.catalog.c2800.init.Boot'); Boot.configurePll = true; Boot.pllOSCCLK = 8; Boot.pllcrDIV = 2; Boot.pllstsDIVSEL = 0;
用户定义的复位函数: 如果要将自己的函数添加到早期复位函数表中、可以通过在应用程序配置文件中添加如下语句来实现:
RESET = xdc.useModule('xdc.runtime.Reset'); Reset.Fxns[Reset.Fxns.length++]='&myResetFxn';
SYS/BIOS 在28x 器件上提供与在其他器件上相同的基本硬件中断功能。 此外、它还提供配置和使用外设中断扩展(PIE)块以及28x 器件支持的零延迟中断的功能。 ti.sysbios.family.c28.Hwi 模块使用特定于器件的功能来实现和扩展通用 ti.sysbios.hal.Hwi 模块。
如果只想使用通用 Hwi 模块运行时 API 和静态配置设置来管理28x 应用中的硬件中断、则应使用 ti.sysbios.hal.hwi 模块。 要使用此模块、请在代码中包含以下内容:
#include <ti/sysbios/hal/Hwi.h>
var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
或者、您可以使用 ti.sysbios.family.c28.Hwi 模块提供的28x 特定版本的运行时 API 和静态配置设置。 这些仅包括28x 的一些附加功能。 要使用此模块、请在代码中包含以下内容:
#include <ti/sysbios/family/c28/Hwi.h>
var Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi');
28x 外设中断扩展(PIE)块将多个中断源多路复用为一组更小的中断输入。 根据器件的不同、中断被分成8或16个块、并且每个组被馈入12个 CPU 中断线路中的一个(INT1至 INT12)。 每个中断都由其存储在用作 PIE 中断矢量表的专用 RAM 块中的矢量支持。 C28x 系统控制和中断参考指南 主题中链接到的参考指南更详细地描述了 PIE 块。
在处理中断时、CPU 自动提取矢量。 取矢量并保存关键 CPU 寄存器需要九个 CPU 时钟周期。 因此、28x CPU 可以快速响应中断事件。 每个单独的中断都可以在 PIE 模块内启用/禁用。
您可以使用相同的 Hwi_create() API 和 Hwi.create()静态配置方法为32个内核中断线(INT1至 INT12)和单个 PIE 中断创建 Hwi 对象。 中断编号0-32应用于内核中断线路(INT1至 INT12)、而编号32-223应用于单个 PIE 中断。
下表显示了 PIENUM (中断 ID)和 PIE 组之间的映射。 INTx.Y 是属于组 X 和组特定 ID Y 的 PIE 中断的中断号。例如、在 PIE 组2中、中断3将是 INT2.3、中断 ID 为42。 请注意、INTX.9-INTX.16列并不适用于所有器件;有关更多信息、请参阅器件的技术参考手册。
INTx.1 | INTx.2 | INTx.3 | INTx.4 | INTx.5 | INTx.6 | INTx.7 | INTx.8 | INTx.9 | INTx.10 | INTx.11 | INTx.12 | INTx.13 | INTx.14 | INTx.15 | INTx.16 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
INT1.Y | 32 | 33. | 34 | 35. | 36. | 37. | 38. | 39. | 128 | 129. | 130 | 131. | 132. | 133. | 134. | 135. |
INT2.Y | 40 | 41. | 42. | 43. | 44. | 45. | 46. | 47. | 136. | 137. | 138. | 139. | 140 | 141. | 142. | 143. |
INT3.Y | 48 | 49 | 50 | 51. | 52. | 53. | 54 | 55 | 144. | 145. | 146. | 147. | 148. | 149. | 150 | 151. |
int4.Y | 56. | 57. | 58. | 59. | 60 | 61. | 62. | 63. | 152. | 153. | 154. | 155. | 156. | 157. | 158. | 159. |
INT5.Y | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71. | 160 | 161. | 162. | 163. | 164. | 165. | 166. | 167. |
INT6.Y | 72. | 73. | 74. | 75 | 76. | 77 | 78 | 79 | 168. | 169. | 170 | 171. | 172. | 173. | 174. | 175. |
INT7.Y | 80 | 81. | 82. | 83. | 84 | 85. | 86 | 87 | 176. | 177. | 178. | 179. | 180 | 181. | 182. | 183. |
INT8.Y | 88 | 89 | 90 | 91. | 92 | 93 | 94 | 95 | 184. | 185. | 186. | 187. | 188. | 189. | 190 | 191. |
INT9.Y | 96 | 97 | 98 | 99 | 100 | 101. | 102. | 103. | 192. | 193. | 194. | 195. | 196 | 197 | 198 | 199 |
INT10.Y | 104. | 105. | 106. | 107. | 108. | 109. | 110 | 111. | 200 | 201 | 202. | 203. | 204. | 205. | 206. | 207. |
INT11.Y | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 208. | 209. | 210 | 211 | 212 | 213. | 214. | 215. |
INT12.Y | 120 | 121. | 122. | 123. | 124. | 125. | 126. | 127. | 216 | 217. | 218. | 219. | 220 | 221. | 222. | 223. |
例如、以下配置代码将函数'myHwi'插入 PIE 组5的矢量表、中断1。 如上表所示、这对应于中断 ID 64:
var hwi = xdc.useModule('ti.sysbios.family.c28.Hwi'); /* PIE 组5、中断1 */ var interruptNum = 64; var hwiParams = new Hwi.Params (); hwiParams.arg = interruptNum; hwi.create (partNum、"&myHwi"、hwiams);
除了创建 Hwi 对象来为 PIE 中断提供服务外、还可以使用 ti.sysbios.family.c28.Hwi 模块中的以下 API 来管理运行时的 PIE 中断处理:
类似的 API --Hwi_disableIER ()、Hwi_enableIER ()和 Hwi_restoreIER ()--可用于在运行时禁用、启用和恢复内核中断线(INT1至 INT12)。
Hwi_clearInterrupt () API 可用于清除中断的挂起状态。 对于28x 器件、如果中断编号是 PIE 中断编号、此函数将清除 PIEIFR 位。 如果这是一个介于1和14之间的中断编号、它会清除 IFR 位。
提供了以下附加配置参数来配置28x 中断:
您可以将位掩码传递给 Hwi.zeroLatencyIERMask 属性、以标识永远不应禁用的中断。 这样做的好处是、此类中断具有最小的中断到 ISR 执行时间。 (虽然属性名称被命名为"零延迟"、但实际上延迟被最小化、而不是零。) 使用这个设置的缺点是当 SYS/BIOS 禁用或者启用中断时、需要额外的工作来避免对这些中断进行改变。
例如、以下配置代码将 INT5和 PIE 组5多路复用为 INT5以提供最小延迟:
VAR Hwi = xdc.useModule('ti.sysbios.family.c28.Hwi'); Hwi.zeroLatencyIERMask = 0x0010;
IER 掩码中的位0对应于 INT1和 PIE 组1。 位1对应于 INT2和 PIE 组2、依此类推、直到 INT12。 位12-16用于其它用途、不应在 zeroLatencyIERMask 中置位。 在上一个示例中、0x0010的掩码会将位4置位、这对应于 INT5。
默认情况下、Hwi.zeroLatencyIERMask 属性在 XGCONF 中显示为十进制值:
请注意 、在 zeroLatencyIERMask 中设置位的 PIE 组中的所有中断都将被视为零延迟中断。
注意: 我们建议您仅在组中的所有中断都执行非 SYS/BIOS 中断处理程序时使用 zeroLatencyIERMask。 此功能最适合仅在需要极低延迟的应用中使用。
此掩码中指定的 CPU 中断(对应于16位 IER 寄存器)不会被 Hwi_disable()调用禁用、并且通常保持启用状态、除非使用 Hwi_disableIER ()或 Hwi_disablePIEIER ()显式禁用。
如果对任何中断使用零延迟模式、则用于在 SYS/BIOS 中禁用、启用和恢复中断的代码将更慢。 这是因为代码需要在 IER 寄存器中设置单独的位、而不是设置 INTM 位。 在使用此功能之前、请务必注意与使用零延迟中断相关的性能权衡。
为了整合为每个中断执行寄存器保存和恢复的代码、SYS/BIOS 提供了一个中断调度程序、该调度程序会自动为中断例程执行这些操作。 使用 Hwi 调度程序允许用 C 语言编写 ISR 函数。除了保留中断线程的上下文外、SYS/BIOS Hwi 调度程序还会编排以下操作:
默认情况下、所有由 SYS/BIOS 静态或动态创建的 Hwi 中断都被路由到中断调度程序。
如果你有一些不想被 SYS/BIOS 中断调度程序处理的中断、你应该使用 Hwi_plug ()运行时 API 来创建它们。 此类 ISR 函数直接插入到矢量表中。 Hwi_plug ()只能用于不调用任何 SYS/BIOS API 的 ISR 函数。 如果你正在使用 Hwi_plug ()、你还应该注意在已经并且不由 SYS/BIOS 中断调度程序管理的 ISR 之间潜在的时序和资源访问问题。
如果将 Hwi_plug ()用于任何 PIE 中断,则应用程序必须手动清除相应 PIE 块的 CPU 确认位,然后才能从该块中进一步发生中断。 SYS/BIOS 中断调度程序通常负责处理此问题。 (这与 DSP/BIOS 5不同、在该应用程序必须确认中断。) 如果您的应用程序包含带有 HWI 实例的传统代码、则在返回之前、HWI 函数还必须手动清除 CPU 确认位。
下面是通过 Hwi_plug ()添加零延迟中断的 F28379D 示例: /cfs-file/__key/communityserver-discussions-components-files/171/4555.C28_5F00_zero_5F00_latency.pdf
在28x 器件上创建 Hwi 对象时、使用的 Hwi.Params 结构中的参数有两个限制:
28x 器件有三个32位定时器-定时器0至定时器2。 默认情况下、SYS/BIOS 使用其中两个定时器、一个用于时钟模块、一个用于时间戳模块。 通常、SYS/BIOS 使用的定时器为定时器0和定时器1、但是如果您的应用使用定时器进行自身的处理、SYS/BIOS 将在必要时使用定时器2。
您可以通过配置 ti.sysbios.family.c28.TimestampProvider 模块来控制 SYS/BIOS 使用的28x 计时器。 默认情况下、SYS/BIOS 使用时钟和时间戳模块的前两个可用定时器。 您可以指定时间戳模块应使用计时器2、例如具有以下配置代码(在.cfg 文件中):
VAR TimestampProvider = xdc.useModule('ti.sysbios.family.c28.TimestampProvider'); TimestampProvider.timerId = 2;
以下配置代码使时间戳模块使用与时钟模块相同的28x 计时器:
VAR TimestampProvider = xdc.useModule('ti.sysbios.family.c28.TimestampProvider'); TimestampProvider.useClockTimer = true;
共享时钟计时器会使更多计时器可用于其他用途、但会降低计时器 API 的效率。 如果使用时钟计时器进行时间戳,则时间戳的计算公式为: (Clock ticks) x (tick period) + (current timer count)
因此,时间戳的最大值限制为 2^32 x (Clock tick period)
。
如果对时间戳使用单独的计时器(默认行为)、则时间戳的最大值为 2^64
、并且不需要执行乘法运算来检索该值。
对于 Concerto 器件、应使用 ti.sysbios.family.[c28|arm].f28m35x.TimestampProvider 模块、这些模块访问可由28x 或 M3内核读取的共享时间戳计数器。
在内部、28x 定时器从"周期"向下计数到0;然而、Timer_getCount () API 从周期中减去定时器计数器值、这样它向上计数而不是向下计数。
ti.sysbios.family.c28.Timer 模块配置允许您指定一个掩码来标识可供计时器模块使用的 CPU 计时器。 默认情况下、此掩码设置为7 (二进制为111)、这意味着计时器0、1和2可用。 SYS/BIOS 使用的定时器不需要从这个掩码中省略、但是如果您的应用使用一个特定的28x 定时器、您应该从这个掩码中省略该定时器的位。
如果您创建特定于器件的 ti.sysbios.family.c28.计时 器模块的实例(而不是通用 ti.sysbios.hal.计时 器模块的实例)、您还可以配置下面圆圈内的28x 参数:
Timer ID 参数指定此实例应使用哪个28x CPU 定时器。 如果您选择任何、将使用第一个可用的计时器。 请记住、28x 器件有3个计时器、SYS/BIOS 默认使用2个计时器。
预分频因子参数使用28x 器件的16位预分频器设置计时器节拍的长度。 如果指定的预分频因子为10、则每11个周期将发生一次计时器节拍。 如果这个定时器被用作一个计数器、预分频因子决定计数之间的周期。 否则、预分频因子可被用于实现更长的定时器周期;在指定预分频的情况下、实际周期为 period * prescale+1
28x 定时器模块提供以下 API 来访问预分频器:
自由运行和软停止参数允许您指定计时器在软件断点处的行为方式、就像您可以在 Code Composer Studio 中设置的那些断点一样。 如果"free"标志被设定为1、当程序在一个软件断点处暂停时、定时器将继续正常运行;如果"free"被设定为1、则"soft"标志的值无关紧要。 如果"free"为0、"soft"为1、则定时器将运行至0、然后停止。 当"free"为0且"soft"为0 (默认值)时、定时器在软件断点处停止。
例如、以下配置代码创建一个周期为2000微秒、预分频值为999的28x 定时器。 因此、计时器每1000个周期(预分频+1)计时一次、运行 myTimerFxn ()函数的实际周期为2、000、000微秒(2秒)。 当 Code Composer Studio 中出现软件断点时、此计时器将继续运行。
var ti_sysbios_family_c28_Timer = xdc.useModule('ti.sysbios.family.c28.Timer'); var my28xTimerParams = new ti_sysbios_family_c28_Timer.Params (); my28xTimerParams.instance.name ="my28xTimer"; my28xTimerParams.period = 2000; my28xTimerParams.prescale = 999; my28xTimerParams.emulationModeInit.free = 1; my28xTimerParams.emulationModeInit.soft = 0; Program.global.my28xTimer = ti_SYSBIOS_family_c28_Timer.create (空、"&myTimerFxn"、my28xTimerParams);
与其他特定于器件的计时器模块一样、您也可以为将由该计时器中断触发的 Hwi 对象指定创建参数。
请记住、28x 器件上的尺寸是以16位字表示的。 最小可寻址数据单元(MADU)为16位。
由于28x 器件上的可用内存量相对较小、因此减少应用程序所用的内存量可能很重要。 如果应用程序占用空间太大而无法放入 RAM、则在构建应用程序时可能会遇到错误。 请参阅 SYS/BIOS 用户指南 (SPRUEX3)的"最大限度地减少应用程序占用空间"附录、以了解减少 SYS/BIOS 所用内存量的多种方法。
由于28x RAM 有限、您可能需要考虑从闪存存储器运行应用、并仅将关键段复制到 RAM 以加快执行速度。
系统堆栈和所有任务堆栈必须位于内存中的第0页内、内存地址为0至0xFFFF。 如果将任务堆栈放置在其他存储器位置、则会产生错误。 默认情况下、任务堆栈放置在.ebss:taskStackSection 部分中、该部分位于第0页。 本节是.ebss 的一个子段、允许将 SYS/BIOS 与 CCS 为28x 器件提供的链接器.cmd 文件一同使用。
taskStackSection 包含用于静态创建的任务的堆栈。 taskStackSection 的大小计算为 (Task.defaultStackSize * number of static tasks) + system heap size
。
要减小此部分的大小、您可以执行以下操作:
当你减少堆和堆栈大小时、你需要注意堆的"内存不足"错误和堆栈的过度运行。 ROV 工具有助于监控堆栈和堆使用情况。