完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我正在寻找一些在Bootloader中处理死人定时器和看门狗定时器的技巧和建议。我的情况如下:我使用PIC32 MZ2048 EFM144@ 200 MZZySyl CLKYFRQ。我的应用程序基于和声2.03B。它由一个主循环组成,它为异步外围设备提供服务。以阻塞的方式。这包括文件处理和MICROSD、TCPIP栈与Web服务器、通过SPI的EEPROM、通过QSPI的闪存。但是应用程序的主要组件是一个时间关键中断,它被称为每20ms,并完成主要功能。当访问主循环和中断之间共享的资源时,主循环禁用一些指令的中断。CONFIG(用MHC设置)是这样的:到目前为止,我使用Windows模式下的死人定时器监视中断。它被设置为具有打开窗口的16的除数的DMT22。这给出了大约19661毫秒关闭窗口,然后1311毫秒打开窗口,导致2097 2ms超时。这就足够了中断来完成它的工作了。我在中断开始时调用CurnStest1,在中断结束时调用CeleStist2。它被设置为PS1684和窗口时间为50%。这给出了8192MS的闭合窗口和8192MS的打开窗口,从而导致超时16164MS。在主回路中的一个点上,我读取100MHz核心定时器,并且在上次重置后超过1228个毫秒时,我清除了看门狗。第一次重置将在1228800000个核心定时器周期之后完成(参见下面的代码)。这就使得主循环完成大约4秒。我已经看到SD卡有时需要大约2秒。这就是为什么我有这么大。这个设置已经很好地为应用程序,我想保持它。但是,现在,一个引导加载程序被创建。不幸的是,它被创建了许多阻塞循环,等待一些东西。为了发展,Deadman Timer和看门狗定时器都关闭了。到目前为止,引导加载程序运行并能够进行固件更新。现在我想再次启用死人定时器和看门狗定时器。现在我的主要问题是,如何处理这个问题。当然,一种方法是将这两个残疾人放在引导加载程序中,并在主应用程序启动时用软件启用它们。但实际上我更喜欢在设备配置中使用它。这里有几个问题:-引导加载程序有很多阻塞循环。完全改变它将是很好的,但它目前不是我的选择。-当引导装载器移交应用程序时,时间必须适合,所以应用程序将击中监视器和死人定时器窗口的第一个明确的命令正确。目前,我的想法是创建20MS INTE。用于引导加载程序的RURBT。幸运的是,我能做到这一点,因为中断在Bootloader中总是启用的,除了很短的时间(只有几个指令)。在这20毫秒的中断中,我将以与应用程序类似的方式清除死人和看门狗定时器(例如,每12300毫秒)。当移交给应用程序时,BooDoad主代码将等待最后一次20MS中断发生。然后,它将操纵核心定时器,并将其设置为经过的时间,因为最后一个看门狗清除。然后交给应用程序。在移交给应用程序之前的点将是Bootloader和应用程序中唯一可以处理核心定时器的地方。20MS中断的最后调用将允许应用程序正确地继续20MS间隔。而核心定时器的操作将允许应用程序在正确的时间点完成看门狗定时器的第一次清除。这对你有意义吗?或者你将如何处理这个问题?
以上来自于百度翻译 以下为原文 I'm looking for some tips and recommendations for handling a deadman timer and a watchdog timer in a bootloader. My situations is a following: I'm using a PIC32MZ2048EFM144 @ 200MHz SYS_CLK_FREQ. My application is based on HARMony 2.03b. It consists of a main loop, which serves asynchronous peripherals in a blocking way. This includes file handling and microSD, TCPIP stack with web server, an EEPROM via SPI, an Flash via QSPI. But the main component of the application is a time critical interrupt, which is called every 20ms and doing the main functionality. When accessing resources which are shared between main loop and interrupt, then the main loop disables the interrupt for a few instructions. Config (set with MHC) is like this: /*** DEVCFG1 ***/ #pragma config FNOSC = SPLL #pragma config DMTINTV = WIN_15_16 #pragma config FSOSCEN = OFF #pragma config IESO = OFF #pragma config POSCMOD = EC #pragma config OSCIOFNC = OFF #pragma config FCKSM = CSECME #pragma config WDTPS = PS16384 #pragma config WDTSPGM = STOP #pragma config FWDTEN = ON #pragma config WINDIS = WINDOW #pragma config FWDTWINSZ = WINSZ_50 #pragma config DMTCNT = DMT22 #pragma config FDMTEN = ON So far I'm using a Deadman Timer in window mode for monitoring the interrupt. It is set to DMT22 with an divisor of 16 for the open window. This gives about 19,661 ms closed window, then 1,311 ms open window, resulting in 20,972ms for the timeout. This is enough for the interrupt to do its job. I'm calling ClearStep1 at the beginning of the interrupt and ClearStep2 at the end of the interrupt. Also I'm using a watchdog timer with window mode for the main loop. It is set to PS16384 and a window time of 50%. This gives a closed window of 8192ms and an open window of 8192ms, resulting in 16384ms for the timeout. At one point in the main loop I read the 100MHz core timer, and I clear the watchdog when more than 12288ms have been passed since the last reset. The first reset will be done after 1228800000 core timer cycles (see code below). So this leaves about 4 seconds for a main loop to do its stuff. I have already seen that the SD card sometimes might take about 2 seconds. That's why I have it so huge. // watch dog time out: 16384 ms // watch dog window size: 50% // watch dog open/closed window: 8192 ms // targeted reset time for watch dog: 3/4 * 16384 ms = 12288 ms // number of clock cycles till reset: // 16384ms / 1000ms/s * 3/4 * 100000000 cyc/s // overflow of core timer: 2^32 = 4294967296 = ~ 42,9 s #define TS_WTD_TILL_NEXT_RESET 1228800000 uint32_t const TS_now = ReadCoreTimer(); if ((int32_t)(TS_now - TS_wtd_next_reset) > 0) { SYS_WDT_TimerClear(); TS_wtd_next_reset = TS_now + TS_WTD_TILL_NEXT_RESET; } This setup has worked very well for the application and I would like to keep it. However, now a bootloader was created. Unfortunately it was created with many blocking loops, which wait for something. For the development both Deadman Timer and Watchdog Timer were turned off. So far the bootloader works and is able to do firmware updates. Now I would like to enable Deadman Timer and Watchdog Timer again. And the main question for me is now, how to handle this. One way of course would be to leave these two disabled for the bootloader, and enable them by software, when the main application starts. But actually I would prefer to have it in the device config. There are several problems with this: - The bootloader has a lot of blocking loops. Changing it completely would be nice, but it is currently no option for me. - When the bootloader hands over the application, the timing must fit, so the application will hit the windows of watchdog and deadman timer with its first clear commands correctly. Currently, my idea is to create a 20ms interrupt for the bootloader. Fortunately I can do this, because interrupts are always enabled in the bootloader, except for very short amounts of time (just a few instructions). In this 20ms interrupt I would clear both deadman and watchdog timer (e.g. every 12300ms) in a similar way as in the application. When handing over to the application, the boodloader main code would wait for a last 20ms interrupt to happen. Then it would manipulate the core timer and set it to the passed time, since the last watchdog clear. And then hand over to the application. The point just before handing over to the application would be the only place in both bootloader and application where I would manipulate the core timer. The last call of the 20ms interrupt would allow the application to continue with the 20ms intervals correctly. And the manipulation of the core timer would allow the application to do the first clear of the watchdog timer at the correct point in time. Does this make any sense to you? Or how would you handle this issue? |
|
相关推荐
1个回答
|
|
我现在大部分都解决了这个问题,对于Deadman Timer来说,我的计划很有效。在Bootloader中,我为中断中的死人定时器服务。Bootloader中的中断与主应用程序完全分离,所以没有问题。在启动主应用程序之前,我只是等待一个死人定时器的清除。对于看门狗定时器,我的计划不起作用。我对处理器核心定时器有误解。我假设,当BooLoad启动主应用程序时,核心定时器将继续计数。但是,正如您可以在MPLAB®XC32 C/C++编译器用户指南,Stuts7.3.4.4计数寄存器中读取的,计数寄存器在默认PIC32启动代码中被清除。因此,在启动主应用程序之前,更改引导程序中的核心定时器没有影响,因为主应用程序的启动代码清除了它。嗯,你可以替换启动代码,但我想我不想这么做。一种方法是在引导加载程序中等待一个看门狗清除,或者确保,清除是在一个短时间之前,所以主应用程序仍然会击中窗口。窗口从8192毫秒到16384毫秒,并且清除是1228 8ms。因此,这一条4096ms需要覆盖对外围设备(主要是SD卡)的阻塞调用,并且还可以覆盖自引导加载程序的一个小偏移量。但是如果引导者忽略了看门狗,那么这意味着它必须等待下一个清除,并且可能需要闲置11秒,直到它可以启动主应用程序。不是很好。当然,更好的方法是从上一次看门狗从Bootloader到主应用程序,从某种程度上获得关于时间的信息。我需要一个固定的RAM位置交接变量。现在,我只需要找出如何选择一个位置,并正确地做这件事,这样它就不会与未来的任何东西发生冲突。到目前为止,我还没有尝试过,但是找到了一些关于它的信息(例如:线程:从应用程序传递到Bootloader的HTTP://www. McCHIP.COM/FoMss/FuntPo/675 699)。
以上来自于百度翻译 以下为原文 I mostly solved this issue now. For the Deadman Timer my plan worked very well. In the bootloader I'm serving the clears for the Deadman Timer in an interrupt. Interrupts in the Bootloader are completely separate from the main application, so there is no problem. And before starting the main application, I just wait for a clear of the Deadman Timer. For the Watchdog Timer my plan did not work. I had a misunderstanding about the processor core timer. I assumed, that the core timer will continue counting, when the booloader starts the main application. But as you can read in the MPLAB® XC32 C/C++ Compiler User’s Guide, section 15.3.6.4 COUNT REGISTER, the count register is cleared in the default PIC32 start-up code. So changing the core timer in the bootloader just before starting the main application has no effect, because the start-up code of the main application clears it. Well, you could probably replace the start-up code, but I guess I don't really want to do that. One way which works is waiting in the bootloader for a watchdog clear or making sure, that the clear was just a short time ago, so the main application will still hit the window. The window goes from 8192 ms to 16384 ms, and the clear is at 12288 ms. So this leaves 4096 ms, which need to cover the blocking calls to peripherals (mainly SD card) and can also cover a small offset from the bootloader. But if the bootleader misses the watchdog clear, then this means it would have to wait for the next clear and might have to idle for maybe 11 seconds until it can start the main application. Not really nice. The better way is of course getting the information about the time since the last watchdog clear from the bootloader to the main application in some way. I need a fixed RAM location for handing over the variable. Now I just need to find out how to chose a location and do this correctly, so it won't collide with anything which in the future. I haven't tried it so far, but found some information about it (e.g. thread: Pass variable from Application to Bootloader http://www.microchip.com/forums/FindPost/675699 ). |
|
|
|
只有小组成员才能发言,加入小组>>
5253 浏览 9 评论
2038 浏览 8 评论
1958 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3219 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2267 浏览 5 评论
792浏览 1评论
688浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
617浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
686浏览 0评论
586浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 11:18 , Processed in 1.626620 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号