Hello everyone,
The problem: when the backup watchdog is 'exercised' to confirm that it is operating properly, it causes a system freeze that is not recoverable unless I cycle power. Obviously I desired it to cause the system to reset.
The setup: (a bit convoluted) I have a codewarrior pre-ecliple project that is a bootloader; suffice to say that I start up the backup watchdog in this bootloader, and have test it to successfully cause a reboot. Once the system jumps from this code into my main code, which is a Codewarrior 10 project w/MQX, I continue to feed the watchdog during normal operation using identical code to that present in the bootloader:
//------------------------------------------------------------------------------
// watchdog_task.c
//
// Task to control the hardware watchdog; will force a reset of the system if
// something causes this task to crash.
//------------------------------------------------------------------------------
#include <mqx.h>
#include <bsp.h>
#include "task_template.h"
#include "watchdog_task.h"
//------------------------------------------------------------------------------
// private defines
//------------------------------------------------------------------------------
// point directly at the watchdog registers. For some reason MQX does not supply
// a way to access these particular registers within the IPSBAR
//#define WATCHDOG_TASK_WCR (*(volatile uint_16 *)(0x40140000))
//#define WATCHDOG_TASK_WMR (*(volatile uint_16 *)(0x40140002))
//#define WATCHDOG_TASK_WSR (*(volatile uint_16 *)(0x40140006))
//------------------------------------------------------------------------------
// global variables
//------------------------------------------------------------------------------
extern FILE_PTR g_ittyb_fptr;
//------------------------------------------------------------------------------
// watchdog_task
//
// Handles setting up and feeding the watchdog.
//------------------------------------------------------------------------------
void watchdog_task(uint_32 parameter) {
VMCF5225_STRUCT_PTR mcf5225_ptr;
VMCF5225_WATCHDOG_STRUCT_PTR w_ptr;
_int_disable();
// initialize the watchdog registers - grab IPSBAR
mcf5225_ptr = _PSP_GET_IPSBAR();
w_ptr = (VMCF5225_WATCHDOG_STRUCT_PTR)0x40140000;
// set BWCR register with proper values for the clock source
mcf5225_ptr->CLK.BWCR = (0 << 0); // the source for the BWT is half the system frequency
// determine the desired timeout period and write it to WMR
// tau = 25 nS
// T = [(WM + 1) * 4096 + 4] * tau = 5 seconds
w_ptr->WMR = 0xBEBB;
//WATCHDOG_TASK_WMR = 0xBEBB;
// watch-dog timer control register
//WATCHDOG_TASK_WCR = (1 << 4) | // stop on STOP mode
w_ptr->WCR = (1 << 4) | // stop on STOP mode
(1 << 3) | // stop on WAIT mode
(1 << 2) | // stop on DOZE mode
(1 << 0); // enable BACKUP_WATCHDOG_TIMER
while(TRUE) {
_int_disable();
// feed the watch-dog
w_ptr->WSR = 0x5555;
w_ptr->WSR = 0xAAAA;
//WATCHDOG_TASK_WSR = 0x5555;
//WATCHDOG_TASK_WSR = 0xAAAA;
_int_enable();
// wait
fprintf(g_ittyb_fptr, "fed\n");
_time_delay(2000);
}
}
//------------------------------------------------------------------------------
I was experimenting with enabling/disabling interrupts, and using the w_ptr instead of the directly accessed registers, but I get the same results either way.
Anyway, what I think the problem may be, is that when the system tries to reset once it is in the main code, it jumps somewhere incorrectly to reset; ie the reset vector is not set up properly. I don't know where this is set or how to check or change it.
Here is my linker command file for the MQX project:
MEMORY
{
## intflash (RX): ORIGIN = 0x00000000, LENGTH = 0x00080000
## sram (RW): ORIGIN = 0x20000000, LENGTH = 0x00010000
vectorrom (RX): ORIGIN = 0x00008000, LENGTH = 0x00000400
cfmprotrom (RX): ORIGIN = 0x00008400, LENGTH = 0x00000020
tramp (RX): ORIGIN = 0x00008420, LENGTH = 0x00000020
rom (RX): ORIGIN = 0x00008440, LENGTH = 0x00077B00 # Code + Const data
ram (RW): ORIGIN = 0x20000000, LENGTH = 0x00010000 # SRAM - RW data
# kernel space starts after RAM variables (Location of MQX Kernel data + MQX heap)
end_of_kd (RW): ORIGIN = 0x2000FFF0, LENGTH = 0x00000000
# Boot stack reused by MQX Kernel data
bstack (RW): ORIGIN = 0x2000FA00, LENGTH = 0x00000200 # Boot stack
end_bstack (RW): ORIGIN = 0x2000FBFF, LENGTH = 0x00000000
}
KEEP_SECTION { .vectors_rom, .vectors_ram, .cfmconfig, .trampoline }
SECTIONS
{
___INTERNAL_SRAM_BASE = 0x20000000;
___INTERNAL_SRAM_SIZE = 0x00010000;
___INTERNAL_FLASH_BASE = 0x00000000;
___INTERNAL_FLASH_SIZE = 0x00080000;
___IPSBAR = 0x40000000; # Peripherals/FlexCAN
___VECTOR_TABLE_START = 0x20000000; # Runtime vector table in sram
# MQX link time configurations
___DEFAULT_PROCESSOR_NUMBER = 1;
___DEFAULT_INTERRUPT_STACK_SIZE = 1024;
___KERNEL_DATA_VERIFY_ENABLE = 0; # Test SDRAM read/write
# Flashx configurations
___FLASHX_SECT_SIZE = 0x1000;
.vectors :
{
___VECTOR_TABLE_ROM_START = .; # Runtime vector table in sram
*(.vectors_rom)
. = ALIGN (0x4);
} > vectorrom
.cfmprotect :
{
*(.cfmconfig)
. = ALIGN (0x4);
} > cfmprotrom
.trampoline :
{
*(.trampoline)
. = ALIGN (0x4);
} > tramp
.main_application :
{
*(KERNEL)
*(S_BOOT)
*(IPSUM)
*(.text)
*(.init)
*(.fini)
*(.eini)
*(.ctors)
*(.dtors)
.= ALIGN(0x4);
*(.rodata)
.= ALIGN(0x4);
*(.rdata)
. = ALIGN(0x4);
*(.exception)
. = ALIGN(0x4);
__exception_table_start__ = .;
EXCEPTION
__exception_table_end__ = .;
___sinit__ = .;
STATICINIT
.= ALIGN(0x4);
__COPY_OF_DATA = .;
} > rom
.main_application_data : AT(__COPY_OF_DATA)
{
. = ALIGN(0x10000);
___VECTOR_TABLE_RAM_START = .; # Runtime vector table in sram
*(.vectors_ram)
. = ALIGN(512);
__BDT_BASE = .;
*(.usb_bdt)
__BDT_END = .;
__START_DATA = .;
*(.data)
__END_DATA = .;
. = ALIGN(0x4);
__START_SDATA = .;
*(.sdata)
__END_SDATA = .;
. = ALIGN(0x4);
__SDA_BASE = .;
__SDA_BASE_ = __SDA_BASE;
} > ram
.main_application_bss :
{
__START_SBSS = .;
*(.sbss)
*(SCOMMON)
__END_SBSS = .;
__START_BSS = .;
*(.bss)
*(COMMON)
__END_BSS = .;
} >> ram
.kernel_data : #AT(ADDR(.main_application_bss) + SIZEOF(.main_application_bss))
{
___KERNEL_DATA_START = ALIGN(0x10);
}
.end_of_kernel_data :
{
___KERNEL_DATA_END = .;
} > end_of_kd
.boot_stack :
{
_stack_end = .;
} > bstack
.end_of_boot_stack :
{
_stack_addr = .;
__SP_INIT = .;
___BOOT_STACK_ADDRESS = .;
} > end_bstack
# Locate the ROM copy table into ROM after the initialized data
_romp_at = __COPY_OF_DATA + SIZEOF(.main_application_data);
.romp : AT (_romp_at)
{
__S_romp = _romp_at;
WRITEW(__COPY_OF_DATA); #ROM start address
WRITEW(ADDR(.main_application_data)); #RAM start address
WRITEW(SIZEOF(.main_application_data)); #size
WRITEW(0);
WRITEW(0);
WRITEW(0);
}
_flashx_start = __COPY_OF_DATA + SIZEOF(.main_application_data) +
SIZEOF(.romp);
# flashx working area spans across the whole rest of Flash memory
___FLASHX_START_ADDR = (_flashx_start + 0xfff) / 0x1000 * 0x1000;
___FLASHX_END_ADDR = ___INTERNAL_FLASH_BASE + ___INTERNAL_FLASH_SIZE;
}
/* EOF */
Also, here is my user config:
/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: user_config.h$
* $Version : 3.6.33.0$
* $Date : Jun-14-2010$
*
* Comments:
*
* User configuration for MQX components
*
*END************************************************************************/
#ifndef __user_config_h__
#define __user_config_h__
/* mandatory CPU identification */
#define MQX_CPU PSP_CPU_MCF52259
/*
** BSP settings - for defaults see mqx\source\bsp\<board_name>\<board_name>.h
*/
#define BSPCFG_ENABLE_RTCDEV 0
#define BSPCFG_ENABLE_TTYA 0
#define BSPCFG_ENABLE_TTYB 0
#define BSPCFG_ENABLE_TTYC 0
#define BSPCFG_ENABLE_ITTYA 1
#define BSPCFG_ENABLE_ITTYB 1
#define BSPCFG_ENABLE_ITTYC 0
#define BSPCFG_ENABLE_I2C0 0
#define BSPCFG_ENABLE_I2C1 0
#define BSPCFG_ENABLE_II2C0 1
#define BSPCFG_ENABLE_II2C1 1
#define BSPCFG_ENABLE_SPI0 0
#define BSPCFG_ENABLE_ISPI0 0
#define BSPCFG_ENABLE_ADC 0
#define BSPCFG_ENABLE_GPIODEV 1
#define BSPCFG_ENABLE_FLASHX 0
#define BSPCFG_RX_RING_LEN 4
#define BSPCFG_TX_RING_LEN 2
// added by SAM for the ADX and HLX projects
#define MQX_TASK_DESTRUCTION 1 // to use _task_abort and exit handlers
#define MQX_EXIT_ENABLED 0 // don't need to use _mqx_exit()
#define MQX_ROM_VECTORS 0 // not using ROM interrupt vectors (relocating into RAM)
/*
** board-specific MQX settings - see for defaults mqx\source\include\mqx_cnfg.h
*/
#define MQX_HAS_TIME_SLICE 1
/*
** board-specific RTCS settings - see for defaults rtcs\source\include\rtcscfg.h
*/
#define RTCSCFG_ENABLE_ICMP 1
#define RTCSCFG_ENABLE_UDP 1
#define RTCSCFG_ENABLE_TCP 1
#define RTCSCFG_ENABLE_STATS 0
#define RTCSCFG_ENABLE_GATEWAYS 1
#define FTPDCFG_USES_MFS 0
#define TELNETDCFG_NOWAIT FALSE
/*
** include common settings
*/
/* use the rest of defaults from small-RAM-device profile */
#include "small_ram_config.h"
/* and enable verification checks in kernel */
#include "verif_enabled_config.h"
#endif
/* EOF */
As you can see, I'm telling MQX not to use ROM vectors, and I have a section 'tramp' which contains the address to jump to for the bootloader.
Thanks for any help!
Steve
Hello,
It happen to you because registers:
WMR and WCR are written only one time for Power On Reset and If you have a bootloader you should refresh it in the bootloader in other way the system hard reset each 5 seconds.
I hope it help you.