📄 monlib.c
字号:
/* monlib.c:
* This file is part of the monitor code, but it is actually linked into
* the application. It is built with (but not linked with) the monitor,
* then the monlib.o file is linked with the application.
* The only requirement on the application is that it know where the address
* of the monCom function is in the monitor's space.
* The monCom function will be accessible in some "well-known" way (processor
* and platform dependent) so that this will not be a problem.
*
* This monlib.c file is a replacement for the older mechanism that was
* a bit more error-prone... A table of function pointers existed at some
* well-known location in the monitor, and the content of that table was
* assumed to also be "well-known". This new version only assumes that the
* pointer to monCom is well-known; everything else will work based on the
* fact that the monitor and application will share the monlib.h header
* file.
*
* General notice:
* This code is part of a boot-monitor package developed as a generic base
* platform for embedded system designs. As such, it is likely to be
* distributed to various projects beyond the control of the original
* author. Please notify the author of any enhancements made or bugs found
* so that all may benefit from the changes. In addition, notification back
* to the author will allow the new user to pick up changes that may have
* been made by other users after this version of the code was distributed.
*
* Note1: the majority of this code was edited with 4-space tabs.
* Note2: as more and more contributions are accepted, the term "author"
* is becoming a mis-representation of credit.
*
* Original author: Ed Sutter
* Email: esutter@lucent.com
* Phone: 908-582-2351
*/
#include "monlib.h"
static unsigned short (*_xcrc16)(), (*_crc32)();
static unsigned long (*_intsoff)();
static struct tfshdr *(*_tfsnext)(), *(*_tfsstat)();
static long (*_tfsctrl)(), (*_tfstell)();
static int (*_tfsseek)(), (*_tfsgetline)(), (*_tfsipmod)();
static int (*_tfsinit)(), (*_tfsadd)(), (*_tfsunlink)(), (*_tfsrun)();
static int (*_tfsread)(), (*_tfswrite)(), (*_tfsopen)(), (*_tfsclose)();
static int (*_printf)(), (*_cprintf)(), (*_sprintf)(), (*_monrestart)();
static int (*_rputchar)(), (*_getchar)(), (*_gotachar)(), (*_getbytes)();
static int (*_addcommand)(), (*_docommand)(), (*_pioget)(), (*_getline)();
static int (*_tfsfstat)(), (*_tfseof)(), (*_decompress)();
static int (*_tfstruncate)(), (*_heapextend)(), (*_tfslink)();
static int (*_pcicfgwrite)();
static int (*_i2cwrite)(), (*_i2cread)();
static char *(*_getenv)(), *(*_malloc)(), *(*_version)(), *(*_getenvp)();
static char *(*_realloc)();
static void (*_intsrestore)(), (*_appexit)(), (*_free)();
static void (*_setenv)(), (*_getargv)(), (*_pioset)(), (*_pioclr)();
static void (*_profiler)(), (*_bbc)(), (*_memtrace)();
static void (*_appwarmstart)(), (*_mondelay)();
static unsigned long (*_i2cctrl)();
static unsigned long (*_pcicfgread)(), (*_pcictrl)();
static void (*_monlock)(), (*_monunlock)();
static int (*_moncom)(int,void *,void *, void *);
/**************************************************************************
*
* The following macros support the default monitor lock/unlock mechanism when
* they point to monLock and monUnlock. If something other than the default
* is to be used, then simply redefine them here. Refer to the monitor
* app note that discusses multi-tasking access to the monitor API for more
* information.
*
* TFS_MONLOCK/UNLOCK:
* Lock/unlock for functions that access TFS flash space:
*/
#define TFS_MONLOCK monLock
#define TFS_MONUNLOCK monUnlock
/* ENV_MONLOCK/UNLOCK:
* Lock/unlock for functions that access monitor shell variables:
*/
#define ENV_MONLOCK monLock
#define ENV_MONUNLOCK monUnlock
/* CONSOLE_MONLOCK/UNLOCK:
* Lock/unlock for functions in the monitor that deal with console output.
*/
#define CONSOLE_MONLOCK monLock
#define CONSOLE_MONUNLOCK monUnlock
/* HEAP_MONLOCK/UNLOCK:
* Lock/unlock for functions in the monitor that deal with the heap.
*/
#define HEAP_MONLOCK monLock
#define HEAP_MONUNLOCK monUnlock
/* BLOCKING_MONLOCK/UNLOCK:
* Lock/unlock for functions in the monitor that block waiting for
* console input.
*/
#define BLOCKING_MONLOCK monLock
#define BLOCKING_MONUNLOCK monUnlock
/* GENERIC_MONLOCK/UNLOCK:
* Lock/unlock for all functions not covered by the above macros.
*/
#define GENERIC_MONLOCK monLock
#define GENERIC_MONUNLOCK monUnlock
/**************************************************************************
*
* monConnect():
* This must be the first call by the application code to talk to the
* monitor. It is expecting three incoming function pointers:
*
* mon: Points to the monitor's _moncom function;
* This is a "well-known" address because the monitor and
* application code (two separately linked binaries) must
* know it.
* lock: Points to a function in the application code that will be
* used by the monitor as a lock-out function (some kind of
* semaphore in the application).
* unlock: Points to a function in the application code that will be
* used by the monitor as an un-lock-out function (undo whatever
* lock-out mechanism was done by lock).
*/
void
monConnect(int (*mon)(), void (*lock)(), void (*unlock)())
{
/* Assign incoming lock and unlock functions... */
_monlock = lock;
_monunlock = unlock;
/* If the mon pointer is non-zero, then make the mon_ connections... */
if (mon) {
_moncom = mon;
/* Make the connections between "mon_" functions that are */
/* symbolically accessible by the application and the corresponding */
/* functions that exists in the monitor. */
_moncom(GETMONFUNC_PUTCHAR,&_rputchar,0,0);
_moncom(GETMONFUNC_GETCHAR,&_getchar,0,0);
_moncom(GETMONFUNC_GOTACHAR,&_gotachar,0,0);
_moncom(GETMONFUNC_GETBYTES,&_getbytes,0,0);
_moncom(GETMONFUNC_PRINTF,&_printf,0,0);
_moncom(GETMONFUNC_CPRINTF,&_cprintf,0,0);
_moncom(GETMONFUNC_SPRINTF,&_sprintf,0,0);
_moncom(GETMONFUNC_RESTART,&_monrestart,0,0);
_moncom(GETMONFUNC_GETENV,&_getenv,0,0);
_moncom(GETMONFUNC_SETENV,&_setenv,0,0);
_moncom(GETMONFUNC_TFSINIT,&_tfsinit,0,0);
_moncom(GETMONFUNC_TFSADD,&_tfsadd,0,0);
_moncom(GETMONFUNC_TFSUNLINK,&_tfsunlink,0,0);
_moncom(GETMONFUNC_TFSRUN,&_tfsrun,0,0);
_moncom(GETMONFUNC_TFSNEXT,&_tfsnext,0,0);
_moncom(GETMONFUNC_TFSSTAT,&_tfsstat,0,0);
_moncom(GETMONFUNC_TFSREAD,&_tfsread,0,0);
_moncom(GETMONFUNC_TFSWRITE,&_tfswrite,0,0);
_moncom(GETMONFUNC_TFSOPEN,&_tfsopen,0,0);
_moncom(GETMONFUNC_TFSCLOSE,&_tfsclose,0,0);
_moncom(GETMONFUNC_TFSSEEK,&_tfsseek,0,0);
_moncom(GETMONFUNC_TFSGETLINE,&_tfsgetline,0,0);
_moncom(GETMONFUNC_TFSIPMOD,&_tfsipmod,0,0);
_moncom(GETMONFUNC_TFSCTRL,&_tfsctrl,0,0);
_moncom(GETMONFUNC_ADDCOMMAND,&_addcommand,0,0);
_moncom(GETMONFUNC_DOCOMMAND,&_docommand,0,0);
_moncom(GETMONFUNC_GETARGV,&_getargv,0,0);
_moncom(GETMONFUNC_CRC16,&_xcrc16,0,0);
_moncom(GETMONFUNC_CRC32,&_crc32,0,0);
_moncom(GETMONFUNC_PIOGET,&_pioget,0,0);
_moncom(GETMONFUNC_PIOSET,&_pioset,0,0);
_moncom(GETMONFUNC_PIOCLR,&_pioclr,0,0);
_moncom(GETMONFUNC_INTSOFF,&_intsoff,0,0);
_moncom(GETMONFUNC_INTSRESTORE,&_intsrestore,0,0);
_moncom(GETMONFUNC_APPEXIT,&_appexit,0,0);
_moncom(GETMONFUNC_MALLOC,&_malloc,0,0);
_moncom(GETMONFUNC_FREE,&_free,0,0);
_moncom(GETMONFUNC_GETLINE,&_getline,0,0);
_moncom(GETMONFUNC_TFSFSTAT,&_tfsfstat,0,0);
_moncom(GETMONFUNC_TFSEOF,&_tfseof,0,0);
_moncom(GETMONFUNC_DECOMPRESS,&_decompress,0,0);
_moncom(GETMONFUNC_TFSTRUNCATE,&_tfstruncate,0,0);
_moncom(GETMONFUNC_HEAPXTEND,&_heapextend,0,0);
_moncom(GETMONFUNC_PROFILER,&_profiler,0,0);
_moncom(GETMONFUNC_TFSLINK,&_tfslink,0,0);
_moncom(GETMONFUNC_BBC,&_bbc,0,0);
_moncom(GETMONFUNC_MEMTRACE,&_memtrace,0,0);
_moncom(GETMONFUNC_TFSTELL,&_tfstell,0,0);
_moncom(GETMONFUNC_VERSION,&_version,0,0);
_moncom(GETMONFUNC_WARMSTART,&_appwarmstart,0,0);
_moncom(GETMONFUNC_PCICFGREAD,&_pcicfgread,0,0);
_moncom(GETMONFUNC_PCICFGWRITE,&_pcicfgwrite,0,0);
_moncom(GETMONFUNC_PCICONTROL,&_pcictrl,0,0);
_moncom(GETMONFUNC_I2CREAD,&_i2cread,0,0);
_moncom(GETMONFUNC_I2CWRITE,&_i2cwrite,0,0);
_moncom(GETMONFUNC_I2CCONTROL,&_i2cctrl,0,0);
_moncom(GETMONFUNC_MONDELAY,&_mondelay,0,0);
_moncom(GETMONFUNC_GETENVP,&_getenvp,0,0);
_moncom(GETMONFUNC_REALLOC,&_realloc,0,0);
}
}
/* ignorelock:
* Used as a back-door to disable the monLock()/monUnlock() stuff.
* This is useful if the application CLI falls through to the monitor's
* CLI and you are using the "call" command in the monitor to execute some
* function that has a mon_xxx function in it. In this case, the fact that
* the application has fallen through to the monitor means that the lock
* is already active, so when the function tries to call some other mon_xxx
* function it won't be able to because of the lock already being set.
*
* With these functions in the application space, the user can do the
* following:
* call %DisableLock
* call %Func_with_monXXX_in_it
* call %EnableLock
*
* Note that this is NOT to be used by application code, it is simply a
* back-door mechanism to allow "call" from the CLI to invoke functions
* that have mon_XXX functionality in them.
*/
static int ignorelock = 0;
void
DisableMonLock(void)
{
ignorelock = 2;
}
void
EnableMonLock(void)
{
ignorelock = 0;
}
/* monLock() & monUnlock():
* Used by all of the wrapper functions below this point to call
* the function pointed to by _monlock & _monunlock function pointers
* (if set).
* These functions must test both the function pointer and the state
* of the ignorelock variable. The function DisableMonLock() sets the
* ignorelock variable to 2 because it is being executed through "call"
* which means that the lock is active.
*/
static void
monLock()
{
if (_monlock) {
switch(ignorelock) {
case 1:
break;
case 2:
ignorelock--;
break;
default:
_monlock();
break;
}
}
}
static void
monUnlock()
{
if (_monunlock) {
switch(ignorelock) {
case 1:
break;
case 2:
ignorelock--;
default:
_monunlock();
break;
}
}
}
int
mon_com(int cmd, void *arg1, void *arg2, void *arg3)
{
int ret;
GENERIC_MONLOCK();
ret = _moncom(cmd,arg1,arg2,arg3);
GENERIC_MONUNLOCK();
return(ret);
}
int
mon_putchar(unsigned char c)
{
int ret;
CONSOLE_MONLOCK();
ret = _rputchar(c);
CONSOLE_MONUNLOCK();
return(ret);
}
int
mon_getchar(void)
{
int ret;
BLOCKING_MONLOCK();
ret = _getchar();
BLOCKING_MONUNLOCK();
return(ret);
}
int
mon_gotachar(void)
{
int ret;
GENERIC_MONLOCK();
ret = _gotachar();
GENERIC_MONUNLOCK();
return(ret);
}
int
mon_getbytes(char *buf,int cnt,int block)
{
int ret;
BLOCKING_MONLOCK();
ret = _getbytes(buf,cnt,block);
BLOCKING_MONUNLOCK();
return(ret);
}
int
mon_printf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
char *fmt;
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12;
{
int ret;
CONSOLE_MONLOCK();
ret = _printf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
CONSOLE_MONUNLOCK();
return(ret);
}
int
mon_cprintf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
char *fmt;
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12;
{
int ret;
CONSOLE_MONLOCK();
ret = _cprintf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
CONSOLE_MONUNLOCK();
return(ret);
}
int
mon_sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
char *fmt, *buf;
int a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12;
{
int ret;
GENERIC_MONLOCK();
ret = _sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
GENERIC_MONUNLOCK();
return(ret);
}
int
mon_restart(int val)
{
int ret;
GENERIC_MONLOCK();
ret = _monrestart(val);
GENERIC_MONUNLOCK();
return(ret);
}
char *
mon_getenvp(void)
{
char *ret;
ENV_MONLOCK();
ret = _getenvp();
ENV_MONUNLOCK();
return(ret);
}
char *
mon_getenv(char *name)
{
char *ret;
ENV_MONLOCK();
ret = _getenv(name);
ENV_MONUNLOCK();
return(ret);
}
void
mon_setenv(char *name,char *val)
{
ENV_MONLOCK();
_setenv(name,val);
ENV_MONUNLOCK();
}
int
mon_tfsinit(void)
{
int ret;
TFS_MONLOCK();
ret = _tfsinit();
TFS_MONUNLOCK();
return(ret);
}
int
mon_tfsadd(char *name, char *info, char *flags, unsigned char *src, int size)
{
int ret;
TFS_MONLOCK();
ret = _tfsadd(name,info,flags,src,size);
TFS_MONUNLOCK();
return(ret);
}
int
mon_tfslink(char *src, char *target)
{
int ret;
TFS_MONLOCK();
ret = _tfslink(src,target);
TFS_MONUNLOCK();
return(ret);
}
int
mon_tfsunlink(char *name)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -