立即注册
查看: 2179|回复: 0

[原创] mt2523 How to use dwt to monitor memory corruption

已绑定手机
发表于 2017-9-6 16:00:00 | 显示全部楼层 |阅读模式 来自 广东省深圳市
[DESCRIPTION]


DWT(Data Watch Point) feature is a powerful tool which is used to detect the monitored address at run time.
–For abnormal memory corruption debugging
–For unexpected memory access detection
when dwt detect the memory r/w you set, system will trigger debug monitor excetption then we can get memorydump uart log to analysis.


usage sop:
1)add the 2 source file(hal_dwt.c,hal_dwt.h)into project to compile, file at FAQ tail.
2)add the following code in the file end
:<sdk_root>/kernel/service/src_core/exception_handler.c void Debug_Monitor_Handler(uint32_t stack[])
{
printf("\n\rIn Debug Monitor Fault Handler\n\r");
stackDump(stack);
memoryDumpAll();
#if DEBUGGER_ON
__ASM volatile("BKPT #01");
#else
while (1);
#endif
}
#if defined(__GNUC__)
__EXHDLR_ATTR__ void DebugMon_Handler(void)
{
__asm volatile
(
"MOV r12, lr \n"
"bl CommonFault_Handler \n"
"bl Debug_Monitor_Handler \n"
);
}
#endif
#if defined (__CC_ARM)
__EXHDLR_ATTR__ void DebugMon_Handler(void)
{
PRESERVE8
mov r12, lr
bl __cpp(CommonFault_Handler)
bl __cpp(Debug_Monitor_Handler)
}
#endif
#if defined (__ICCARM__)
#pragma location=".ram_code"
void DebugMon_Handler(void);
__EXHDLR_ATTR__ void DebugMon_Handler(void)
{
__asm volatile
(
"mov r12, lr \n"
"bl CommonFault_Handler \n"
"bl Debug_Monitor_Handler \n"
);
}
#endif
3)call dwt_init() in project main()
<sdk_root>\project\mtXXXX_hdk\apps\<your_projcet>\src\main.c
#include"hal_dwt.h"
int main()
{
system_init();
dwt_init(); // call init function
}
3. call request_dwt_watchpoint()&enable_dwt_comp() to enable monitor
Be careful: when expected normal read/write, should call disable_dwt_comp() to disable
monitor, or system will also trigger exception. after normal read/write we need
recallenable_dwt_comp().
9.4-9.png

example

See this sample in hal_dwt.c
9.4-10.png
Source code
hal_dwt.c :
#include<FreeRTOS.h>
#include<stdio.h>
#include<string.h>
#include<task.h>
#include<core_cm4.h>
#include<hal_dwt.h>
extern UBaseType_t uxTaskGetEndOfStack(TaskHandle_t xTask);
typedef struct {
int enable;
uint32_t comp_val;
uint32_t mask;
uint32_t mask_size;
DWT_FUNC_TYPE func;
} dwt_comp_setting_t;
static dwt_comp_setting_t dwt_comp[4];
static int DWT_NUMCOMP;
/* reset all comparators' setting */
static void dwt_reset(void)
{
DWT->MASK0 = 0;
DWT->MASK1 = 0;
DWT->MASK2 = 0;
DWT->MASK3 = 0;
DWT->COMP0 = 0;
DWT->COMP1 = 0;
DWT->COMP2 = 0;
DWT->COMP3 = 0;
DWT->FUNCTION0 &= !DWT_FUNCTION_FUNCTION_Msk;
DWT->FUNCTION1 &= !DWT_FUNCTION_FUNCTION_Msk;
DWT->FUNCTION2 &= !DWT_FUNCTION_FUNCTION_Msk;
DWT->FUNCTION3 &= !DWT_FUNCTION_FUNCTION_Msk;
}
void dwt_init(void)
{
/* enable debug monitor mode */
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_MON_EN_Msk)) {
CoreDebug->DEMCR |= (CoreDebug_DEMCR_MON_EN_Msk |
CoreDebug_DEMCR_TRCENA_Msk) ;
}
printf("DWT_CTRL Init: 0x%lx \n\r", DWT->CTRL);
DWT->CTRL |= DWT_CTRL_EXCTRCENA_Msk;
printf("DWT_CTRL Init Done: 0x%lx \n\r", DWT->CTRL);
DWT_NUMCOMP = DWT->CTRL >> DWT_CTRL_NUMCOMP_Pos;
/*
The maximum mask size is IMPLEMENTATION DEFINED. A debugger can write
0b11111 to this
field and then read the register back to determine the maximum mask size
supported.
*/
DWT->MASK0 |= 0x1f;
DWT->MASK1 |= 0x1f;
DWT->MASK2 |= 0x1f;
DWT->MASK3 |= 0x1f;
dwt_comp[0].mask_size = DWT->MASK0;
dwt_comp[1].mask_size = DWT->MASK1;
dwt_comp[2].mask_size = DWT->MASK2;
dwt_comp[3].mask_size = DWT->MASK3;
printf("DWT has %d comparators, those supported mask size are: [0]%lx
[1]%lx [2]%lx [3]%lx \n\r",
DWT_NUMCOMP, dwt_comp[0].mask_size, dwt_comp[1].mask_size,
dwt_comp[2].mask_size, dwt_comp[3].mask_size);
dwt_reset();
printf("Init DWT OK! \n\r");
return;
}
void dump_dwt_status(void)
{
printf("DHCSR:0x%lx, DEMCR:0x%lx \n\r", CoreDebug->DHCSR, CoreDebug-
>DEMCR);
printf("DWT_CTRL: 0x%lx \n\r", DWT->CTRL);
printf("COMP0: %8lx \t MASK0: %8lx \t FUNC0: %8lx \n\r", DWT->COMP0, DWT-
>MASK0, DWT->FUNCTION0);
printf("COMP1: %8lx \t MASK1: %8lx \t FUNC1: %8lx \n\r", DWT->COMP1, DWT-
>MASK1, DWT->FUNCTION1);
printf("COMP2: %8lx \t MASK2: %8lx \t FUNC2: %8lx \n\r", DWT->COMP2, DWT-
>MASK2, DWT->FUNCTION2);
printf("COMP3: %8lx \t MASK3: %8lx \t FUNC3: %8lx \n\r", DWT->COMP3, DWT-
>MASK3, DWT->FUNCTION3);
return;
}
/*
@param addr_base: address for data accesses or instruction fetches
@param addr_mask: the size of the ignore mask applied to address range
matching
@param func: which kind of compared accesses will generate watchpoint
debug event
@return val: compator N for address comparison functions
!! Note: the addr_base should be 2^(addr_mask) byte alignment, otherwise
the behavior is UNPREDICTABLE !!
*/
int request_dwt_watchpoint(uint32_t addr_base, uint32_t addr_mask,
DWT_FUNC_TYPE func)
{
int index;
if (addr_base & addr_mask) {
printf("Fail: The address %lx is not 2^%d alignment \n\r", addr_base,
(int)addr_mask);
return -1;
}
for (index = 0; index < DWT_NUMCOMP; index++) {
if (!dwt_comp[index].enable) {
break;
}
}
if (index >= DWT_NUMCOMP) {
printf("Fail: All DWT compators are already in used \n\r");
return -1;
}
dwt_comp[index].comp_val = addr_base;
dwt_comp[index].mask = (addr_mask > dwt_comp[index].mask_size) ?
dwt_comp[index].mask_size : addr_mask;
dwt_comp[index].func = func;
return index;
}
/*
@param index: compator N
*/
int enable_dwt_comp(int index)
{
uint32_t offset;
if (index > DWT_NUMCOMP) {
printf("DWT do NOT support comparator[%d]! \n\r ", index);
return -1;
}
offset = (0x10 * index) / 4; // pointer size = 4 bytes
*(&DWT->COMP0 + offset) = dwt_comp[index].comp_val;
*(&DWT->MASK0 + offset) = dwt_comp[index].mask;
*(&DWT->FUNCTION0 + offset) = (*(&DWT->FUNCTION0 + offset) &
DWT_FUNCTION_FUNCTION_Msk) | dwt_comp[index].func;
dwt_comp[index].enable = 1;
return 0;
}
/*
@param index: compator N
*/
int disable_dwt_comp(int index)
{
uint32_t offset;
if (index > DWT_NUMCOMP) {
printf("DWT do NOT support comparator[%d]! \n\r ", index);
return -1;
}
offset = (0x10 * index) / 4; // pointer size = 4 bytes
if (*(&DWT->FUNCTION0 + offset)) {
*(&DWT->FUNCTION0 + offset) &= !DWT_FUNCTION_FUNCTION_Msk;
dwt_comp[index].enable = 0;
} else {
printf("DWT comparator[%d] is not enabled! \n\r ", index);
}
printf("COMPATOR %d is disabled \n\r", index);
return 0;
}
int32_t stack_protector(TaskHandle_t task_handler)
{
uint32_t stack_end_address;
uint32_t compator;
stack_end_address = uxTaskGetEndOfStack(task_handler);
printf("stack address:0x%x\n", stack_end_address);
compator = request_dwt_watchpoint(stack_end_address, 0x2, WDE_DATA_WO);
if (compator >= 0) {
printf("Request COMPATOR %d \n\r", compator);
enable_dwt_comp(compator);
#if 0
dump_dwt_status();
#endif
} else {
printf("Request COMPATOR Fail! \n\r");
}
return 0;
}
hal_dwt.h :
#ifndef __HAL_DWT_H__
#define __HAL_DWT_H__
typedef enum { // now only suppuort for EMITRANGE=0, CYCMATCH = 0
COMP_DISABLE = 0,
WDE_INST = 4, // 0x0100: Generate PC watchpoint debug event whem
instruction fetches
WDE_DATA_RO, // 0x0101: Generate watchpoint debug event when read data
accesses
WDE_DATA_WO, // 0x0110: Generate watchpoint debug event when write data
accesses
WDE_DATA_RW // 0x0111: Generate watchpoint debug event when read/write
data accesses
} DWT_FUNC_TYPE;
/* DWT APIs **********************************************************/
void dwt_init(void);
void dump_dwt_status(void);
int request_dwt_watchpoint(uint32_t addr_base, uint32_t addr_mask,
DWT_FUNC_TYPE func);
int enable_dwt_comp(int index);
int disable_dwt_comp(int index);
int32_t stack_protector(TaskHandle_t task_handler);
#endif /* __DWT_H__ */


  • 一牛网商城 一牛网直播
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

合作/建议

TEL: 19168984579

工作时间:
周一到周五 9:00-11:30 13:30-19:30
  • 扫一扫关注公众号
  • 扫一扫打开小程序
Copyright © 2013-2024 一牛网 版权所有 All Rights Reserved. 帮助中心|隐私声明|联系我们|手机版|粤ICP备13053961号|营业执照|EDI证
在本版发帖搜索
微信客服扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表