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.
工具与软件:
大家好、TI 专家:
我使用带 FreeRTOS 的 AM2431作为系统。 在一个线程中、我需要控制多个 GPIO 高电平/低电平信号作为控制信号来管理外设。 我使用 for 环路输出连续信号、但我注意到信号设为低电平时延迟更长。
void my_delay(uint32_t ticks) { volatile uint32_t delay; hGpio1->BANK_REGISTERS[0].SET_DATA = 0x00000400; for (delay = 0; delay < ticks; delay++) { NOP_DELAY; } hGpio1->BANK_REGISTERS[0].CLR_DATA = 0x00000400 } for (scanline = 18; scanline > 0; scanline--) { / for (channel = 16; channel > 0; channel--) { for (driver = 20; driver > 0; driver--) { value = hGpio1->BANK_REGISTERS[0].OUT_DATA; value |= (((Value1 << 1); value |= (((Value2 << 10); value |= (((Value3 << 13); value |= (((Value4 << 21); value |= (((Value5 << 22); value |= (((Value6 << 30); hGpio1->BANK_REGISTERS[0].OUT_DATA = value; my_delay(delayTime); } } }
为了使我的 GPIO 控制尽可能稳定、我没有使用vTaskDelay
。 相反,我使用了一个for
NOP_DELAY
内部循环,以防止该过程切换到其他线程。 不过、我注意到输出波形出现了一些异常。 我在延迟前后添加了一个 GPIO 切换开关、并通过使用逻辑分析仪观察该 GPIO、发现低电平时间几乎是高电平时间的两倍。 我在中找不到设置 GPIO 速度的选项syscfg
、但简单的for
循环应该不会有这种效果。 我还尝试了删除值运算、但低电平时间仍然没有减少。 是否有改进的方法?
此致、
Larry
Larry、您好!
感谢您的提问。
您能否提供有关设置的更多详细信息?
Unknown 说:系统上当前正在运行多少个线程? 每项任务的优先级是什么?
Unknown 说:但我注意到设置信号低电平时有较长的延迟您是如何捕获波形的?
请分享 GPIO 所用时间比平常更长的波形。
此致、
Tushar
尊敬的 Tushar:
感谢您的答复、
系统上当前正在运行多少个线程? 每项任务的优先级是什么?
我有五个线程、将优先级设置为一样
for
循环来控制 GPIO、我需要总共控制12个 GPIO。 为了节省时间、我会尝试通过匹配所需的值将所需数据直接写入相应的 GPIO 寄存器。 for (bit = NUM_BITS_PER_CH - 1; bit > 0; bit--) { gpioTargetValue_0 = hGpio1->BANK_REGISTERS[0].OUT_DATA; gpioTargetValue_0 &= ~mask0; gpioTargetValue_0 |= ( (rValue1_l & valueMask[bit])? (1 << UDR1_L_PIN_SHIFT):0 ) | ( (gValue1_l & valueMask[bit])? (1 << UDG1_L_PIN_SHIFT):0 ) | ( (bValue1_l & valueMask[bit])? (1 << UDB1_L_PIN_SHIFT):0 ) | ( (rValue2_l & valueMask[bit])? (1 << UDR2_L_PIN_SHIFT):0 ) | ( (gValue2_l & valueMask[bit])? (1 << UDG2_L_PIN_SHIFT):0 ) | ( (bValue2_l & valueMask[bit])? (1 << UDB2_L_PIN_SHIFT):0 ); gpioTargetValue_1 = hGpio0->BANK_REGISTERS[1].OUT_DATA; gpioTargetValue_1 &= ~mask1; gpioTargetValue_1 |= ( (rValue1_r & valueMask[bit])? (1 << UDR1_R_PIN_SHIFT):0 ) | ( (gValue1_r & valueMask[bit])? (1 << UDG1_R_PIN_SHIFT):0 ) | ( (bValue1_r & valueMask[bit])? (1 << UDB1_R_PIN_SHIFT):0 ) | ( (rValue2_r & valueMask[bit])? (1 << UDR2_R_PIN_SHIFT):0 ) | ( (gValue2_r & valueMask[bit])? (1 << UDG2_R_PIN_SHIFT):0 ) | ( (bValue2_r & valueMask[bit])? (1 << UDB2_R_PIN_SHIFT):0 ); hGpio1->BANK_REGISTERS[0].OUT_DATA = gpioTargetValue_0; hGpio0->BANK_REGISTERS[1].OUT_DATA = gpioTargetValue_1; DCLK_EN; for (uint32_t delay = 0; delay < universal_config->driver_dclk_delay; delay++) { NOP_DELAY; } DCLK_DIS; }
// hGpio1->BANK_REGISTERS[0].OUT_DATA = gpioTargetValue_0; // hGpio0->BANK_REGISTERS[1].OUT_DATA = gpioTargetValue_1;
尊敬的 Tushar:
有任何信息可以共享?
此致、
Larry
Larry、您好!
在很长 一段时间后、我捕获了一个 GPIO 在关闭时花费近57ns、打开时花费近43ns。
我没有使用任何 API 来控制 GPIO 的开/关、并直接写入寄存器地址。
这里使用的是 for 循环和逻辑运算、处理这也需要一些时间。
我的建议是、根据上述代码、您需要直接控制10个引脚、然后 在不循环的情况下在相应的寄存器中写入1或0。
例如、您需要将31引脚控制为高电平。 只需将寄存器中的直接值设置为0x80000000。
如果您需要基于某些阵列数据控制引脚、则我们不能采取任何措施、只能循环、并确保在执行此操作时不进行任何任务切换、否则还应考虑此任务切换时间。
此致、
Anil。
尊敬的 Anil:
我在另一个讨论中找到了解决方案、我在我要控制的 GPIO 地址中添加 MPU、然后速度显著 提高、感谢您的帮助。
此致、
Larry
你好 Larry ,
您是否向 MPU 区域添加了 GPIO 地址并缓存了此 GPIO 地址?
您能否分享您获得解决方案的主题?
此致、
Anil。
尊敬的 Anil:
您是否向 MPU 区域添加了 GPIO 地址并缓存了此 GPIO 地址?
是的、下面是我的设置。
您能否分享您获得解决方案的主题?
此致、
Larry
Larry、您好!
感谢以上链接和详细信息。
我需要与其他专家确认这些设置、因为大多数 SOC 外设 空间都应配置为严格排序、但此处我们配置了不同的配置、我建议至少根据 TRM 配置上述 GPIO 的大小。
例如、GPIO_0或 GPIO_1 大小应为256个字节。 因此、在上述 MPU 配置中、我们需要配置相同的大小、而不是8KB。
您能否确认延迟在上述设置下有多大改善?
您是否在 debug build 或 release build 中执行了此测试?
如果您在 debug build 中执行此测试、则在 release build 中执行测试、查看性能是否仍与 debug build 相比有所改善?
此致、
Anil。
尊敬的 Anil:
您能否确认延迟在上述设置下有多大改善?
在此设置之前、低电平状态需要1.2us、设置之后、低电平状态只需270ns。
您是否在 debug build 或 release build 中执行了此测试?
我在调试模式下测试它。
感谢您的帮助、我可以稍后使用释放模式进行测试。
此致、
Larry
你好 Larry ,
感谢分享上述结果.
如果您在释放模式下进行测试,您可能会获得更好的结果。
此致、
Anil。