95 lines
3.9 KiB
C++
95 lines
3.9 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2011, 2012, 2013, 2014 by Terraneo Federico *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* As a special exception, if other files instantiate templates or use *
|
|
* macros or inline functions from this file, or you compile this file *
|
|
* and link it with other works to produce a work based on this file, *
|
|
* this file does not by itself cause the resulting work to be covered *
|
|
* by the GNU General Public License. However the source code for this *
|
|
* file must still be made available in accordance with the GNU General *
|
|
* Public License. This exception does not invalidate any other reasons *
|
|
* why a work based on this file might be covered by the GNU General *
|
|
* Public License. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
|
***************************************************************************/
|
|
|
|
/*
|
|
* DCC support inspired by dcc_stdio.c in OpenOCD
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <errno.h>
|
|
#include "filesystem/ioctl.h"
|
|
#include "dcc.h"
|
|
|
|
namespace miosix {
|
|
|
|
ssize_t ARMDCC::readBlock(void* buffer, size_t size, off_t where)
|
|
{
|
|
return -EBADF;
|
|
}
|
|
|
|
ssize_t ARMDCC::writeBlock(const void* buffer, size_t size, off_t where)
|
|
{
|
|
Lock<FastMutex> l(mutex);
|
|
debugStr(reinterpret_cast<const char*>(buffer),size);
|
|
return size;
|
|
}
|
|
|
|
void ARMDCC::IRQwrite(const char* str)
|
|
{
|
|
//Actually, there is a race condition if IRQdebugWrite is called from an
|
|
//interrupt while the main code is printing with debugWrite, but it is
|
|
//not such an issue since IRQdebugWrite is called only
|
|
//- at boot before the kernel is started, so there are no other threads
|
|
//- in case of a serious error, to print what went wrong before rebooting
|
|
//In the second case, which is rare, the data may not be printed correctly
|
|
debugStr(str,-1);
|
|
}
|
|
|
|
int ARMDCC::ioctl(int cmd, void* arg)
|
|
{
|
|
if(cmd==IOCTL_SYNC) return 0; //Nothing to do, but say we did somaething
|
|
return -ENOTTY; //Means the operation does not apply to this descriptor
|
|
}
|
|
|
|
void ARMDCC::send(unsigned char c)
|
|
{
|
|
const unsigned int busy=1;
|
|
while(CoreDebug->DCRDR & busy) ;
|
|
CoreDebug->DCRDR=(static_cast<unsigned int>(c)<<8) | busy;
|
|
}
|
|
|
|
void ARMDCC::debugStr(const char *str, int length)
|
|
{
|
|
//If not being debugged, don't print anything
|
|
if((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)==0) return;
|
|
|
|
if(length<0) length=strlen(str);
|
|
if(length>0 && str[0]=='\r') str++, length--; //TODO: better \r\n removal
|
|
if(length>0 && str[0]=='\n') str++, length--;
|
|
if(length==0) return;
|
|
send(1); //1=sending a string
|
|
send(0);
|
|
send(length & 0xff);
|
|
send(length>>8);
|
|
for(int i=0;i<length;i++) send(*str++);
|
|
//OpenOCD expects data in 4 byte blocks, so send trailing zeros to align
|
|
int remaining=4-(length & 3);
|
|
if(remaining<4) for(int i=0;i<remaining;i++) send(0);
|
|
}
|
|
|
|
} //namespace miosix
|