Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1524147
  • 博文数量: 226
  • 博客积分: 3997
  • 博客等级: 少校
  • 技术积分: 2369
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-19 17:26
个人简介

Never save something for a special occasion. Every day in your life is a special occasion.

文章分类

全部博文(226)

文章存档

2018年(5)

2017年(11)

2016年(1)

2015年(17)

2014年(14)

2013年(30)

2012年(5)

2011年(52)

2010年(107)

分类:

2010-12-21 20:12:53

ht-ide3000调试助手 —— 实现 go funcName
 
提要:
命令行的好处在于快速、灵活。holtek单片机开发环境提供一个简单的命令行工具,其中有条非常有用的命令 go 运行到指定地址,通常用户会希望它是这样 “go 运行到指定程序”,但ide3k没这么做。这里借助 bat,vbs,perl 来改变这个残忍的现实。
 
正文:

Holtek 单片机开发环境 ht-ide3k 目前最高版本 V7.33 仍然存在一个令人抓狂的 Bug :
断点与程序行关联,而不是程序代码!
这个bug加上其它缺陷,有时令人实在不爽:
1、可以设置最多9个断点,同时只有3个有效(即enable/disable);
2、打开断点列表,断点名字很不形象;
3、一个功能简单,而且不支持扩展的命令行调试工具 ht-command.exe
 
尤其要提的是,第3点很不友好。 执行命令 h 可获得帮助信息,有一些比较有用的命令,如
执行到指定地址:go addr
读取内存:dr addr
写内存:dw addr “string”
 
我不知道别的用户是怎么用的~ 我猜无非是这样:
执行到指定地址:go 00c2
读取内存:dr 0042
写内存:dw 0042 “1234”
因为ht-command.exe只允许这么使用。至于00c2之类的地址,用户可以查map文件获得!
好吧,当我要暂停程序,希望它运行到函数 funcName() 时我从 map 文件查到它的地址 funcAddr
(不用想,这种事情肯定是由脚本/程序来完成),然后回到 ht-command.exe ,执行下面的命令:
go funcAddr
当试图用管道向 ht-command.exe 传递一些数据时,报错了!我无从获得它的帮助信息——着磨老半天,
原来它不支持命令行 —— 觉得这个程序好无耻!
若不是我知道 VBScript能模拟按键,恐怕只能无技可施!
 
下面制作一个 调试助手,希望对 长期忍受ht-ide3000的用户有所帮助。
 
功能:
针对ht-command.exe的 go命令 "go funcAddr" 提供更人性的接口"go funcName"
 
思路:
制作一个脚本 ht-dbg.bat,此脚本接受用户输入"go funcName",利用 map 文件将 funcName转换为funcAddr,
然后在ht-command.exe中执行命令"go funcAddr".
 
提示:
这里涉及文件读取、剪贴板访问、模拟按键,分别由perl程序hc.pl 、winclip.exe、VBScript程序hc.vbs 来实现。—— 使用正确的工具 ^-^
 
CODE:
 
============ht-dbg.bat==============
 

@echo off
rem ht-IDE3000 debuger Assistant.
rem 调用 hc.pl 将"go functionName"转换为"go functionAddress"
rem 调用 ht.vbs 激活ht-command,粘贴"go functionAddress"

:Ready
rem path of winclip.exe
set path=%path%;"F:\Tools\outwit-bin-1.26\bin"

:Step1
rem Get config from file.
for /f "delims==; tokens=1,2* usebackq" %%i in ("ht-Cfg.txt") do (
echo %%i, %%j
if %%i==prj set prjPath=%%j
if %%i==map set mapPath=%%j
)
echo prjPath-%prjPath%
echo mapPath-%mapPath%

:Step2
rem Get command from user.
if "%*"=="" (set /p cmd=debug command:
) else (
set cmd=%*
)
call perl hc.pl %mapPath% %cmd%|winclip -c

:Step3
hc.vbs %prjPath%


==========================
 
===========hc.pl===============

# usage:

# hc.pl mapPath cmd cmdParams


#print "argv:@ARGV\n";

# get input

if(@ARGV <2 )
{
#    printf ("ARGC:%d\n",@ARGV);

    die "Lack params. ARGV:@ARGV";
}
else
{
    $argnum=@ARGV;
    
#printf ("ARGC:$argnum\n");

}

open (ifp, $ARGV[0]) || die ("open map file '@ARGV[0]' failed.");

if(lc($ARGV[1]) ne "go")
{
    die "bad command '$ARGV[0]'. syntax:go target";
}
$target = $ARGV[2];
chomp($target);

$bFind = 0;
# 奇怪:有时候用false/true,最后的条件语句结果异常:明明为false,却执行第1分支

$ResAddrBeg="0";

#print "CODE identity list:\n";

while($line = <ifp>)
{
    
#field: bank addrBeg addrEnd lenth memory id

    
#eg: 00h 0bb9h 0c1ch 0064h CODE @Sleep (D:\Project\NT3\NT3_prj\MAIN.OBJ)

    if($line =~ /([0-9]{2})h\s+([0-9a-f]{4})h\s+([0-9a-f]{4})h\s+([0-9a-f]{4})h\s+CODE\s+@(\w+).*/)
    {
        $bank =$1;
        $addrBeg=$2;
        $addrEnd=$3;
        $lenth=$4;
        $id=$5;
        
#print "bank:$bank, addrBeg:$addrBeg, addrEnd:$addrEnd, lenth:$lenth, id:$id\n";

        if(lc($target) eq lc($id))
        {
            $bFind=1;
            $ResAddrBeg = $addrBeg;    
# 保存结果。因为执行last后中间变量已经变成最后一条记录的相应域。

            last;            
# 注意, 退出循环后 变量 $bank,$addrBeg 等均与最后一条记录相符。这与C的 break 不同。

        }
    }
}

# print "res:$bFind";


print ($bFind ? "go $ResAddrBeg" : "undefined target $target");

#printf ("%s\n", $bFind ? "go $ResAddrBeg" : "bad target $target");


#$str = $bFind ? "go $ResAddrBeg" : "undefined target $target"

#print $str; # 注意,如果不flush缓冲区,则有部分数据看不到。或者使用\n自动flush,即print $str,"\n"; 但会影响输出。


use IO::Handle;
$fh->flush;

==========================
 
============hc.vbs==============
 

' 激活ht-command.exe, 然后粘贴剪贴板中的内容(准备执行的命令)
' 此脚本需要输入工程名称,因为ht-command.exe使用它作为标题。
' get params: full path of holtek-mcu-project
dim prjPath
Set oArgs = WScript.Arguments
If oArgs.Count <> 1 Then
 MsgBox "Error paramater number:" & oArgs.Count
Else
 prjPath = oArgs(0)
 'MsgBox "ht-project:" & prjPath
End if
set ws=WScript.CreateObject("WScript.Shell")
' active ht-command.exe
If Not ws.AppActivate (prjPath&" - ht-command") then
 MsgBox "Activation ht-command.exe failed."&vbCr&"Please make sure:"&vbCr&"Project name:" & prjPath & vbCr & "2 ht-command.exe is running.", vbExclamation
Else
 'msgbox "Success to active ht-command.exe"
 wscript.sleep 100
 ws.SendKeys "^V"
End if

==========================
 
===========ht-Cfg.txt===============
prj="D:\Project\prj2\prj_ht\prj2.prj"
map="D:\Project\prj2\prj_ht\NC6.map"
==========================
 
=============prj2.map(part)=============
盛群连接器 版本8.2
版权 盛群半导体公司 2002-2003
Input Object File: D:\Project\prj2\prj_ht\prj2.OBJ
Input Library File: C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.3\LIB\MATH6.LIB

     Bank    Start     End      Length     Class      Name
     00h     0000h     0001h    0002h      CODE       @CODE (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0002h     000ah    0009h      CODE       _TBL_PWM (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     000bh     0013h    0009h      CODE       @timer (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0014h     001bh    0008h      CODE       @CHGOKProc (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     001ch     001dh    0002h      CODE       @Clr_Dog (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     001eh     001eh    0001h      CODE       STARTSEC (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0024h     0024h    0001h      CODE       @@timer (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0025h     0054h    0030h      CODE       MATH (C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.3\LIB\MATH6.LIB)
     00h     0055h     0070h    001ch      CODE       __DELAY (C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.3\LIB\MATH6.LIB)
     00h     0071h     00e6h    0076h      CODE       @MAIN (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00e7h     011bh    0035h      CODE       @HT66f30_init (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     011ch     0145h    002ah      CODE       @pwm_write (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0146h     0212h    00cdh      CODE       @TimerProc (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     0213h     028eh    007ch      CODE       @ad_detect (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     028fh     02a4h    0016h      CODE       @clr_ram (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     02a5h     03c2h    011eh      CODE       @ReadBattery (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     03c3h     04b1h    00efh      CODE       @CheckBattery (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00aah     00abh    0002h      DATA       @gAdSum (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00ach     00adh    0002h      DATA       @gAdMin (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00aeh     00afh    0002h      DATA       @gAdMax (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00b0h     00b0h    0001h      DATA       @gAdCnt (D:\Project\prj2\prj_ht\prj2.OBJ)
 
     Local Sections
 
     Bank    Start     End      Length     Class      Name
     00h     00c7h     00ceh    0008h      LOCAL      _ad_detect (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00c7h     00c7h    0000h      LOCAL      MULL (C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.3\LIB\MATH6.LIB)
     00h     00c7h     00c9h    0003h      LOCAL      _wait_ack (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00dbh     00dbh    0000h      LOCAL      @DUMMY (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00d9h     00dah    0002h      LOCAL      _main (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00c7h     00c7h    0000h      LOCAL      _HT66f30_init (D:\Project\prj2\prj_ht\prj2.OBJ)
 
     Indepentent Local Sections
     Bank    Start     End      Length     Class      Name
     00h     00dbh     00dbh    0000h      ILOCAL     _timer (D:\Project\prj2\prj_ht\prj2.OBJ)
     00h     00dbh     00dbh    0000h      ILOCAL     __DELAY (C:\Program Files\Holtek MCU Development Tools\HT-IDE3000V7.3\LIB\MATH6.LIB)
     Public Symbols Information
     Address            Public by Name
     003ah              DIVUL
     0025h              MULL
     00bbh              RH
     00d0h              ReadBatInfo0
     00c4h              T10
     00bch              T2
     00bdh              T3
     03c3h              _CheckBattery
     001ch              _Clr_Dog
     0f8eh              _DelaySec
     074ch              _DisplayLed
     0e81h              _GetKey
     00e7h              _HT66f30_init
     0c9fh              _InitSystem
     0ec7h              _ProcessKey
     04b2h              _ReadBatInfo
     02a5h              _ReadBattery
     0fach              _ReadEEPROM
     06e9h              _ReadFromIIC
     00b8h[1]           _f_200ma
     00b9h[6]           _f_250ms
     00b9h[7]           _f_2ms
     00b9h[5]           _f_500ms
     00b9h[4]           _f_500ms_chg
     00b0h              _gAdCnt
     00aeh              _gAdMax
     00ach              _gAdMin
     00aah              _gAdSum
     008ch              _gAdcAver
     Address            Public by Value
     0014h              _CHGOKProc
     001ch              _Clr_Dog
     0025h              MULL
     003ah              DIVUL
     0055h              __DELAY3
     0056h              __DELAY2
     0084h              _pwm
     0086h              _gAdcParam
     008ch              _gAdcAver
     0092h              _gAdcSum
     0098h              _gAdcMin
     009eh              _gAdcMax
     00a4h              _gAdcCnt
 
ROM Usage Statistics
     Size      Used     Percentage
     1000h     0fdfh    99%
 
RAM Usage Statistics
    Bank      Size      Used     Percentage
     00h       0080h     007fh    99%
     01h       0040h     000ch    18%
     01h       0001h     0001h    100%
     Total     00c1h     008ch    72%
 
Call Tree
    _ad_detect
        MULL
    _wait_ack
    @DUMMY
        _main
            _HT66f30_init
            _clr_ram
            _Clr_Dog
            _DelaySec
                _Clr_Dog
            _pwm_write
            _InitSystem
                _ReadEEPROM
                _ShowLed
            _GetKey
            _ProcessKey
                _WriteEEPROM
                _ShowLed
 ...
HLINK:程序的开始执行点在程序段(地址0)。定义在'D:\Project\prj2\prj_ht\prj2.OBJ' 文件中
错误总数:0  警告总数:0
 
==========================
 
阅读(4216) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~