Merge branch 'master' into feature/pypi

pull/90/head
Paris Kasidiaris 2013-10-22 13:25:01 +01:00
commit ae77a10212
81 changed files with 518 additions and 3790 deletions

View File

@ -167,7 +167,7 @@ public:
*
* @returns
* The function object created for 'fptr'
*/
*/
pFunctionPointer_t fall_add(void (*fptr)(void)) {
return fall_add_common(fptr);
}
@ -240,6 +240,14 @@ public:
*/
void mode(PinMode pull);
/** Enable IRQ
*/
void enable_irq();
/** Disable IRQ
*/
void disable_irq();
static void _irq_handler(uint32_t id, gpio_irq_event event);
protected:

View File

@ -99,6 +99,14 @@ void InterruptIn::_irq_handler(uint32_t id, gpio_irq_event event) {
}
}
void InterruptIn::enable_irq() {
gpio_irq_enable(&gpio_irq);
}
void InterruptIn::disable_irq() {
gpio_irq_disable(&gpio_irq);
}
#ifdef MBED_OPERATORS
InterruptIn::operator int() {
return read();

View File

@ -37,6 +37,8 @@ typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event);
int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id);
void gpio_irq_free(gpio_irq_t *obj);
void gpio_irq_set (gpio_irq_t *obj, gpio_irq_event event, uint32_t enable);
void gpio_irq_enable(gpio_irq_t *obj);
void gpio_irq_disable(gpio_irq_t *obj);
#ifdef __cplusplus
}

View File

@ -154,3 +154,19 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
// Interrupt configuration and clear interrupt
port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
}
void gpio_irq_enable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_EnableIRQ(PORTA_IRQn);
} else if (obj->port == PortB) {
NVIC_EnableIRQ(PORTB_IRQn);
}
}
void gpio_irq_disable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_DisableIRQ(PORTA_IRQn);
} else if (obj->port == PortB) {
NVIC_DisableIRQ(PORTB_IRQn);
}
}

View File

@ -143,3 +143,19 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
// Interrupt configuration and clear interrupt
port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
}
void gpio_irq_enable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_EnableIRQ(PORTA_IRQn);
} else if (obj->port == PortD) {
NVIC_EnableIRQ(PORTD_IRQn);
}
}
void gpio_irq_disable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_DisableIRQ(PORTA_IRQn);
} else if (obj->port == PortD) {
NVIC_DisableIRQ(PORTD_IRQn);
}
}

View File

@ -143,3 +143,19 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
// Interrupt configuration and clear interrupt
port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
}
void gpio_irq_enable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_EnableIRQ(PORTA_IRQn);
} else if (obj->port == PortD) {
NVIC_EnableIRQ(PORTD_IRQn);
}
}
void gpio_irq_disable(gpio_irq_t *obj) {
if (obj->port == PortA) {
NVIC_DisableIRQ(PORTA_IRQn);
} else if (obj->port == PortD) {
NVIC_DisableIRQ(PORTD_IRQn);
}
}

View File

@ -131,3 +131,11 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}

View File

@ -174,3 +174,43 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT);
switch (port_num) {
case 0:
NVIC_EnableIRQ(EINT0_IRQn);
break;
case 1:
NVIC_EnableIRQ(EINT1_IRQn);
break;
case 2:
NVIC_EnableIRQ(EINT2_IRQn);
break;
case 3:
NVIC_EnableIRQ(EINT3_IRQn);
break;
default:
break;
}
}
void gpio_irq_disable(gpio_irq_t *obj) {
uint32_t port_num = ((obj->pin & 0xF000) >> PORT_SHIFT);
switch (port_num) {
case 0:
NVIC_DisableIRQ(EINT0_IRQn);
break;
case 1:
NVIC_DisableIRQ(EINT1_IRQn);
break;
case 2:
NVIC_DisableIRQ(EINT2_IRQn);
break;
case 3:
NVIC_DisableIRQ(EINT3_IRQn);
break;
default:
break;
}
}

View File

@ -131,3 +131,12 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}

View File

@ -150,3 +150,12 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ(EINT3_IRQn);
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ(EINT3_IRQn);
}

View File

@ -143,3 +143,12 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ(EINT3_IRQn);
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ(EINT3_IRQn);
}

View File

@ -164,3 +164,11 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ(GPIO_IRQn);
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ(GPIO_IRQn);
}

View File

@ -134,3 +134,19 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
#if !defined(CORE_M0)
NVIC_EnableIRQ((IRQn_Type)(PIN_INT0_IRQn + obj->ch));
#else
NVIC_EnableIRQ((IRQn_Type)(PIN_INT4_IRQn + obj->ch));
#endif
}
void gpio_irq_disable(gpio_irq_t *obj) {
#if !defined(CORE_M0)
NVIC_DisableIRQ((IRQn_Type)(PIN_INT0_IRQn + obj->ch));
#else
NVIC_DisableIRQ((IRQn_Type)(PIN_INT4_IRQn + obj->ch));
#endif
}

View File

@ -125,3 +125,11 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
}
}
}
void gpio_irq_enable(gpio_irq_t *obj) {
NVIC_EnableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}
void gpio_irq_disable(gpio_irq_t *obj) {
NVIC_DisableIRQ((IRQn_Type)(PININT_IRQ + obj->ch));
}

View File

@ -0,0 +1,78 @@
/* CellularModem.h */
/* Copyright (C) 2013 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef CELLULARMODEM_H_
#define CELLULARMODEM_H_
#include "core/fwk.h"
#include "at/ATCommandsInterface.h"
class CellularModem
{
public:
//Internet-related functions
/** Open a 3G internet connection
@return 0 on success, error code on failure
*/
virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL) = 0;
/** Close the internet connection
@return 0 on success, error code on failure
*/
virtual int disconnect() = 0;
/** Send a SM
@param number The receiver's phone number
@param message The message to send
@return 0 on success, error code on failure
*/
virtual int sendSM(const char* number, const char* message) = 0;
/** Receive a SM
@param number Pointer to a buffer to store the sender's phone number (must be at least 17 characters-long, including the sapce for the null-terminating char)
@param message Pointer to a buffer to store the the incoming message
@param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
@return 0 on success, error code on failure
*/
virtual int getSM(char* number, char* message, size_t maxLength) = 0;
/** Get the number of SMs in the incoming box
@param pCount pointer to store the number of unprocessed SMs on
@return 0 on success, error code on failure
*/
virtual int getSMCount(size_t* pCount) = 0;
/** Get the ATCommandsInterface instance
@return Pointer to the ATCommandsInterface instance
*/
virtual ATCommandsInterface* getATCommandsInterface() = 0;
/** Switch power on or off
In order to use this function, a pin name must have been entered in the constructor
@param enable true to switch the dongle on, false to switch it off
@return 0 on success, error code on failure
*/
virtual int power(bool enable) = 0;
};
#endif /* CELLULARMODEM_H_ */

View File

@ -27,6 +27,10 @@
#include "UbloxCDMAModemInitializer.h"
UbloxCDMAModemInitializer::UbloxCDMAModemInitializer(USBHost* pHost) : WANDongleInitializer(pHost)
{
}
uint16_t UbloxCDMAModemInitializer::getMSDVid()
{
return 0x05C6;

View File

@ -27,10 +27,11 @@
#include "USBSerialStream.h"
#include "ip/PPPIPInterface.h"
#include "sms/CDMASMSInterface.h"
#include "CellularModem.h"
/** u-blox LISA-C200 modem
*/
class UbloxUSBCDMAModem
class UbloxUSBCDMAModem: public CellularModem
{
public:
/** Create Sprint USB Modem (Sierra Wireless 598U) API instance
@ -44,12 +45,12 @@ public:
/** Open a 3G internet connection
@return 0 on success, error code on failure
*/
int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
/** Close the internet connection
@return 0 on success, error code on failure
*/
int disconnect();
virtual int disconnect();
/** Send a SM
@ -57,7 +58,7 @@ public:
@param message The message to send
@return 0 on success, error code on failure
*/
int sendSM(const char* number, const char* message);
virtual int sendSM(const char* number, const char* message);
/** Receive a SM
@ -66,25 +67,25 @@ public:
@param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
@return 0 on success, error code on failure
*/
int getSM(char* number, char* message, size_t maxLength);
virtual int getSM(char* number, char* message, size_t maxLength);
/** Get the number of SMs in the incoming box
@param pCount pointer to store the number of unprocessed SMs on
@return 0 on success, error code on failure
*/
int getSMCount(size_t* pCount);
virtual int getSMCount(size_t* pCount);
/** Get the ATCommandsInterface instance
@return Pointer to the ATCommandsInterface instance
*/
ATCommandsInterface* getATCommandsInterface();
virtual ATCommandsInterface* getATCommandsInterface();
/** Switch power on or off
In order to use this function, a pin name must have been entered in the constructor
@param enable true to switch the dongle on, false to switch it off
@return 0 on success, error code on failure
*/
int power(bool enable);
virtual int power(bool enable);
protected:
bool power();

View File

@ -29,10 +29,11 @@
#include "sms/GSMSMSInterface.h"
#include "ussd/USSDInterface.h"
#include "link/LinkMonitor.h"
#include "CellularModem.h"
/** u-blox WCDMA modem (LISA-U200)
*/
class UbloxUSBGSMModem
class UbloxUSBGSMModem: public CellularModem
{
public:
/** Create u-blox API instance
@ -46,12 +47,12 @@ public:
/** Open a 3G internet connection
@return 0 on success, error code on failure
*/
int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
virtual int connect(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
/** Close the internet connection
@return 0 on success, error code on failure
*/
int disconnect();
virtual int disconnect();
/** Send a SM
@ -59,7 +60,7 @@ public:
@param message The message to send
@return 0 on success, error code on failure
*/
int sendSM(const char* number, const char* message);
virtual int sendSM(const char* number, const char* message);
/** Receive a SM
@ -68,13 +69,13 @@ public:
@param maxLength Maximum message length that can be stored in buffer (including null-terminating character)
@return 0 on success, error code on failure
*/
int getSM(char* number, char* message, size_t maxLength);
virtual int getSM(char* number, char* message, size_t maxLength);
/** Get the number of SMs in the incoming box
@param pCount pointer to store the number of unprocessed SMs on
@return 0 on success, error code on failure
*/
int getSMCount(size_t* pCount);
virtual int getSMCount(size_t* pCount);
/** Send a USSD command & wait for its result
@param command The command to send
@ -95,14 +96,14 @@ public:
/** Get the ATCommandsInterface instance
@return Pointer to the ATCommandsInterface instance
*/
ATCommandsInterface* getATCommandsInterface();
virtual ATCommandsInterface* getATCommandsInterface();
/** Switch power on or off
In order to use this function, a pin name must have been entered in the constructor
@param enable true to switch the dongle on, false to switch it off
@return 0 on success, error code on failure
*/
int power(bool enable);
virtual int power(bool enable);
protected:
bool power(); //< Turn power to USB dongle ON.

View File

@ -1,21 +1,22 @@
#include "mbed.h"
#include "VodafoneUSBModem.h"
#include "CellularModem.h"
#include "HTTPClient.h"
#include "test_env.h"
#include "httptest.h"
int main()
int httptest(CellularModem& modem, const char* apn, const char* username, const char* password)
{
printf("Connecting...\n");
VodafoneUSBModem modem;
HTTPClient http;
char str[512];
int ret = modem.connect("internet", "web", "web");
modem.power(true);
Thread::wait(1000);
int ret = modem.connect(apn, username, password);
if(ret)
{
printf("Could not connect\n");
notify_completion(false); //Blocks indefinitely
return false;
}
//GET data
@ -30,7 +31,7 @@ int main()
{
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
modem.disconnect();
notify_completion(false); //Blocks indefinitely
return false;
}
//POST data
@ -49,10 +50,9 @@ int main()
{
printf("Error - ret = %d - HTTP return code = %d\n", ret, http.getHTTPResponseCode());
modem.disconnect();
notify_completion(false); //Blocks indefinitely
return false;
}
modem.disconnect();
notify_completion(true); //Blocks indefinitely
modem.disconnect();
return true;
}

View File

@ -0,0 +1,9 @@
#ifndef HTTPTEST_H_
#define HTTPTEST_H_
#include "CellularModem.h"
int httptest(CellularModem& modem, const char* apn = NULL, const char* username = NULL, const char* password= NULL);
#endif

View File

@ -0,0 +1,35 @@
#include "UbloxUSBGSMModem.h"
#include "UbloxUSBCDMAModem.h"
#include "httptest.h"
#if !defined(MODEM_UBLOX_GSM) && !defined(MODEM_UBLOX_CDMA)
#warning No modem defined, using GSM by default
#define MODEM_UBLOX_GSM
#endif
#ifndef MODEM_APN
#warning APN not specified, using "internet"
#define MODEM_APN "internet"
#endif
#ifndef MODEM_USERNAME
#warning username not specified
#define MODEM_USERNAME NULL
#endif
#ifndef MODEM_PASSWORD
#warning password not specified
#define MODEM_PASSWORD NULL
#endif
int main()
{
#ifdef MODEM_UBLOX_GSM
UbloxUSBGSMModem modem;
#else
UbloxUSBCDMAModem modem(p18, true, 1);
#endif
httptest(modem, MODEM_APN, MODEM_USERNAME, MODEM_PASSWORD);
while (true);
}

View File

@ -0,0 +1,41 @@
#include "CellularModem.h"
#include "smstest.h"
void smstest(CellularModem& modem)
{
modem.power(true);
Thread::wait(1000);
#ifdef DESTINATION_NUMBER
modem.sendSM(DESINATION_NUMBER, "Hello from mbed:)");
#endif
while(true)
{
char num[17];
char msg[64];
size_t count;
int ret = modem.getSMCount(&count);
if(ret)
{
printf("getSMCount returned %d\n", ret);
Thread::wait(3000);
continue;
}
if( count > 0)
{
printf("%d SMS to read\n", count);
ret = modem.getSM(num, msg, 64);
if(ret)
{
printf("getSM returned %d\n", ret);
Thread::wait(3000);
continue;
}
printf("%s : %s\n", num, msg);
}
Thread::wait(3000);
}
}

View File

@ -0,0 +1,9 @@
#ifndef SMSTEST_H_
#define SMSTEST_H_
#include "CellularModem.h"
void smstest(CellularModem&);
#endif

View File

@ -0,0 +1,21 @@
#include "UbloxUSBGSMModem.h"
#include "UbloxUSBCDMAModem.h"
#include "smstest.h"
#if !defined(MODEM_UBLOX_GSM) && !defined(MODEM_UBLOX_CDMA)
#warning No modem defined, using GSM by default
#define MODEM_UBLOX_GSM
#endif
int main()
{
#ifdef MODEM_UBLOX_GSM
UbloxUSBGSMModem modem;
#else
UbloxUSBCDMAModem modem(p18, true, 1);
#endif
smstest(modem);
while (true);
}

View File

@ -1,138 +0,0 @@
#include "mbed.h"
#include "VodafoneUSBModem.h"
#include "test_env.h"
bool compare_msisdn(char* remote_msisdn, char* local_msisdn)
{
if( !memcmp(remote_msisdn, "+44", 3) ) //Conver to local number
{
remote_msisdn += 2;
remote_msisdn[0] = '0';
}
if( !memcmp(local_msisdn, "+44", 3) ) //Conver to local number
{
local_msisdn += 2;
local_msisdn[0] = '0';
}
return !strcmp(remote_msisdn, local_msisdn);
}
bool run(VodafoneUSBModem& modem)
{
char local_msisdn[32];
char remote_msisdn[32];
char local_msg[192];
char remote_msg[192];
int ret;
//Clear SMS inbox
size_t count;
do
{
ret = modem.getSMCount(&count);
if(ret)
{
return false;
}
if(count)
{
//Fetch SMS
ret = modem.getSM(remote_msisdn, remote_msg, 192);
if(ret)
{
return false;
}
}
} while(count);
//Now get MSISDN using USSD
ret = modem.sendUSSD("*#100#", local_msisdn, 32);
if(ret)
{
return false;
}
printf("Local MSISDN is %s\n", local_msisdn);
//Makeup a random text message (32 uppper case letters)
for(int i = 0; i < 32; i++)
{
local_msg[i] = 'A' + (rand() % 26); //This is pseudo-random only, but we don't really care anyway
}
local_msg[32] = '\0'; //Terminate string
printf("Sending '%s'\n", local_msg);
//Send SM
ret = modem.sendSM(local_msisdn, local_msg);
if(ret)
{
return false;
}
//Now wait for corresponding message for 15s max
Timer t;
t.start();
do
{
ret = modem.getSMCount(&count);
if(ret)
{
return false;
}
if(count)
{
//Fetch SM
ret = modem.getSM(remote_msisdn, remote_msg, 192);
if(ret)
{
return false;
}
printf("Received '%s' from %s\n", remote_msg, remote_msisdn);
if( compare_msisdn(remote_msisdn, local_msisdn) && !strcmp(remote_msg, local_msg) )
{
break;
}
}
if(t.read_ms() > 15000)
{
return false;
}
Thread::wait(500);
} while(true);
//Success :)
return true;
}
void test(void const*)
{
VodafoneUSBModem modem;
bool test = run(modem);
if(test)
{
printf("Test successful\n");
notify_completion(true);
}
else
{
printf("Test failed\n");
notify_completion(false);
}
//notify_completion() blocks indefinitely
}
int main()
{
Thread testTask(test, NULL, osPriorityNormal, 1024 * 5);
DigitalOut led(LED1);
while(1)
{
led=!led;
Thread::wait(1000);
}
return 0;
}

View File

@ -52,6 +52,8 @@ if __name__ == '__main__':
default=False, help="Verbose diagnostic output")
parser.add_option("-b", "--ublox", action="store_true", dest="ublox",
default=False, help="Compile the u-blox library")
parser.add_option("-D", "", action="append", dest="macros",
help="Add a macro definition")
(options, args) = parser.parse_args()
# Get target list
@ -92,10 +94,12 @@ if __name__ == '__main__':
try:
mcu = TARGET_MAP[target]
build_mbed_libs(mcu, toolchain, options=options.options,
verbose=options.verbose, clean=options.clean)
verbose=options.verbose, clean=options.clean,
macros=options.macros)
for lib_id in libraries:
build_lib(lib_id, mcu, toolchain, options=options.options,
verbose=options.verbose, clean=options.clean)
verbose=options.verbose, clean=options.clean,
macros=options.macros)
successes.append(id)
except Exception, e:
if options.verbose:

View File

@ -26,19 +26,21 @@ from workspace_tools.libraries import Library
def build_project(src_path, build_path, target, toolchain_name,
libraries_paths=None, options=None, linker_script=None,
clean=False, notify=None, verbose=False, name=None):
clean=False, notify=None, verbose=False, name=None, macros=None):
# Toolchain instance
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify)
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros)
toolchain.VERBOSE = verbose
toolchain.build_all = clean
src_paths = [src_path] if type(src_path) != ListType else src_path
if name is None:
name = basename(src_path)
name = basename(src_paths[0])
toolchain.info("\n>>> BUILD PROJECT: %s (%s, %s)" % (name.upper(), target.name, toolchain_name))
# Scan src_path and libraries_paths for resources
resources = toolchain.scan_resources(src_path)
src_paths = [src_path]
resources = toolchain.scan_resources(src_paths[0])
for path in src_paths[1:]:
resources.add(toolchain.scan_resources(path))
if libraries_paths is not None:
src_paths.extend(libraries_paths)
for path in libraries_paths:
@ -75,7 +77,7 @@ verbose: Write the actual tools command lines if True
"""
def build_library(src_paths, build_path, target, toolchain_name,
dependencies_paths=None, options=None, name=None, clean=False,
notify=None, verbose=False):
notify=None, verbose=False, macros=None):
if type(src_paths) != ListType: src_paths = [src_paths]
for src_path in src_paths:
@ -83,7 +85,7 @@ def build_library(src_paths, build_path, target, toolchain_name,
raise Exception("The library source folder does not exist: %s", src_path)
# Toolchain instance
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify)
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, notify, macros)
toolchain.VERBOSE = verbose
toolchain.build_all = clean
@ -122,25 +124,25 @@ def build_library(src_paths, build_path, target, toolchain_name,
toolchain.build_library(objects, bin_path, name)
def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=False):
def build_lib(lib_id, target, toolchain, options=None, verbose=False, clean=False, macros=None):
lib = Library(lib_id)
if lib.is_supported(target, toolchain):
build_library(lib.source_dir, lib.build_dir, target, toolchain,
lib.dependencies, options,
verbose=verbose, clean=clean)
verbose=verbose, clean=clean, macros=macros)
else:
print '\n\nLibrary "%s" is not yet supported on target %s with toolchain %s' % (lib_id, target.name, toolchain)
# We do have unique legacy conventions about how we build and package the mbed library
def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=False):
def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=False, macros=None):
# Check toolchain support
if toolchain_name not in target.supported_toolchains:
print '\n%s target is not yet supported by toolchain %s' % (target.name, toolchain_name)
return
# Toolchain
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options)
toolchain = TOOLCHAIN_CLASSES[toolchain_name](target, options, macros=macros)
toolchain.VERBOSE = verbose
toolchain.build_all = clean
@ -189,3 +191,4 @@ def build_mbed_libs(target, toolchain_name, options=None, verbose=False, clean=F
objects.remove(retargeting)
toolchain.build_library(objects, BUILD_TOOLCHAIN, "mbed")
toolchain.copy_files(retargeting, BUILD_TOOLCHAIN)

View File

@ -1,148 +0,0 @@
pyOCD
=====
pyOCD is an Open Source python library in order to program and
debug ARM Cortex-M microcontrollers using CMSIS-DAP. You can either
use a python interpreter to control your target or start a GDB server.
What allows this library?
-------------------------
1. From a python interpretor:
* halt, step, resume execution
* read/write memory
* read/write block memory
* read-write core register
* set/remove hardware breakpoints
* flash new binary
* reset
2. From a GDB client, you have all the features provided by gdb:
* load a .elf file
* read/write memory
* read/write core register
* set/remove hardware breakpoints
* high level stepping
* ...
DEPENDANCIES:
-------------
pyOCD relies on external libraries:
* pyOCD has been tested with python 2.7
* distutils
* Windows: [pyWinUSB](https://github.com/rene-aguirre/pywinusb):
```
$ cd /path-to-pywinusb/
$ python setup.py install
```
* Linux: [pyUSB](https://github.com/walac/pyusb):
```
$ sudo apt-get install python libusb-1.0-0-dev
$ cd /path-to-pyusb/
$ sudo python setup.py install
```
* Mac:
So far Mac OS X is not supported
Installation:
-------------
$ cd /path-to-pyOCD/
$ python setup.py install
Examples:
---------
## Tests
A series of tests are on the test directory:
* basic_test.py: simple test that checks:
1. read/write core registers
2. read/write memory
3. stop/resume/step the execution
4. reset the target
5. flash a binary
* gdb_test.py: launch a gdbserver
## Hello World example:
from pyOCD.board import MbedBoard
import logging
logging.basicConfig(level=logging.INFO)
board = MbedBoard.chooseBoard()
target = board.target
flash = board.flash
target.resume()
target.halt()
print "pc: 0x%X" % target.readCoreRegister("pc")
pc: 0xA64
target.step()
print "pc: 0x%X" % target.readCoreRegister("pc")
pc: 0xA30
target.step()
print "pc: 0x%X" % target.readCoreRegister("pc")
pc: 0xA32
flash.flashBinary("binaries/l1_lpc1768.bin")
print "pc: 0x%X" % target.readCoreRegister("pc")
pc: 0x10000000
target.reset()
target.halt()
print "pc: 0x%X" % target.readCoreRegister("pc")
pc: 0xAAC
board.uninit()
##GDB server example:
Python:
from pyOCD.gdbserver import GDBServer
from pyOCD.board import MbedBoard
import logging
logging.basicConfig(level=logging.INFO)
board = MbedBoard.chooseBoard()
# start gdbserver
gdb = GDBServer(board, 3333)
gdb server:
arm-none-eabi-gdb basic.elf
<gdb> target remote localhost:3333
<gdb> load
<gdb> continue
Architecture:
-------------
# interface:
An interface does the link between the target and the computer.
This package contains basic functions to write and read data to and from
an interface. You can inherit from Interface and overwrite read(), write(),...
Then declare your interface in INTERFACE (in pyOCD.interface.__init__.py)
# target:
A target defines basic functionalities such as step, resume, halt, readMemory,...
You can inherit from Target to implement your own functions.
Then declare your target in TARGET (in pyOCD.target.__init__.py)
# transport:
Defines the transport used to communicate. In particular, you can find CMSIS-DAP.
Defines functions such as memWriteAP, memReadAP, writeDP, readDP,...
You can inherit from Transport and implement your own functions.
Then declare your transport in TRANSPORT (in pyOCD.transport.__init__.py)
# flash:
Contains flash algorithm in order to flash a new binary into the target.
# gdbserver:
Start a GDB server. The server listens on a specific port. You can then
connect a GDB client to it and debug/program the target
Then you can debug a board which is composed by an interface, a target, a transport and a flash

View File

@ -1,16 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

View File

@ -1,16 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

View File

@ -1,18 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from mbed_board import MbedBoard

View File

@ -1,60 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from pyOCD.target import TARGET
from pyOCD.transport import TRANSPORT
from pyOCD.interface import INTERFACE
from pyOCD.flash import FLASH
import logging
class Board():
"""
This class associates a target, a flash, a transport and an interface
to create a board
"""
def __init__(self, target, flash, interface, transport = "cmsis_dap"):
if isinstance(interface, str) == False:
self.interface = interface
else:
self.interface = INTERFACE[interface].chooseInterface(INTERFACE[interface])
self.transport = TRANSPORT[transport](self.interface)
self.target = TARGET[target](self.transport)
self.flash = FLASH[flash](self.target)
return
def init(self):
"""
Initialize the board: interface, transport and target
"""
logging.debug("init board %s", self)
self.interface.init()
self.transport.init()
self.target.init()
def uninit(self):
"""
Uninitialize the board: inetrface, transport and target.
This function resets the target
"""
logging.debug("uninit board %s", self)
self.target.resume()
self.transport.uninit()
self.interface.close()
def getInfo(self):
return self.interface.getInfo()

View File

@ -1,160 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import sys, os
import logging, array
from time import sleep
from board import Board
from pyOCD.interface import INTERFACE
TARGET_TYPE = {"1010": "lpc1768",
"0200": "kl25z",
"1040": "lpc11u24",
"0300": "lpc800",
}
usb_backend = ""
if os.name == "nt":
usb_backend = "pywinusb"
elif os.name == "posix":
usb_backend = "pyusb"
mbed_vid = 0x0d28
mbed_pid = 0x0204
class MbedBoard(Board):
"""
This class inherits from Board and is specific to mbed boards.
Particularly, this class allows you to dynamically determine
the type of all boards connected based on the id board
"""
def __init__(self, target, flash, interface, transport = "cmsis_dap"):
"""
Init the board
"""
Board.__init__(self, target, flash, interface, transport)
self.unique_id = ""
self.target_type = ""
def getUniqueID(self):
"""
Return the unique id of the board
"""
return self.unique_id
def getTargetType(self):
"""
Return the type of the board
"""
return self.target_type
def getInfo(self):
"""
Return info on the board
"""
return Board.getInfo(self) + " [" + self.target_type + "]"
@staticmethod
def getAllConnectedBoards(transport = "cmsis_dap", close = False, blocking = True):
"""
Return an array of all mbed boards connected
"""
first = True
while True:
while True:
all_mbeds = INTERFACE[usb_backend].getAllConnectedInterface(mbed_vid, mbed_pid)
if all_mbeds != None or not blocking:
break
if (first == True):
logging.info("Waiting for a USB device connected")
first = False
sleep(0.2)
mbed_boards = []
for mbed in all_mbeds:
mbed.write([0x80])
u_id_ = mbed.read()
try:
target_type = array.array('B', [i for i in u_id_[2:6]]).tostring()
target_type = TARGET_TYPE[target_type]
new_mbed = MbedBoard("target_" + target_type, "flash_" + target_type, mbed, transport)
new_mbed.target_type = target_type
new_mbed.unique_id = array.array('B', [i for i in u_id_[2:2+u_id_[1]]]).tostring()
logging.info("new board id detected: %s", new_mbed.unique_id)
mbed_boards.append(new_mbed)
if close:
mbed.close()
except Exception as e:
print "received exception: %s" % e
mbed.close()
if len(mbed_boards) > 0 or not blocking:
return mbed_boards
if (first == True):
logging.info("Waiting for a USB device connected")
first = False
@staticmethod
def chooseBoard(transport = "cmsis_dap", blocking = True, return_first = False):
"""
Allow you to select a board among all boards connected
"""
all_mbeds = MbedBoard.getAllConnectedBoards(transport, False, blocking)
if all_mbeds == None:
return None
index = 0
for mbed in all_mbeds:
print "%d => %s" % (index, mbed.getInfo())
index += 1
if len(all_mbeds) == 1:
all_mbeds[0].init()
return all_mbeds[0]
try:
ch = 0
if not return_first:
while True:
ch = sys.stdin.readline()
sys.stdin.flush()
if (int(ch) < 0) or (int(ch) >= len(all_mbeds)):
logging.info("BAD CHOICE: %d", int(ch))
index = 0
for mbed in all_mbeds:
print "%d => %s" % ( index, mbed.getInfo())
index += 1
else:
break
# close all others mbed connected
for mbed in all_mbeds:
if mbed != all_mbeds[int(ch)]:
mbed.interface.close()
all_mbeds[int(ch)].init()
return all_mbeds[int(ch)]
except Exception as e:
try:
print e
except:
pass
finally:
for mbed in all_mbeds:
mbed.interface.close()

View File

@ -1,27 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from flash_lpc1768 import Flash_lpc1768
from flash_kl25z import Flash_kl25z
from flash_lpc11u24 import Flash_lpc11u24
from flash_lpc800 import Flash_lpc800
FLASH = {'flash_lpc1768': Flash_lpc1768,
'flash_kl25z': Flash_kl25z,
'flash_lpc11u24': Flash_lpc11u24,
'flash_lpc800': Flash_lpc800
}

View File

@ -1,145 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from pyOCD.target.target import TARGET_RUNNING
import logging
from struct import unpack
from time import time
"""
import os,sys
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,parentdir)
"""
class Flash():
"""
This class is responsible to flash a new binary in a target
"""
def __init__(self, target, flash_algo, memoryMapXML):
self.target = target
self.flash_algo = flash_algo
self.end_flash_algo = flash_algo['load_address'] + len(flash_algo)*4
self.begin_stack = flash_algo['begin_stack']
self.begin_data = flash_algo['begin_data']
self.static_base = flash_algo['static_base']
self.page_size = flash_algo['page_size']
self.memoryMapXML = memoryMapXML
def init(self):
"""
Download the flash algorithm in RAM
"""
self.target.halt()
self.target.setTargetState("PROGRAM")
# download flash algo in RAM
self.target.writeBlockMemoryAligned32(self.flash_algo['load_address'], self.flash_algo['instructions'])
# update core register to execute the init subroutine
self.updateCoreRegister(0, 0, 0, 0, self.flash_algo['pc_init'])
# resume and wait until the breakpoint is hit
self.target.resume()
while(self.target.getState() == TARGET_RUNNING):
pass
return
def eraseAll(self):
"""
Erase all the flash
"""
# update core register to execute the eraseAll subroutine
self.updateCoreRegister(0, 0, 0, 0, self.flash_algo['pc_eraseAll'])
# resume and wait until the breakpoint is hit
self.target.resume()
while(self.target.getState() == TARGET_RUNNING):
pass
return
def programPage(self, flashPtr, bytes):
"""
Flash one page
"""
# first transfer in RAM
self.target.writeBlockMemoryUnaligned8(self.begin_data, bytes)
# update core register to execute the program_page subroutine
self.updateCoreRegister(flashPtr, self.page_size, self.begin_data, 0, self.flash_algo['pc_program_page'])
# resume and wait until the breakpoint is hit
self.target.resume()
while(self.target.getState() == TARGET_RUNNING):
pass
return
def flashBinary(self, path_file):
"""
Flash a binary
"""
f = open(path_file, "rb")
start = time()
self.init()
logging.debug("flash init OK: pc: 0x%X", self.target.readCoreRegister('pc'))
self.eraseAll()
logging.debug("eraseAll OK: pc: 0x%X", self.target.readCoreRegister('pc'))
"""
bin = open(os.path.join(parentdir, 'res', 'good_bin.txt'), "w+")
"""
flashPtr = 0
nb_bytes = 0
try:
bytes_read = f.read(1024)
while bytes_read:
bytes_read = unpack(str(len(bytes_read)) + 'B', bytes_read)
nb_bytes += len(bytes_read)
# page download
self.programPage(flashPtr, bytes_read)
"""
i = 0
while (i < len(bytes_read)):
bin.write(str(list(bytes_read[i:i+16])) + "\n")
i += 16
"""
flashPtr += 1024
bytes_read = f.read(1024)
finally:
f.close()
"""
bin.close()
"""
end = time()
logging.info("%f kbytes flashed in %f seconds ===> %f kbytes/s" %(nb_bytes/1000, end-start, nb_bytes/(1000*(end - start))))
def updateCoreRegister(self, r0, r1, r2, r3, pc):
self.target.writeCoreRegister('pc', pc)
self.target.writeCoreRegister('r0', r0)
self.target.writeCoreRegister('r1', r1)
self.target.writeCoreRegister('r2', r2)
self.target.writeCoreRegister('r3', r3)
self.target.writeCoreRegister('r9', self.static_base)
self.target.writeCoreRegister('sp', self.begin_stack)
self.target.writeCoreRegister('lr', self.flash_algo['load_address'] + 1)
return

View File

@ -1,92 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from flash import Flash
flash_algo = { 'load_address' : 0x20000000,
'instructions' : [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0xb510492f, 0x60084449, 0x2100482e, 0x482f6001, 0x44484a2d, 0x22016002, 0x04926041, 0x02926082,
0x220560c2, 0x61420692, 0x03122201, 0x46026182, 0x70113220, 0x62411e49, 0xf929f000, 0xd0002800,
0xbd102001, 0x47702000, 0xb5084a21, 0x0349447a, 0x0c0a9200, 0x481d4601, 0x44482300, 0xf9b7f000,
0xd0002800, 0xbd082001, 0x4919b510, 0x48174479, 0x44483920, 0xf891f000, 0xd0002800, 0xbd102001,
0x4b13b510, 0x4601447b, 0x22014810, 0x02923b38, 0xf0004448, 0x2800f8b4, 0x2001d000, 0xb538bd10,
0x490b460c, 0x39584479, 0x46019100, 0x46134807, 0x44484622, 0xf948f000, 0xd0002800, 0xbd382001,
0x00000004, 0x40048100, 0x40020000, 0x00000008, 0x00000085, 0x4604b570, 0x25006800, 0x061b7803,
0x2370d5fc, 0x20007003, 0x0003e03a, 0xfa60f000, 0x0f0b070c, 0x1f1b1713, 0x2f2b2723, 0x68263633,
0x71f37813, 0x6826e02a, 0x71b37853, 0x6826e026, 0x71737893, 0x6826e022, 0x713378d3, 0x6826e01e,
0x72f37913, 0x6826e01a, 0x72b37953, 0x6826e016, 0x72737993, 0x6826e012, 0x723379d3, 0x6826e00e,
0x73f37a13, 0x6826e00a, 0x73b37a53, 0x6826e006, 0x73737a93, 0x6826e002, 0x73337ad3, 0xb2c01c40,
0xd9c24288, 0x20806821, 0xe0037008, 0x1c416a60, 0x4780d000, 0x78006820, 0xd5f70600, 0x78006820,
0xd5010681, 0xe0062504, 0xd50106c1, 0xe0022508, 0xd00007c0, 0x46282510, 0xb508bd70, 0x2244460b,
0x700a4669, 0x2100466a, 0xbd084798, 0x4614b538, 0xd002078a, 0x300120ff, 0x6843bd38, 0xd803428b,
0x189a6882, 0xd80d428a, 0x428a68c2, 0x6903d803, 0x428b18d3, 0x2002d801, 0x1a89bd38, 0x05d22201,
0xe0001889, 0x22081ac9, 0x701a466b, 0x705a0c0a, 0x709a0a0a, 0x466a70d9, 0x47a02103, 0xb5ffbd38,
0x4615b081, 0x27019a01, 0x26006852, 0x02bf1948, 0xd804428a, 0x689b9b01, 0x428318d3, 0x9a01d20f,
0x428a68d2, 0x9b01d804, 0x18d3691b, 0xd2014283, 0xe0292602, 0x21011a88, 0x184405c9, 0x1a8ce000,
0x46204639, 0xf907f000, 0xd0022900, 0x360126ff, 0x4639e01a, 0xf0004628, 0x2900f8fe, 0x2601d012,
0x2009e012, 0x70084669, 0x70480c20, 0x70880a20, 0x9b0470cc, 0x2103466a, 0x47989801, 0xd1030006,
0x19e41bed, 0xd1ec2d00, 0xb0054630, 0xb5f0bdf0, 0x24006801, 0x0612780a, 0x2270d5fc, 0x6802700a,
0x71d12103, 0x22806801, 0x6803718a, 0x71592100, 0x23fc6805, 0x6803712b, 0x680373d9, 0x6802701a,
0x061b7813, 0x7a55d5fc, 0x07177a12, 0x0f3f2201, 0x105603d2, 0xf000003b, 0x0910f96b, 0x09100e0b,
0x10090909, 0x09090e1f, 0x11090909, 0xe0056102, 0x03522203, 0x6106e7fa, 0x6101e000, 0x0f12072a,
0xf0000013, 0x0c10f955, 0x120f0c0c, 0x1d1b1815, 0x0c0c0c1f, 0x0d0c0c0c, 0x03522201, 0x61c1e7e6,
0xbdf04620, 0x02c92101, 0x2101e7f9, 0xe7f60289, 0x02492101, 0x21ffe7f3, 0xe7f03101, 0xe7ee2180,
0xe7ec2140, 0xe7ea2120, 0x4607b5fe, 0x461d4616, 0x198a2000, 0xd002078b, 0x300120ff, 0x07b3bdfe,
0x2001d001, 0x687bbdfe, 0xd803428b, 0x191c68bc, 0xd20d4294, 0x428b68fb, 0x693cd803, 0x4294191c,
0x2002d201, 0x2201bdfe, 0x05d21ac9, 0xe01b188c, 0xe0191acc, 0x46692006, 0x0c207008, 0x0a207048,
0x70cc7088, 0x710878e8, 0x714878a8, 0x71887868, 0x71c87828, 0x466a9b08, 0x46382107, 0x28004798,
0x1d24d1e0, 0x1d2d1f36, 0xd1e32e00, 0xb5febdfe, 0x46044615, 0x00a86842, 0x461e1840, 0xd803428a,
0x18d368a3, 0xd808428b, 0x428b68e3, 0x6927d803, 0x428b19db, 0x2002d801, 0x4282bdfe, 0x68a3d805,
0x428318d3, 0x1a8fd301, 0x68e2e00a, 0xd9034282, 0x18d36923, 0xd3ee4283, 0x21011a88, 0x184705c9,
0x46382104, 0xf817f000, 0xd0022900, 0x300120ff, 0x2001bdfe, 0x70084669, 0x70480c38, 0x70880a38,
0x0a2870cf, 0x714d7108, 0x9b08718e, 0x2106466a, 0x47984620, 0x2200bdfe, 0x428b0903, 0x0a03d32c,
0xd311428b, 0x469c2300, 0x4603e04e, 0xd43c430b, 0x08432200, 0xd331428b, 0x428b0903, 0x0a03d31c,
0xd301428b, 0xe03f4694, 0x428b09c3, 0x01cbd301, 0x41521ac0, 0x428b0983, 0x018bd301, 0x41521ac0,
0x428b0943, 0x014bd301, 0x41521ac0, 0x428b0903, 0x010bd301, 0x41521ac0, 0x428b08c3, 0x00cbd301,
0x41521ac0, 0x428b0883, 0x008bd301, 0x41521ac0, 0x428b0843, 0x004bd301, 0x41521ac0, 0xd2001a41,
0x41524601, 0x47704610, 0x0fcae05d, 0x4249d000, 0xd3001003, 0x40534240, 0x469c2200, 0x428b0903,
0x0a03d32d, 0xd312428b, 0x018922fc, 0x0a03ba12, 0xd30c428b, 0x11920189, 0xd308428b, 0x11920189,
0xd304428b, 0xd03a0189, 0xe0001192, 0x09c30989, 0xd301428b, 0x1ac001cb, 0x09834152, 0xd301428b,
0x1ac0018b, 0x09434152, 0xd301428b, 0x1ac0014b, 0x09034152, 0xd301428b, 0x1ac0010b, 0x08c34152,
0xd301428b, 0x1ac000cb, 0x08834152, 0xd301428b, 0x1ac0008b, 0xd2d94152, 0x428b0843, 0x004bd301,
0x41521ac0, 0xd2001a41, 0x46634601, 0x105b4152, 0xd3014610, 0x2b004240, 0x4249d500, 0x46634770,
0xd300105b, 0xb5014240, 0x46c02000, 0xbd0246c0, 0x4674b430, 0x78251e64, 0x42ab1c64, 0x461dd200,
0x005b5d63, 0xbc3018e3, 0x00004718, 0xfffffffe
],
'pc_init' : 0x20000020,
'pc_eraseAll' : 0x20000088,
'pc_program_page' : 0x200000be,
'begin_stack' : 0x20001000,
'begin_data' : 0x20002000,
'static_base' : 0x200005ec,
'page_size' : 1024
};
memoryMapXML = "<?xml version=\"1.0\"?>" \
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">" \
"<memory-map>" \
"<memory type=\"flash\" start=\"0x0\" length=\"0x20000\"> <property name=\"blocksize\">0x400</property></memory>" \
"<memory type=\"ram\" start=\"0x20000000\" length=\"0x3000\"> </memory>" \
"</memory-map>"
class Flash_kl25z(Flash):
def __init__(self, target):
Flash.__init__(self, target, flash_algo, memoryMapXML)

View File

@ -1,57 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from flash import Flash
flash_algo = { 'load_address' : 0x10000000,
'instructions' : [
0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2,
0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x47700b00, 0x484e494f,
0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9, 0x49496382, 0x39402002,
0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x46222607, 0x4621c261, 0x4f423114,
0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448, 0x462060e0, 0x47b89900,
0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0b044d35, 0x2032444d, 0x4629606c, 0x311460ac, 0x4e326028,
0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829, 0x68004448, 0x462860e8,
0x696847b0, 0xd0002800, 0xbdf82001, 0x0006b5f8, 0xd11e4614, 0x0180200b, 0x6bc11820, 0x42814823,
0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861, 0x184068e2, 0x188968a1,
0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0b30, 0x60682132, 0x60a86029,
0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033, 0x20016028, 0x60e80280,
0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001, 0x00002ee0, 0x00000004,
0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x43218765, 0x00000000,
0x00000000
],
'pc_init' : 0x1000003d,
'pc_eraseAll' : 0x1000006b,
'pc_program_page' : 0x100000ed,
'begin_data' : 0x100001c4,
'begin_stack' : 0x10001000,
'static_base' : 0x1000019c,
'page_size' : 1024
};
memoryMapXML = "<?xml version=\"1.0\"?>" \
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">" \
"<memory-map>" \
"<memory type=\"flash\" start=\"0x0\" length=\"0x8000\"> <property name=\"blocksize\">0x400</property></memory>" \
"<memory type=\"ram\" start=\"0x10000000\" length=\"0x1000\"> </memory>" \
"</memory-map>"
class Flash_lpc11u24(Flash):
def __init__(self, target):
Flash.__init__(self, target, flash_algo, memoryMapXML)

View File

@ -1,61 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from flash import Flash
flash_algo = { 'load_address' : 0x10000000,
'instructions' : [
0xe00abe00, 0x062d780d, 0x24084068, 0xd3000040, 0x1e644058, 0x1c49d1fa, 0x2a001e52, 0x4770d1f2,
0x7803e005, 0x42931c40, 0x2001d001, 0x1e494770, 0x2000d2f7, 0x00004770, 0x28100b00, 0x210ed302,
0x00d0eb01, 0x486c4770, 0x7801b510, 0x0102f021, 0x22aa7001, 0x23557302, 0x78017303, 0x0101f021,
0x73027001, 0xf8d07303, 0xf0411120, 0xf8c00120, 0xf1a01120, 0xf8d00080, 0x064911a0, 0xf100d5fb,
0x24010080, 0x408cf880, 0x0113f04f, 0x73026041, 0x78017303, 0x0101f041, 0x73027001, 0xf1a07303,
0xf8d00080, 0x01491088, 0xf100d5fb, 0x2107006d, 0x1097f880, 0x0109f04f, 0x109bf880, 0xf0417cc1,
0x74c10102, 0x77c377c2, 0x4c2df800, 0xf64e494b, 0x44492060, 0xf04f6008, 0xbd100000, 0x47702000,
0x41f0e92d, 0x20324c46, 0x2500444c, 0xe884271d, 0xf10400a1, 0x4e430114, 0x46204688, 0x696047b0,
0x2034b960, 0x00a1e884, 0x4641483c, 0x68004448, 0x462060e0, 0x696047b0, 0xd0002800, 0xe8bd2001,
0xe92d81f0, 0xf7ff41f0, 0x4d35ff87, 0x444d4604, 0xe9c52032, 0xf1050400, 0x4e320114, 0x4628460f,
0x47b060ac, 0xb9686968, 0xe9c52034, 0x482b0400, 0x444860ac, 0x68004639, 0x462860e8, 0x696847b0,
0xd0dc2800, 0xe7da2001, 0x41f0e92d, 0x46140006, 0x4925d11d, 0x02fcf8d4, 0xd03a4288, 0x42884923,
0x4923d037, 0xd0344288, 0x4131ea4f, 0xd0304288, 0x0100e9d4, 0xe9d44408, 0x44111202, 0x69214408,
0x69614408, 0x69a14408, 0x42404408, 0x463061e0, 0xff42f7ff, 0x21324d12, 0x4f12444d, 0x1000e9c5,
0x0114f105, 0x468860a8, 0x47b84628, 0xb9806968, 0xe9c52033, 0xf44f0600, 0xe9c56080, 0x48074002,
0x44484641, 0x61286800, 0x47b84628, 0x28006968, 0x2001d095, 0x0000e793, 0x400fc080, 0x00000004,
0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321, 0x00000000, 0x00000000
],
'pc_init' : 0x10000047,
'pc_eraseAll' : 0x100000e1,
'pc_program_page' : 0x10000169,
'begin_data' : 0x1000023c,
'begin_stack' : 0x10001000,
'static_base' : 0x10000214,
'page_size' : 1024
};
memoryMapXML = "<?xml version=\"1.0\"?>" \
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">" \
"<memory-map>" \
"<memory type=\"flash\" start=\"0x0\" length=\"0x80000\"> <property name=\"blocksize\">0x400</property></memory>" \
"<memory type=\"ram\" start=\"0x10000000\" length=\"0x8000\"> </memory>" \
"<memory type=\"ram\" start=\"0x2007C000\" length=\"0x8000\"> </memory>" \
"</memory-map>"
class Flash_lpc1768(Flash):
def __init__(self, target):
Flash.__init__(self, target, flash_algo, memoryMapXML)

View File

@ -1,56 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from flash import Flash
flash_algo = { 'load_address' : 0x10000000,
'instructions' : [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x47700a80, 0x484e494f, 0x60084449, 0x2100484e, 0x22016301, 0x63416342, 0x6b416342, 0xd0fc07c9,
0x49496382, 0x39402002, 0x20007008, 0x20004770, 0xb5f84770, 0x20324c45, 0x2500444c, 0x4622260f,
0x4621c261, 0x4f423114, 0x91004620, 0x696047b8, 0xd10c2800, 0x46212034, 0x483ac161, 0x68004448,
0x462060e0, 0x47b89900, 0x28006960, 0x2001d000, 0xb5f8bdf8, 0x0a844d35, 0x2032444d, 0x4629606c,
0x311460ac, 0x4e326028, 0x4628460f, 0x696847b0, 0xd10d2800, 0x2034606c, 0x602860ac, 0x46394829,
0x68004448, 0x462860e8, 0x696847b0, 0xd0002800, 0xbdf82001, 0x4614b5f8, 0xd11e0006, 0x0180200b,
0x6bc11820, 0x42814823, 0x4823d038, 0xd0354281, 0x42814822, 0x4822d032, 0xd02f4281, 0x68206861,
0x184068e2, 0x188968a1, 0x69211840, 0x69611840, 0x69a11840, 0x42401840, 0x4d1461e0, 0x444d0ab0,
0x60682132, 0x60a86029, 0x31144629, 0x46284f10, 0x47b89100, 0x28006968, 0x606ed110, 0x60ac2033,
0x20016028, 0x60e80280, 0x44484806, 0x61286800, 0x99004628, 0x696847b8, 0xd0002800, 0xbdf82001,
0x00002ee0, 0x00000004, 0x40048040, 0x00000008, 0x1fff1ff1, 0x4e697370, 0x12345678, 0x87654321,
0x43218765
],
'pc_init' : 0x10000024,
'pc_eraseAll' : 0x10000052,
'pc_program_page' : 0x100000d4,
'begin_data' : 0x10000400,
'begin_stack' : 0x10001000,
'static_base' : 0x10000300,
'page_size' : 1024
};
memoryMapXML = "<?xml version=\"1.0\"?>" \
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">" \
"<memory-map>" \
"<memory type=\"flash\" start=\"0x0\" length=\"0x8000\"> <property name=\"blocksize\">0x400</property></memory>" \
"<memory type=\"ram\" start=\"0x10000000\" length=\"0x1000\"> </memory>" \
"</memory-map>"
class Flash_lpc800(Flash):
def __init__(self, target):
Flash.__init__(self, target, flash_algo, memoryMapXML)

View File

@ -1,18 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from gdbserver import GDBServer

View File

@ -1,55 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import socket, select
class GDBSocket():
def __init__(self, port, packet_size):
self.packet_size = packet_size
self.s = None
self.conn = None
self.port = port
return
def init(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind(('', self.port))
self.s.listen(5)
def connect(self):
self.conn = None
self.init()
rr,_,_ = select.select([self.s],[],[], 0.5)
if rr:
self.conn, _ = self.s.accept()
return self.conn
def read(self):
return self.conn.recv(self.packet_size)
def write(self, data):
return self.conn.send(data)
def close(self):
if self.conn != None:
self.conn.close()
return self.s.close()
def setBlocking(self, blocking):
return self.conn.setblocking(blocking)

View File

@ -1,51 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
try:
from websocket import create_connection
except:
pass
class GDBWebSocket():
def __init__(self, url):
self.url = url
self.wss = None
return
def connect(self):
self.wss = None
try:
self.wss = create_connection(self.url)
except:
pass
return self.wss
def read(self):
return self.wss.recv()
def write(self, data):
return self.wss.send(data)
def close(self):
return self.wss.close()
def setBlocking(self, blocking):
if blocking != 0:
self.wss.settimeout(None)
else:
self.wss.settimeout(0)

View File

@ -1,594 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import logging, threading, socket
from pyOCD.target.cortex_m import CORE_REGISTER
from pyOCD.target.target import TARGET_HALTED
from struct import unpack
from time import sleep
import sys
from gdb_socket import GDBSocket
from gdb_websocket import GDBWebSocket
"""
import os
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,parentdir)
"""
SIGINT = (2)
SIGSEGV = (11)
SIGILL = (4)
SIGSTOP = (17)
SIGTRAP = (5)
SIGBUS = (10)
FAULT = {0: "17", #SIGSTOP
1: "17",
2: "02", #SIGINT
3: "11", #SIGSEGV
4: "11",
5: "10", #SIGBUS
6: "04", #SIGILL
7: "17",
8: "17",
9: "17",
10: "17",
11: "17",
12: "17",
13: "17",
14: "17",
15: "17",
}
class GDBServer(threading.Thread):
"""
This class start a GDB server listening a gdb connection on a specific port.
It implements the RSP (Remote Serial Protocol).
"""
def __init__(self, board, port_urlWSS):
threading.Thread.__init__(self)
self.board = board
self.target = board.target
self.flash = board.flash
self.abstract_socket = None
self.wss_server = None
self.port = 0
if isinstance(port_urlWSS, str) == True:
self.wss_server = port_urlWSS
else:
self.port = port_urlWSS
self.packet_size = 2048
self.flashData = ""
self.conn = None
self.lock = threading.Lock()
self.shutdown_event = threading.Event()
self.detach_event = threading.Event()
self.quit = False
if self.wss_server == None:
self.abstract_socket = GDBSocket(self.port, self.packet_size)
else:
self.abstract_socket = GDBWebSocket(self.wss_server)
self.start()
def restart(self):
if self.isAlive():
self.detach_event.set()
def stop(self):
if self.isAlive():
self.shutdown_event.set()
while self.isAlive():
pass
logging.info("GDB server thread killed")
self.board.uninit()
def setBoard(self, board, stop = True):
self.lock.acquire()
if stop:
self.restart()
self.board = board
self.target = board.target
self.flash = board.flash
self.lock.release()
return
def run(self):
while True:
new_command = False
data = []
logging.info('GDB server started')
self.shutdown_event.clear()
self.detach_event.clear()
while not self.shutdown_event.isSet() and not self.detach_event.isSet():
connected = self.abstract_socket.connect()
if connected != None:
break
if self.shutdown_event.isSet():
return
if self.detach_event.isSet():
continue
logging.info("One client connected!")
while True:
if self.shutdown_event.isSet():
return
if self.detach_event.isSet():
continue
# read command
while True:
if (new_command == True):
new_command = False
break
try:
if self.shutdown_event.isSet() or self.detach_event.isSet():
break
self.abstract_socket.setBlocking(0)
data = self.abstract_socket.read()
if data.index("$") >= 0 and data.index("#") >= 0:
break
except (ValueError, socket.error):
pass
if self.shutdown_event.isSet():
return
if self.detach_event.isSet():
continue
self.abstract_socket.setBlocking(1)
data = data[data.index("$"):]
self.lock.acquire()
if len(data) != 0:
# decode and prepare resp
[resp, ack, detach] = self.handleMsg(data)
if resp is not None:
# ack
if ack:
resp = "+" + resp
# send resp
self.abstract_socket.write(resp)
# wait a '+' from the client
try:
data = self.abstract_socket.read()
if data[0] != '+':
logging.debug('gdb client has not ack!')
else:
logging.debug('gdb client has ack!')
if data.index("$") >= 0 and data.index("#") >= 0:
new_command = True
except:
pass
if detach:
self.abstract_socket.close()
self.lock.release()
break
self.lock.release()
def handleMsg(self, msg):
if msg[0] != '$':
logging.debug('msg ignored: first char != $')
return None, 0, 0
#logging.debug('-->>>>>>>>>>>> GDB rsp packet: %s', msg)
# query command
if msg[1] == 'q':
return self.handleQuery(msg[2:]), 1, 0
elif msg[1] == 'H':
return self.createRSPPacket(''), 1, 0
elif msg[1] == '?':
return self.lastSignal(), 1, 0
elif msg[1] == 'g':
return self.getRegister(), 1, 0
elif msg[1] == 'p':
return self.readRegister(msg[2:]), 1, 0
elif msg[1] == 'P':
return self.writeRegister(msg[2:]), 1, 0
elif msg[1] == 'm':
return self.getMemory(msg[2:]), 1, 0
elif msg[1] == 'X':
return self.writeMemory(msg[2:]), 1, 0
elif msg[1] == 'v':
return self.flashOp(msg[2:]), 1, 0
# we don't send immediately the response for C and S commands
elif msg[1] == 'C' or msg[1] == 'c':
return self.resume()
elif msg[1] == 'S' or msg[1] == 's':
return self.step()
elif msg[1] == 'Z' or msg[1] == 'z':
return self.breakpoint(msg[1:]), 1, 0
elif msg[1] == 'D':
return self.detach(msg[1:]), 1, 1
elif msg[1] == 'k':
return self.kill(), 1, 1
else:
logging.error("Unknown RSP packet: %s", msg)
return None
def detach(self, data):
resp = "OK"
return self.createRSPPacket(resp)
def kill(self):
return self.createRSPPacket("")
def breakpoint(self, data):
# handle Z1/z1 commands
addr = int(data.split(',')[1], 16)
if data[1] == '1':
if data[0] == 'Z':
if self.target.setBreakpoint(addr) == False:
resp = "ENN"
return self.createRSPPacket(resp)
else:
self.target.removeBreakpoint(addr)
resp = "OK"
return self.createRSPPacket(resp)
return None
def resume(self):
self.ack()
self.target.resume()
self.abstract_socket.setBlocking(0)
val = ''
while True:
sleep(0.01)
try:
data = self.abstract_socket.read()
if (data[0] == '\x03'):
self.target.halt()
val = 'S05'
logging.debug("receive CTRL-C")
break
except:
pass
if self.target.getState() == TARGET_HALTED:
logging.debug("state halted")
val = 'S05'
break
self.target.halt()
ipsr = self.target.readCoreRegister('xpsr')
logging.debug("GDB resume xpsr: 0x%X", ipsr)
if (ipsr & 0x1f) == 3:
val = "S" + FAULT[3]
break
self.target.resume()
self.abstract_socket.setBlocking(1)
return self.createRSPPacket(val), 0, 0
def step(self):
self.ack()
self.target.step()
return self.createRSPPacket("S05"), 0, 0
def halt(self):
self.ack()
self.target.halt()
return self.createRSPPacket("S05"), 0, 0
def flashOp(self, data):
ops = data.split(':')[0]
#logging.debug("flash op: %s", ops)
if ops == 'FlashErase':
self.flash.init()
self.flash.eraseAll()
return self.createRSPPacket("OK")
elif ops == 'FlashWrite':
logging.debug("flash write addr: 0x%s", data.split(':')[1])
# search for second ':' (beginning of data encoded in the message)
second_colon = 0
idx_begin = 0
while second_colon != 2:
if data[idx_begin] == ':':
second_colon += 1
idx_begin += 1
self.flashData += data[idx_begin:len(data) - 3]
return self.createRSPPacket("OK")
# we need to flash everything
elif 'FlashDone' in ops :
flashPtr = 0
unescaped_data = self.unescape(self.flashData)
bytes_to_be_written = len(unescaped_data)
"""
bin = open(os.path.join(parentdir, 'res', 'bad_bin.txt'), "w+")
i = 0
while (i < bytes_to_be_written):
bin.write(str(unescaped_data[i:i+16]) + "\n")
i += 16
"""
logging.info("flashing %d bytes", bytes_to_be_written)
while len(unescaped_data) > 0:
size_to_write = min(self.flash.page_size, len(unescaped_data))
self.flash.programPage(flashPtr, unescaped_data[:size_to_write])
flashPtr += size_to_write
unescaped_data = unescaped_data[size_to_write:]
# print progress bar
sys.stdout.write('\r')
i = int((float(flashPtr)/float(bytes_to_be_written))*20.0)
# the exact output you're looking for:
sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
sys.stdout.flush()
sys.stdout.write("\n\r")
self.flashData = ""
"""
bin.close()
"""
# reset and stop on reset handler
self.target.resetStopOnReset()
return self.createRSPPacket("OK")
elif 'Cont' in ops:
if 'Cont?' in ops:
return self.createRSPPacket("vCont;c;s;t")
return None
def unescape(self, data):
data_idx = 0
# unpack the data into binary array
str_unpack = str(len(data)) + 'B'
data = unpack(str_unpack, data)
data = list(data)
# check for escaped characters
while data_idx < len(data):
if data[data_idx] == 0x7d:
data.pop(data_idx)
data[data_idx] = data[data_idx] ^ 0x20
data_idx += 1
return data
def getMemory(self, data):
split = data.split(',')
addr = int(split[0], 16)
length = split[1]
length = int(length[:len(length)-3],16)
val = ''
mem = self.target.readBlockMemoryUnaligned8(addr, length)
for x in mem:
if x >= 0x10:
val += hex(x)[2:4]
else:
val += '0' + hex(x)[2:3]
return self.createRSPPacket(val)
def writeMemory(self, data):
split = data.split(',')
addr = int(split[0], 16)
length = int(split[1].split(':')[0], 16)
idx_begin = 0
for i in range(len(data)):
if data[i] == ':':
idx_begin += 1
break
idx_begin += 1
data = data[idx_begin:len(data) - 3]
data = self.unescape(data)
if length > 0:
self.target.writeBlockMemoryUnaligned8(addr, data)
return self.createRSPPacket("OK")
def readRegister(self, data):
num = int(data.split('#')[0], 16)
reg = self.target.readCoreRegister(num)
logging.debug("GDB: read reg %d: 0x%X", num, reg)
val = self.intToHexGDB(reg)
return self.createRSPPacket(val)
def writeRegister(self, data):
num = int(data.split('=')[0], 16)
val = data.split('=')[1].split('#')[0]
val = val[6:8] + val[4:6] + val[2:4] + val[0:2]
logging.debug("GDB: write reg %d: 0x%X", num, int(val, 16))
self.target.writeCoreRegister(num, int(val, 16))
return self.createRSPPacket("OK")
def intToHexGDB(self, val):
val = hex(int(val))[2:]
size = len(val)
r = ''
for i in range(8-size):
r += '0'
r += str(val)
resp = ''
for i in range(4):
resp += r[8 - 2*i - 2: 8 - 2*i]
return resp
def getRegister(self):
resp = ''
for i in range(len(CORE_REGISTER)):
reg = self.target.readCoreRegister(i)
resp += self.intToHexGDB(reg)
logging.debug("GDB reg: %s = 0x%X", i, reg)
return self.createRSPPacket(resp)
def lastSignal(self):
fault = self.target.readCoreRegister('xpsr') & 0xff
fault = FAULT[fault]
logging.debug("GDB lastSignal: %s", fault)
return self.createRSPPacket('S' + fault)
def handleQuery(self, msg):
query = msg.split(':')
logging.debug('GDB received query: %s', query)
if query is None:
logging.error('GDB received query packet malformed')
return None
if query[0] == 'Supported':
resp = "qXfer:memory-map:read+;qXfer:features:read+;PacketSize="
resp += hex(self.packet_size)[2:]
return self.createRSPPacket(resp)
elif query[0] == 'Xfer':
if query[1] == 'features' and query[2] == 'read' and \
query[3] == 'target.xml':
data = query[4].split(',')
resp = self.handleQueryXML('read_feature', int(data[0], 16), int(data[1].split('#')[0], 16))
return self.createRSPPacket(resp)
elif query[1] == 'memory-map' and query[2] == 'read':
data = query[4].split(',')
resp = self.handleQueryXML('momery_map', int(data[0], 16), int(data[1].split('#')[0], 16))
return self.createRSPPacket(resp)
else:
return None
elif query[0] == 'C#b4':
return self.createRSPPacket("")
elif query[0].find('Attached') != -1:
return self.createRSPPacket("1")
elif query[0].find('TStatus') != -1:
return self.createRSPPacket("")
elif query[0].find('Tf') != -1:
return self.createRSPPacket("")
elif 'Offsets' in query[0]:
resp = "Text=0;Data=0;Bss=0"
return self.createRSPPacket(resp)
elif 'Symbol' in query[0]:
resp = "OK"
return self.createRSPPacket(resp)
else:
return None
def handleQueryXML(self, query, offset, size):
logging.debug('GDB query %s: offset: %s, size: %s', query, offset, size)
xml = ''
if query == 'momery_map':
xml = self.flash.memoryMapXML
elif query == 'read_feature':
xml = self.target.targetXML
size_xml = len(xml)
prefix = 'm'
if offset > size_xml:
logging.error('GDB: offset target.xml > size!')
return
if size > (self.packet_size - 4):
size = self.packet_size - 4
nbBytesAvailable = size_xml - offset
if size > nbBytesAvailable:
prefix = 'l'
size = nbBytesAvailable
resp = prefix + xml[offset:offset + size]
return resp
def createRSPPacket(self, data):
resp = '$' + data + '#'
c = 0
checksum = 0
for c in data:
checksum += ord(c)
checksum = checksum % 256
checksum = hex(checksum)
if int(checksum[2:], 16) < 0x10:
resp += '0'
resp += checksum[2:]
#logging.debug('--<<<<<<<<<<<< GDB rsp packet: %s', resp)
return resp
def ack(self):
self.abstract_socket.write("+")

View File

@ -1,23 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from pyusb_backend import PyUSB
from pywinusb_backend import PyWinUSB
INTERFACE = {'pyusb': PyUSB,
'pywinusb': PyWinUSB
}

View File

@ -1,45 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
class Interface:
def __init__(self):
self.vid = 0
self.pid = 0
self.vendor_name = ""
self.product_name = ""
return
def init(self):
return
def write(self, data):
return
def read(self, size = -1, timeout = -1):
return
def getInfo(self):
return self.vendor_name + " " + \
self.product_name + " (" + \
str(hex(self.vid)) + ", " + \
str(hex(self.pid)) + ")"
def close(self):
return

View File

@ -1,138 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from interface import Interface
import logging, os
try:
import usb.core
import usb.util
except:
if os.name == "posix":
logging.error("PyUSB is required on a Linux Machine")
class PyUSB(Interface):
"""
This class provides basic functions to access
a USB HID device using pyusb:
- write/read an endpoint
"""
vid = 0
pid = 0
def __init__(self):
self.ep_out = None
self.ep_in = None
self.dev = None
@staticmethod
def getAllConnectedInterface(vid, pid):
"""
returns all the connected devices which matches PyUSB.vid/PyUSB.pid.
returns an array of PyUSB (Interface) objects
"""
# find all devices matching the vid/pid specified
all_devices = usb.core.find(find_all=True, idVendor=vid, idProduct=pid)
if all_devices is None:
logging.debug("No device connected")
return None
boards = []
# iterate on all devices found
for board in all_devices:
intf_number = 0
found = False
# get active config
config = board.get_active_configuration()
# iterate on all interfaces:
# - if we found a HID interface -> CMSIS-DAP
for interface in config:
if interface.bInterfaceClass == 0x03:
intf_number = interface.bInterfaceNumber
found = True
break
if found == False:
continue
try:
if board.is_kernel_driver_active(intf_number) is True:
board.detach_kernel_driver(intf_number)
except Exception as e:
print e
pass
intf = usb.util.find_descriptor(config, bInterfaceNumber = intf_number)
ep_out = usb.util.find_descriptor(intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT
)
ep_in = usb.util.find_descriptor(intf,
# match the first IN endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN
)
product_name = usb.util.get_string(board, 256, 2)
vendor_name = usb.util.get_string(board, 256, 1)
if ep_out is None or ep_in is None:
logging.error('Endpoints not found')
return None
new_board = PyUSB()
new_board.ep_in = ep_in
new_board.ep_out = ep_out
new_board.dev = board
new_board.vid = vid
new_board.pid = pid
new_board.product_name = product_name
new_board.vendor_name = vendor_name
boards.append(new_board)
return boards
def write(self, data):
"""
write data on the OUT endpoint associated to the HID interface
"""
if self.ep_out is None:
raise ValueError('EP_OUT endpoint is NULL')
self.ep_out.write(data)
#logging.debug('sent: %s', data)
return
def read(self, timeout = -1):
"""
read data on the IN endpoint associated to the HID interface
"""
if self.ep_in is None:
raise ValueError('EP_IN endpoint is NULL')
data = self.ep_in.read(self.ep_in.wMaxPacketSize, timeout)
#logging.debug('received: %s', data)
return data

View File

@ -1,116 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from interface import Interface
import logging, os
try:
import pywinusb.hid as hid
except:
if os.name == "nt":
logging.error("PyWinUSB is required on a Windows Machine")
class PyWinUSB(Interface):
"""
This class provides basic functions to access
a USB HID device using pywinusb:
- write/read an endpoint
"""
vid = 0
pid = 0
def __init__(self):
# Vendor page and usage_id = 2
self.report = []
self.rcv_data = []
self.device = None
return
# handler called when a report is received
def rx_handler(self, data):
#logging.debug("rcv: %s", data[1:])
self.rcv_data.append(data[1:])
def open(self):
self.device.set_raw_data_handler(self.rx_handler)
self.device.open()
@staticmethod
def getAllConnectedInterface(vid, pid):
"""
returns all the connected devices which matches PyWinUSB.vid/PyWinUSB.pid.
returns an array of PyWinUSB (Interface) objects
"""
all_devices = hid.find_all_hid_devices()
# find devices with good vid/pid
all_mbed_devices = []
for d in all_devices:
if (d.vendor_id == vid) and (d.product_id == pid):
all_mbed_devices.append(d)
if not all_mbed_devices:
logging.debug("No Mbed device connected")
return
boards = []
for dev in all_mbed_devices:
try:
dev.open()
report = dev.find_output_reports()
if (len(report) == 1):
new_board = PyWinUSB()
new_board.report = report[0]
new_board.vendor_name = dev.vendor_name
new_board.product_name = dev.product_name
new_board.vid = dev.vendor_id
new_board.pid = dev.product_id
new_board.device = dev
new_board.device.set_raw_data_handler(new_board.rx_handler)
boards.append(new_board)
except Exception as e:
logging.error("Receiving Exception: %s", e)
dev.close()
return boards
def write(self, data):
"""
write data on the OUT endpoint associated to the HID interface
"""
for _ in range(64 - len(data)):
data.append(0)
#logging.debug("send: %s", data)
self.report.send([0] + data)
return
def read(self, timeout = -1):
"""
read data on the IN endpoint associated to the HID interface
"""
while len(self.rcv_data) == 0:
pass
return self.rcv_data.pop(0)
def close(self):
"""
close the interface
"""
logging.debug("closing interface")
self.device.close()

View File

@ -1,29 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import cortex_m
import target_lpc1768
import target_kl25z
import target_lpc11u24
import target_lpc800
TARGET = {'cortex_m': cortex_m.CortexM,
'target_lpc1768': target_lpc1768.LPC1768,
'target_kl25z': target_kl25z.KL25Z,
'target_lpc11u24': target_lpc11u24.LPC11U24,
'target_lpc800': target_lpc800.LPC800,
}

View File

@ -1,554 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from pyOCD.target.target import Target
from pyOCD.target.target import TARGET_RUNNING, TARGET_HALTED
from pyOCD.transport.cmsis_dap import DP_REG
import logging
# Debug Halting Control and Status Register
DHCSR = 0xE000EDF0
# Debug Core Register Selector Register
DCRSR = 0xE000EDF4
REGWnR = (1 << 16)
# Debug Core Register Data Register
DCRDR = 0xE000EDF8
# Debug Exception and Monitor Control Register
DEMCR = 0xE000EDFC
TRACE_ENA = (1 << 24)
VC_HARDERR = (1 << 9)
VC_BUSERR = (1 << 8)
VC_CORERESET = (1 << 0)
NVIC_AIRCR = (0xE000ED0C)
NVIC_AIRCR_VECTKEY = (0x5FA << 16)
NVIC_AIRCR_VECTRESET = (1 << 0)
NVIC_AIRCR_SYSRESETREQ = (1 << 2)
CSYSPWRUPACK = 0x80000000
CDBGPWRUPACK = 0x20000000
CSYSPWRUPREQ = 0x40000000
CDBGPWRUPREQ = 0x10000000
TRNNORMAL = 0x00000000
MASKLANE = 0x00000f00
C_DEBUGEN = (1 << 0)
C_HALT = (1 << 1)
C_STEP = (1 << 2)
C_MASKINTS = (1 << 3)
C_SNAPSTALL = (1 << 4)
DBGKEY = (0xA05F << 16)
# FPB (breakpoint)
FP_CTRL = (0xE0002000)
FP_CTRL_KEY = (1 << 1)
FP_COMP0 = (0xE0002008)
CORE_REGISTER = {'r0': 0,
'r1': 1,
'r2': 2,
'r3': 3,
'r4': 4,
'r5': 5,
'r6': 6,
'r7': 7,
'r8': 8,
'r9': 9,
'r10': 10,
'r11': 11,
'r12': 12,
'sp': 13,
'lr': 14,
'pc': 15,
'xpsr': 16,
}
targetXML = "<?xml version=\"1.0\"?>\n" \
"<!DOCTYPE feature SYSTEM \"gdb-target.dtd\">\n" \
"<target>\n" \
"<feature name=\"org.gnu.gdb.arm.m-profile\">\n" \
"<reg name=\"r0\" bitsize=\"32\"/>\n" \
"<reg name=\"r1\" bitsize=\"32\"/>\n" \
"<reg name=\"r2\" bitsize=\"32\"/>\n" \
"<reg name=\"r3\" bitsize=\"32\"/>\n" \
"<reg name=\"r4\" bitsize=\"32\"/>\n" \
"<reg name=\"r5\" bitsize=\"32\"/>\n" \
"<reg name=\"r6\" bitsize=\"32\"/>\n" \
"<reg name=\"r7\" bitsize=\"32\"/>\n" \
"<reg name=\"r8\" bitsize=\"32\"/>\n" \
"<reg name=\"r9\" bitsize=\"32\"/>\n" \
"<reg name=\"r10\" bitsize=\"32\"/>\n" \
"<reg name=\"r11\" bitsize=\"32\"/>\n" \
"<reg name=\"r12\" bitsize=\"32\"/>\n" \
"<reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n" \
"<reg name=\"lr\" bitsize=\"32\"/>\n" \
"<reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n" \
"<reg name=\"xpsr\" bitsize=\"32\" regnum=\"16\"/>\n" \
"</feature>\n" \
"</target>\n"
"""
convert a byte array into a word array
"""
def byte2word(data):
res = []
for i in range(len(data)/4):
res.append(data[i*4 + 0] << 0 |
data[i*4 + 1] << 8 |
data[i*4 + 2] << 16 |
data[i*4 + 3] << 24)
return res
"""
convert a word array into a byte array
"""
def word2byte(data):
res = []
for x in data:
res.append((x >> 0) & 0xff)
res.append((x >> 8) & 0xff)
res.append((x >> 16) & 0xff)
res.append((x >> 24) & 0xff)
return res
class Breakpoint():
def __init__(self, comp_register_addr):
self.comp_register_addr = comp_register_addr
self.enabled = False
self.addr = 0
class CortexM(Target):
"""
This class has basic functions to access a Cortex M core:
- init
- read/write memory
- read/write core registers
- set/remove hardware breakpoints
"""
def __init__(self, transport):
self.transport = transport
self.auto_increment_page_size = 0
self.idcode = 0
self.breakpoints = []
self.nb_code = 0
self.num_breakpoint_used = 0
self.nb_lit = 0
self.fpb_enabled = False
self.targetXML = targetXML
return
def init(self, setup_fpb = True):
"""
Cortex M initialization
"""
self.idcode = self.readIDCode()
# select bank 0 (to access DRW and TAR)
self.transport.writeDP(DP_REG['SELECT'], 0)
self.transport.writeDP(DP_REG['CTRL_STAT'], CSYSPWRUPREQ | CDBGPWRUPREQ)
while True:
r = self.transport.readDP(DP_REG['CTRL_STAT'])
if (r & (CDBGPWRUPACK | CSYSPWRUPACK)) == (CDBGPWRUPACK | CSYSPWRUPACK):
break
self.transport.writeDP(DP_REG['CTRL_STAT'], CSYSPWRUPREQ | CDBGPWRUPREQ | TRNNORMAL | MASKLANE)
self.transport.writeDP(DP_REG['SELECT'], 0)
if setup_fpb:
self.halt()
self.setupFPB()
return
def setupFPB(self):
"""
Reads the number of hardware breakpoints available on the core
and disable the FPB (Flash Patch and Breakpoint Unit)
which will be enabled when a first breakpoint will be set
"""
# setup FPB (breakpoint)
fpcr = self.readMemory(FP_CTRL)
self.nb_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF)
logging.info("%d hardware breakpoints", self.nb_code)
for i in range(self.nb_code):
self.breakpoints.append(Breakpoint(FP_COMP0 + 4*i))
# disable FPB (will be enabled on first bp set)
self.disableFPB()
for bp in self.breakpoints:
self.writeMemory(bp.comp_register_addr, 0)
def info(self, request):
return self.transport.info(request)
def readIDCode(self):
"""
return the IDCODE of the core
"""
if self.idcode == 0:
self.idcode = self.transport.readDP(DP_REG['IDCODE'])
return self.idcode
def writeMemory(self, addr, value, transfer_size = 32):
"""
write a memory location.
By default the transfer size is a word
"""
self.transport.writeMem(addr, value, transfer_size)
return
def readMemory(self, addr, transfer_size = 32):
"""
read a memory location. By default, a word will
be read
"""
return self.transport.readMem(addr, transfer_size)
def readBlockMemoryUnaligned8(self, addr, size):
"""
read a block of unaligned bytes in memory. Returns
an array of byte values
"""
res = []
# try to read 8bits data
if (size > 0) and (addr & 0x01):
mem = self.readMemory(addr, 8)
logging.debug("get 1 byte at %s: 0x%X", hex(addr), mem)
res.append(mem)
size -= 1
addr += 1
# try to read 16bits data
if (size > 1) and (addr & 0x02):
mem = self.readMemory(addr, 16)
logging.debug("get 2 bytes at %s: 0x%X", hex(addr), mem)
res.append(mem & 0xff)
res.append((mem >> 8) & 0xff)
size -= 2
addr += 2
# try to read aligned block of 32bits
if (size >= 4):
logging.debug("read blocks aligned at 0x%X, size: 0x%X", addr, (size/4)*4)
mem = self.readBlockMemoryAligned32(addr, size/4)
res += word2byte(mem)
size -= 4*len(mem)
addr += 4*len(mem)
if (size > 1):
mem = self.readMemory(addr, 16)
logging.debug("get 2 bytes at %s: 0x%X", hex(addr), mem)
res.append(mem & 0xff)
res.append((mem >> 8) & 0xff)
size -= 2
addr += 2
if (size > 0):
mem = self.readMemory(addr, 8)
logging.debug("get 1 byte remaining at %s: 0x%X", hex(addr), mem)
res.append(mem)
size -= 1
addr += 1
return res
def writeBlockMemoryUnaligned8(self, addr, data):
"""
write a block of unaligned bytes in memory.
"""
size = len(data)
idx = 0
#try to write 8 bits data
if (size > 0) and (addr & 0x01):
logging.debug("write 1 byte at 0x%X: 0x%X", addr, data[idx])
self.writeMemory(addr, data[idx], 8)
size -= 1
addr += 1
idx += 1
# try to write 16 bits data
if (size > 1) and (addr & 0x02):
logging.debug("write 2 bytes at 0x%X: 0x%X", addr, data[idx] | (data[idx+1] << 8))
self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16)
size -= 2
addr += 2
idx += 2
# write aligned block of 32 bits
if (size >= 4):
logging.debug("write blocks aligned at 0x%X, size: 0x%X", addr, (size/4)*4)
data32 = byte2word(data[idx:idx + (size & ~0x03)])
self.writeBlockMemoryAligned32(addr, data32)
addr += size & ~0x03
idx += size & ~0x03
size -= size & ~0x03
# try to write 16 bits data
if (size > 1):
logging.debug("write 2 bytes at 0x%X: 0x%X", addr, data[idx] | (data[idx+1] << 8))
self.writeMemory(addr, data[idx] | (data[idx+1] << 8), 16)
size -= 2
addr += 2
idx += 2
#try to write 8 bits data
if (size > 0):
logging.debug("write 1 byte at 0x%X: 0x%X", addr, data[idx])
self.writeMemory(addr, data[idx], 8)
size -= 1
addr += 1
idx += 1
return
def writeBlockMemoryAligned32(self, addr, data):
"""
write a block of aligned words in memory.
"""
size = len(data)
while size > 0:
n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1))
if size*4 < n:
n = (size*4) & 0xfffffffc
self.transport.writeBlock32(addr, data[:n/4])
data = data[n/4:]
size -= n/4
addr += n
return
def readBlockMemoryAligned32(self, addr, size):
"""
read a block of aligned words in memory. Returns
an array of word values
"""
resp = []
while size > 0:
n = self.auto_increment_page_size - (addr & (self.auto_increment_page_size - 1))
if size*4 < n:
n = (size*4) & 0xfffffffc
resp += self.transport.readBlock32(addr, n/4)
size -= n/4
addr += n
return resp
def halt(self):
"""
halt the core
"""
self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_HALT)
return
def step(self):
"""
perform an instruction level step
"""
if self.getState() != TARGET_HALTED:
logging.debug('cannot step: target not halted')
return
if self.maybeSkipBreakpoint() is None:
self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_STEP)
return
def reset(self):
"""
reset a core. After a call to this function, the core
is running
"""
self.transport.reset()
def resetStopOnReset(self):
"""
perform a reset and stop the core on the reset handler
"""
logging.debug("reset stop on Reset")
# read address of reset handler
reset_handler = self.readMemory(4)
# reset and halt the target
self.transport.reset()
self.halt()
# set a breakpoint to the reset handler and reset the target
self.setBreakpoint(reset_handler)
self.transport.reset()
# wait until the bp is reached
while (self.getState() == TARGET_RUNNING):
pass
# remove the breakpoint
self.removeBreakpoint(reset_handler)
logging.debug("stopped on reset handler: 0x%X", reset_handler)
def setTargetState(self, state):
if state == "PROGRAM":
self.reset()
self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN)
self.writeMemory(DEMCR, VC_CORERESET)
self.writeMemory(NVIC_AIRCR, NVIC_AIRCR_VECTKEY | NVIC_AIRCR_SYSRESETREQ)
while self.getState() == TARGET_RUNNING:
pass
self.writeMemory(DEMCR, 0)
def getState(self):
dhcsr = self.readMemory(DHCSR)
if dhcsr & (C_STEP | C_HALT):
return TARGET_HALTED
return TARGET_RUNNING
def resume(self):
"""
resume the execution
"""
if self.getState() != TARGET_HALTED:
logging.debug('cannot resume: target not halted')
return
self.maybeSkipBreakpoint()
self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN)
return
def maybeSkipBreakpoint(self):
pc = self.readCoreRegister('pc')
bp = self.findBreakpoint(pc)
if bp is not None:
logging.debug('skip/resume breakpoint: pc 0x%X', pc)
self.removeBreakpoint(pc)
self.writeMemory(DHCSR, DBGKEY | C_DEBUGEN | C_STEP)
self.setBreakpoint(pc)
logging.debug('step over breakpoint: now pc0x%X', self.readCoreRegister('pc'))
return bp
return None
def findBreakpoint(self, addr):
for bp in self.breakpoints:
if bp.enabled and bp.addr == addr:
return bp
return None
def readCoreRegister(self, reg):
"""
read a core register (r0 .. r16).
If reg is a string, find the number associated to this register
in the lookup table CORE_REGISTER
"""
if isinstance(reg, str):
try:
reg = CORE_REGISTER[reg]
except KeyError:
logging.error('cannot find %s core register', id)
return
if (reg < 0) or (reg > len(CORE_REGISTER)):
logging.error("unknown reg: %d", reg)
return
# write id in DCRSR
self.writeMemory(DCRSR, reg)
# read DCRDR
return self.readMemory(DCRDR)
def writeCoreRegister(self, reg, data):
"""
write a core register (r0 .. r16)
If reg is a string, find the number associated to this register
in the lookup table CORE_REGISTER
"""
if isinstance(reg, str):
try:
reg = CORE_REGISTER[reg]
except KeyError:
logging.error('cannot find %s core register', id)
return
if (reg < 0) or (reg > len(CORE_REGISTER)):
logging.error("unknown reg: %d", reg)
return
# write id in DCRSR
self.writeMemory(DCRDR, data)
# read DCRDR
self.writeMemory(DCRSR, reg | REGWnR)
return
def setBreakpoint(self, addr):
"""
set a hardware breakpoint at a specific location in flash
"""
if self.fpb_enabled is False:
self.enableFPB()
if self.availableBreakpoint() == 0:
logging.error('No more available breakpoint!!, dropped bp at 0x%X', addr)
return False
for bp in self.breakpoints:
if not bp.enabled:
bp.enabled = True
bp_match = (1 << 30)
if addr & 0x2:
bp_match = (2 << 30)
self.writeMemory(bp.comp_register_addr, addr & 0x1ffffffc | bp_match | 1)
bp.addr = addr
self.num_breakpoint_used += 1
return True
return False
def availableBreakpoint(self):
return len(self.breakpoints) - self.num_breakpoint_used
def enableFPB(self):
self.writeMemory(FP_CTRL, FP_CTRL_KEY | 1)
self.fpb_enabled = True
logging.debug('fpb has been enabled')
return
def disableFPB(self):
self.writeMemory(FP_CTRL, FP_CTRL_KEY | 0)
self.fpb_enabled = False
logging.debug('fpb has been disabled')
return
def removeBreakpoint(self, addr):
"""
remove a hardware breakpoint at a specific location in flash
"""
for bp in self.breakpoints:
if bp.enabled and bp.addr == addr:
bp.enabled = False
self.writeMemory(bp.comp_register_addr, 0)
bp.addr = addr
self.num_breakpoint_used -= 1
return
return
# GDB functions
def getTargetXML(self):
return self.targetXML, len(self.targetXML)

View File

@ -1,82 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
TARGET_RUNNING = (1 << 0)
TARGET_HALTED = (1 << 1)
class Target():
def __init__(self, transport):
return
def init(self):
return
def info(self, request):
return
def readIDCode(self):
return
def halt(self):
return
def step(self):
return
def resume(self):
return
def writeMemory(self, addr, value, transfer_size = 32):
return
def readMemory(self, addr, transfer_size = 32):
return
def writeBlockMemoryUnaligned8(self, addr, value):
return
def writeBlockMemoryAligned32(self, addr, data):
return
def readBlockMemoryUnaligned8(self, addr, size):
return
def readBlockMemoryAligned32(self, addr, size):
return
def readCoreRegister(self, id):
return
def writeCoreRegister(self, id):
return
def setBreakpoint(self, addr):
return
def removeBreakpoint(self, addr):
return
def reset(self):
return
def getState(self):
return
# GDB functions
def getTargetXML(self):
return

View File

@ -1,57 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cortex_m import CortexM
import logging
MDM_STATUS = 0x01000000
MDM_CTRL = 0x01000004
MDM_IDR = 0x010000fc
class KL25Z(CortexM):
def __init__(self, transport):
CortexM.__init__(self, transport)
self.auto_increment_page_size = 0x400
def init(self):
CortexM.init(self, False)
# check for flash security
val = self.transport.readAP(MDM_IDR)
if val != 0x001c0020:
logging.error("KL25Z: bad flash ID")
val = self.transport.readAP(MDM_STATUS)
if (val & (1 << 2)):
logging.warning("KL25Z secure state: will try to unlock")
self.transport.assertReset(True)
while True:
self.transport.writeAP(MDM_CTRL, 1)
val = self.transport.readAP(MDM_STATUS)
logging.info(val)
if (val & 1):
break
while True:
self.transport.writeAP(MDM_CTRL, 0)
val = self.transport.readAP(MDM_CTRL)
if (val == 0):
break
logging.info("KL25Z not in secure state")
self.halt()
self.setupFPB()

View File

@ -1,24 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cortex_m import CortexM
class LPC11U24(CortexM):
def __init__(self, transport):
CortexM.__init__(self, transport)
self.auto_increment_page_size = 0x400

View File

@ -1,40 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cortex_m import CortexM
class LPC1768(CortexM):
def __init__(self, transport):
CortexM.__init__(self, transport)
self.auto_increment_page_size = 0x1000
def reset(self):
# halt processor
self.halt()
# not remap 0x0000-0x0020 to anything but the flash
self.writeMemory(0x400FC040, 1)
CortexM.reset(self)
def resetStopOnReset(self):
# halt processor
self.halt()
# not remap 0x0000-0x0020 to anything but the flash
self.writeMemory(0x400FC040, 1)
CortexM.resetStopOnReset(self)

View File

@ -1,24 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cortex_m import CortexM
class LPC800(CortexM):
def __init__(self, transport):
CortexM.__init__(self, transport)
self.auto_increment_page_size = 0x400

View File

@ -1,21 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cmsis_dap import CMSIS_DAP
TRANSPORT = {'cmsis_dap': CMSIS_DAP
}

View File

@ -1,229 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from cmsis_dap_core import dapTransferBlock, dapWriteAbort, dapSWJPins, dapConnect, dapDisconnect, dapTransfer, dapSWJSequence, dapSWDConfigure, dapSWJClock, dapTransferConfigure, dapInfo
from transport import Transport
import logging
from time import sleep
# !! This value are A[2:3] and not A[3:2]
DP_REG = {'IDCODE' : 0x00,
'ABORT' : 0x00,
'CTRL_STAT': 0x04,
'SELECT': 0x08
}
AP_REG = {'CSW' : 0x00,
'TAR' : 0x04,
'DRW' : 0x0C
}
IDCODE = 0 << 2
AP_ACC = 1 << 0
DP_ACC = 0 << 0
READ = 1 << 1
WRITE = 0 << 1
VALUE_MATCH = 1 << 4
MATCH_MASK = 1 << 5
APBANKSEL = 0x000000f0
# AP Control and Status Word definitions
CSW_SIZE = 0x00000007
CSW_SIZE8 = 0x00000000
CSW_SIZE16 = 0x00000001
CSW_SIZE32 = 0x00000002
CSW_ADDRINC = 0x00000030
CSW_NADDRINC = 0x00000000
CSW_SADDRINC = 0x00000010
CSW_PADDRINC = 0x00000020
CSW_DBGSTAT = 0x00000040
CSW_TINPROG = 0x00000080
CSW_HPROT = 0x02000000
CSW_MSTRTYPE = 0x20000000
CSW_MSTRCORE = 0x00000000
CSW_MSTRDBG = 0x20000000
CSW_RESERVED = 0x01000000
CSW_VALUE = (CSW_RESERVED | CSW_MSTRDBG | CSW_HPROT | CSW_DBGSTAT | CSW_SADDRINC)
TRANSFER_SIZE = {8: CSW_SIZE8,
16: CSW_SIZE16,
32: CSW_SIZE32
}
def JTAG2SWD(interface):
data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
dapSWJSequence(interface, data)
data = [0x9e, 0xe7]
dapSWJSequence(interface, data)
data = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
dapSWJSequence(interface, data)
data = [0x00]
dapSWJSequence(interface, data)
class CMSIS_DAP(Transport):
"""
This class implements the CMSIS-DAP protocol
"""
def __init__(self, interface):
self.interface = interface
self.packet_max_count = 0
self.packet_max_size = 0
self.csw = -1
self.dp_select = -1
return
def init(self):
# init dap IO
dapConnect(self.interface)
# set clock freq at 1000000Hz
dapSWJClock(self.interface)
# configure transfer
dapTransferConfigure(self.interface)
# configure swd protocol
dapSWDConfigure(self.interface)
# switch from jtag to swd
JTAG2SWD(self.interface)
# read ID code
logging.info('IDCODE: 0x%X', self.readDP(DP_REG['IDCODE']))
# clear abort err
dapWriteAbort(self.interface, 0x1e);
return
def uninit(self):
dapDisconnect(self.interface)
return
def info(self, request):
resp = None
try:
resp = dapInfo(self.interface, request)
except KeyError:
logging.error('request %s not supported', request)
return resp
def writeMem(self, addr, data, transfer_size = 32):
self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size])
if transfer_size == 8:
data = data << ((addr & 0x03) << 3)
elif transfer_size == 16:
data = data << ((addr & 0x02) << 3)
dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'],
WRITE | AP_ACC | AP_REG['DRW']],
[addr, data])
def readMem(self, addr, transfer_size = 32):
self.writeAP(AP_REG['CSW'], CSW_VALUE | TRANSFER_SIZE[transfer_size])
resp = dapTransfer(self.interface, 2, [WRITE | AP_ACC | AP_REG['TAR'],
READ | AP_ACC | AP_REG['DRW']],
[addr])
res = (resp[0] << 0) | \
(resp[1] << 8) | \
(resp[2] << 16) | \
(resp[3] << 24)
if transfer_size == 8:
res = (res >> ((addr & 0x03) << 3) & 0xff)
elif transfer_size == 16:
res = (res >> ((addr & 0x02) << 3) & 0xffff)
return res
# write aligned word ("data" are words)
def writeBlock32(self, addr, data):
# put address in TAR
self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)
self.writeAP(AP_REG['TAR'], addr)
dapTransferBlock(self.interface, len(data), WRITE | AP_ACC | AP_REG['DRW'], data)
return
# read aligned word (the size is in words)
def readBlock32(self, addr, size):
# put address in TAR
self.writeAP(AP_REG['CSW'], CSW_VALUE | CSW_SIZE32)
self.writeAP(AP_REG['TAR'], addr)
data = []
resp = dapTransferBlock(self.interface, size, READ | AP_ACC | AP_REG['DRW'])
for i in range(len(resp)/4):
data.append( (resp[i*4 + 0] << 0) | \
(resp[i*4 + 1] << 8) | \
(resp[i*4 + 2] << 16) | \
(resp[i*4 + 3] << 24))
return data
def readDP(self, addr):
resp = dapTransfer(self.interface, 1, [READ | DP_ACC | (addr & 0x0c)])
return (resp[0] << 0) | \
(resp[1] << 8) | \
(resp[2] << 16) | \
(resp[3] << 24)
def writeDP(self, addr, data):
if addr == DP_REG['SELECT']:
if data == self.dp_select:
return
self.dp_select = data
dapTransfer(self.interface, 1, [WRITE | DP_ACC | (addr & 0x0c)], [data])
return True
def writeAP(self, addr, data):
if addr == AP_REG['CSW']:
if data == self.csw:
return
self.csw = data
ap_sel = addr & 0xff000000
bank_sel = addr & APBANKSEL
self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel)
dapTransfer(self.interface, 1, [WRITE | AP_ACC | (addr & 0x0c)], [data])
return True
def readAP(self, addr):
ap_sel = addr & 0xff000000
bank_sel = addr & APBANKSEL
self.writeDP(DP_REG['SELECT'], ap_sel | bank_sel)
resp = dapTransfer(self.interface, 1, [READ | AP_ACC | (addr & 0x0c)])
return (resp[0] << 0) | \
(resp[1] << 8) | \
(resp[2] << 16) | \
(resp[3] << 24)
def reset(self):
dapSWJPins(self.interface, 0, 'nRESET')
sleep(0.1)
dapSWJPins(self.interface, 0x80, 'nRESET')
sleep(0.1)
def assertReset(self, asserted):
if asserted:
dapSWJPins(self.interface, 0, 'nRESET')
else:
dapSWJPins(self.interface, 0x80, 'nRESET')

View File

@ -1,315 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import logging
import array
COMMAND_ID = {'DAP_INFO': 0x00,
'DAP_LED': 0x01,
'DAP_CONNECT': 0x02,
'DAP_DISCONNECT': 0x03,
'DAP_TRANSFER_CONFIGURE': 0x04,
'DAP_TRANSFER': 0x05,
'DAP_TRANSFER_BLOCK': 0x06,
'DAP_TRANSFER_ABORT': 0x07,
'DAP_WRITE_ABORT': 0x08,
'DAP_DELAY': 0x09,
'DAP_RESET_TARGET': 0x0a,
'DAP_SWJ_PINS': 0x10,
'DAP_SWJ_CLOCK': 0x11,
'DAP_SWJ_SEQUENCE': 0x12,
'DAP_SWD_CONFIGURE': 0x13,
}
ID_INFO = {'VENDOR_ID': 0x01,
'PRODUCT_ID': 0x02,
'SERIAL_NUMBER': 0x03,
'CMSIS_DAP_FW_VERSION': 0x04,
'TARGET_DEVICE_VENDOR': 0x05,
'TARGET_DEVICE_NAME': 0x06,
'CAPABILITIES': 0xf0,
'PACKET_COUNT': 0xfe,
'PACKET_SIZE': 0xff
}
PINS = {'None': 0x00,
'SWCLK_TCK': (1 << 0),
'SWDIO_TMS': (1 << 1),
'TDI': (1 << 2),
'TDO': (1 << 3),
'nTRST': (1 << 5),
'nRESET': (1 << 7),
}
DAP_DEFAULT_PORT = 0
DAP_SWD_PORT = 1
DAP_JTAG_POR = 2
DAP_OK = 0
DAP_ERROR = 0xff
MAX_PACKET_SIZE = 0x0E
def dapInfo(interface, id_):
cmd = []
cmd.append(COMMAND_ID['DAP_INFO'])
cmd.append(ID_INFO[id_])
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_INFO']:
raise ValueError('DAP_INFO response error')
if resp[1] == 0:
return
if resp[1] == 1:
return resp[2]
if resp[1] == 2:
return (resp[3] << 8) | resp[2]
x = array.array('B', [i for i in resp[2:2+resp[1]]])
return x.tostring()
def dapLed(interface):
#not yet implemented
return
def dapConnect(interface, mode = DAP_DEFAULT_PORT):
cmd = []
cmd.append(COMMAND_ID['DAP_CONNECT'])
cmd.append(mode)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_CONNECT']:
raise ValueError('DAP_CONNECT response error')
if resp[1] == 0:
raise ValueError('DAP Connect failed')
if resp[1] == 1:
logging.info('DAP SWD MODE initialised')
if resp[1] == 2:
logging.info('DAP JTAG MODE initialised')
return resp[1]
def dapDisconnect(interface):
cmd = []
cmd.append(COMMAND_ID['DAP_DISCONNECT'])
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_DISCONNECT']:
raise ValueError('DAP_DISCONNECT response error')
if resp[1] != DAP_OK:
raise ValueError('DAP Disconnect failed')
return resp[1]
def dapWriteAbort(interface, data, dap_index = 0):
cmd = []
cmd.append(COMMAND_ID['DAP_WRITE_ABORT'])
cmd.append(dap_index)
cmd.append((data >> 0) & 0xff)
cmd.append((data >> 8) & 0xff)
cmd.append((data >> 16) & 0xff)
cmd.append((data >> 24) & 0xff)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_WRITE_ABORT']:
raise ValueError('DAP_WRITE_ABORT response error')
if resp[1] != DAP_OK:
raise ValueError('DAP Write Abort failed')
return True
def dapResetTarget(interface):
cmd = []
cmd.append(COMMAND_ID['DAP_RESET_TARGET'])
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_RESET_TARGET']:
raise ValueError('DAP_RESET_TARGET response error')
if resp[1] != DAP_OK:
raise ValueError('DAP Reset target failed')
return resp[1]
def dapTransferConfigure(interface, idle_cycles = 0x00, wait_retry = 0x0050, match_retry = 0x0000):
cmd = []
cmd.append(COMMAND_ID['DAP_TRANSFER_CONFIGURE'])
cmd.append(idle_cycles)
cmd.append(wait_retry & 0xff)
cmd.append(wait_retry >> 8)
cmd.append(match_retry & 0xff)
cmd.append(match_retry >> 8)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_TRANSFER_CONFIGURE']:
raise ValueError('DAP_TRANSFER_CONFIGURE response error')
if resp[1] != DAP_OK:
raise ValueError('DAP Transfer Configure failed')
return resp[1]
def dapTransfer(interface, count, request, data = [0], dap_index = 0):
cmd = []
cmd.append(COMMAND_ID['DAP_TRANSFER'])
cmd.append(dap_index)
cmd.append(count)
count_write = count
for i in range(count):
cmd.append(request[i])
if not ( request[i] & ((1 << 1) | (1 << 4))):
cmd.append(data[i] & 0xff)
cmd.append((data[i] >> 8) & 0xff)
cmd.append((data[i] >> 16) & 0xff)
cmd.append((data[i] >> 24) & 0xff)
count_write -= 1
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_TRANSFER']:
raise ValueError('DAP_TRANSFER response error')
if resp[1] != count:
raise ValueError('Transfer not completed')
if resp[2] != 0x01:
raise ValueError('SWD Fault')
return resp[3:3+count_write*4]
def dapTransferBlock(interface, count, request, data = [0], dap_index = 0):
packet_count = count
nb = 0
resp = []
# we send successfully several packets if the size is bigger than MAX_PACKET_COUNT
while packet_count > 0:
cmd = []
cmd.append(COMMAND_ID['DAP_TRANSFER_BLOCK'])
cmd.append(dap_index)
packet_written = min(packet_count, MAX_PACKET_SIZE)
cmd.append(packet_written & 0xff)
cmd.append((packet_written >> 8) & 0xff)
cmd.append(request)
if not (request & ((1 << 1))):
for i in range(packet_written):
cmd.append(data[i + nb*MAX_PACKET_SIZE] & 0xff)
cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 8) & 0xff)
cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 16) & 0xff)
cmd.append((data[i + nb*MAX_PACKET_SIZE] >> 24) & 0xff)
interface.write(cmd)
packet_count = packet_count - MAX_PACKET_SIZE
nb = nb + 1
# we then read
tmp = interface.read()
if tmp[0] != COMMAND_ID['DAP_TRANSFER_BLOCK'] or tmp[3] != 0x01:
raise ValueError('DAP_TRANSFER_BLOCK response error')
size_transfer = tmp[1] | (tmp[2] << 8)
resp.extend(tmp[4:4+size_transfer*4])
return resp
def dapSWJClock(interface, clock = 1000000):
cmd = []
cmd.append(COMMAND_ID['DAP_SWJ_CLOCK'])
cmd.append(clock & 0xff)
cmd.append((clock >> 8) & 0xff)
cmd.append((clock >> 16) & 0xff)
cmd.append((clock >> 24) & 0xff)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_SWJ_CLOCK']:
raise ValueError('DAP_SWJ_CLOCK response error')
if resp[1] != DAP_OK:
raise ValueError('DAP SWJ Clock failed')
return resp[1]
def dapSWJPins(interface, output, pin, wait = 0):
cmd = []
cmd.append(COMMAND_ID['DAP_SWJ_PINS'])
try:
p = PINS[pin]
except KeyError:
logging.error('cannot find %s pin', pin)
return
cmd.append(output & 0xff)
cmd.append(p)
cmd.append(wait & 0xff)
cmd.append((wait >> 8) & 0xff)
cmd.append((wait >> 16) & 0xff)
cmd.append((wait >> 24) & 0xff)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_SWJ_PINS']:
raise ValueError('DAP_SWJ_PINS response error')
return resp[1]
def dapSWDConfigure(interface, conf = 0):
cmd = []
cmd.append(COMMAND_ID['DAP_SWD_CONFIGURE'])
cmd.append(conf)
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_SWD_CONFIGURE']:
raise ValueError('DAP_SWD_CONFIGURE response error')
if resp[1] != DAP_OK:
raise ValueError('DAP SWD Configure failed')
return resp[1]
def dapSWJSequence(interface, data):
cmd = []
cmd.append(COMMAND_ID['DAP_SWJ_SEQUENCE'])
cmd.append(len(data)*8)
for i in range(len(data)):
cmd.append(data[i])
interface.write(cmd)
resp = interface.read()
if resp[0] != COMMAND_ID['DAP_SWJ_SEQUENCE']:
raise ValueError('DAP_SWJ_SEQUENCE response error')
if resp[1] != DAP_OK:
raise ValueError('DAP SWJ Sequence failed')
return resp[1]

View File

@ -1,64 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
class Transport():
def __init__(self, interface):
self.interface = interface
return
def init(self):
return
def uninit(self):
return
def info(self, request):
return
def readDP(self, addr):
return
def writeDP(self, addr, data):
return
def writeAP(self, addr, data):
return
def readAP(self, addr):
return
def writeMem(self, addr, data, transfer_size = 32):
return
def readMem(self, addr, transfer_size = 32):
return
def writeBlock32(self, addr, data):
return
def readBlock32(self, addr, data):
return
def assertReset(self, asserted):
return
def getUniqueID(self):
return
def reset(self):
return

View File

@ -1,33 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from distutils.core import setup
setup(
name="pyOCD",
version="0.1",
description="CMSIS-DAP debugger for python",
author="samux",
author_email="samuel.mokrani@gmail.com",
license="Apache 2.0",
classifiers = [
"Development Status :: 4 - Beta",
"License :: Apache 2.0",
"Programming Language :: Python",
],
packages=["pyOCD", "pyOCD.flash", "pyOCD.gdbserver", "pyOCD.interface", "pyOCD.target", "pyOCD.transport", "pyOCD.board"]
)

View File

@ -1,165 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import argparse, os
from time import sleep
from random import randrange
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
from pyOCD.board import MbedBoard
addr = 0
size = 0
f = None
binary_file = "l1_"
interface = None
import logging
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description='A CMSIS-DAP python debugger')
parser.add_argument('-f', help='binary file', dest = "file")
args = parser.parse_args()
try:
board = MbedBoard.chooseBoard()
target_type = board.getTargetType()
if args.file is None:
binary_file += target_type + ".bin"
binary_file = os.path.join(parentdir, 'binaries', binary_file)
else:
binary_file = args.file
print "binary file: %s" % binary_file
if target_type == "lpc1768":
addr = 0x10000001
size = 0x1102
elif target_type == "lpc11u24":
addr = 0x10000001
size = 0x502
elif target_type == "kl25z":
addr = 0x20000001
size = 0x502
elif target_type == "lpc800":
addr = 0x10000001
size = 0x502
target = board.target
transport = board.transport
flash = board.flash
interface = board.interface
print "\r\n\r\n------ GET Unique ID ------"
print "Unique ID: %s" % board.getUniqueID()
print "\r\n\r\n------ TEST READ / WRITE CORE REGISTER ------"
pc = target.readCoreRegister('pc')
print "initial pc: 0x%X" % target.readCoreRegister('pc')
# write in pc dummy value
target.writeCoreRegister('pc', 0x3D82)
print "now pc: 0x%X" % target.readCoreRegister('pc')
# write initial pc value
target.writeCoreRegister('pc', pc)
print "initial pc value rewritten: 0x%X" % target.readCoreRegister('pc')
print "\r\n\r\n------ TEST HALT / RESUME ------"
print "resume"
target.resume()
sleep(0.2)
print "halt"
target.halt()
print "HALT: pc: 0x%X" % target.readCoreRegister('pc')
sleep(0.2)
print "\r\n\r\n------ TEST READ / WRITE MEMORY ------"
target.halt()
print "READ32/WRITE32"
val = randrange(0, 0xffffffff)
print "write32 0x%X at 0x%X" % (val, addr)
target.writeMemory(addr, val)
res = target.readMemory(addr)
print "read32 at 0x%X: 0x%X" % (addr, res)
if res != val:
print "ERROR in READ/WRITE 32"
print "\r\nREAD16/WRITE316"
val = randrange(0, 0xffff)
print "write16 0x%X at 0x%X" % (val, addr + 2)
target.writeMemory(addr + 2, val, 16)
res = target.readMemory(addr + 2, 16)
print "read16 at 0x%X: 0x%X" % (addr + 2, res)
if res != val:
print "ERROR in READ/WRITE 16"
print "\r\nREAD8/WRITE8"
val = randrange(0, 0xff)
print "write8 0x%X at 0x%X" % (val, addr + 1)
target.writeMemory(addr + 1, val, 8)
res = target.readMemory(addr + 1, 8)
print "read8 at 0x%X: 0x%X" % (addr + 1, res)
if res != val:
print "ERROR in READ/WRITE 8"
print "\r\n\r\n------ TEST READ / WRITE MEMORY BLOCK ------"
data = [randrange(1, 50) for x in range(size)]
target.writeBlockMemoryUnaligned8(addr, data)
block = target.readBlockMemoryUnaligned8(addr, size)
error = False
for i in range(len(block)):
if (block[i] != data[i]):
error = True
print "ERROR: 0x%X, 0x%X, 0x%X!!!" % ((addr + i), block[i], data[i])
if error:
print "TEST FAILED"
else:
print "TEST PASSED"
print "\r\n\r\n------ TEST RESET ------"
target.reset()
sleep(0.1)
target.halt()
for i in range(5):
target.step()
print "pc: 0x%X" % target.readCoreRegister('pc')
print "\r\n\r\n----- FLASH NEW BINARY -----"
flash.flashBinary(binary_file)
target.reset()
except Exception as e:
print "Unknown exception: %s" % e
finally:
if board != None:
board.uninit()

View File

@ -1,36 +0,0 @@
"""
mbed CMSIS-DAP debugger
Copyright (c) 2006-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import logging
from pyOCD.gdbserver import GDBServer
from pyOCD.board import MbedBoard
logging.basicConfig(level=logging.INFO)
try:
board_selected = MbedBoard.chooseBoard()
if board_selected != None:
gdb = GDBServer(board_selected, 3333)
while gdb.isAlive():
gdb.join(timeout = 0.5)
except KeyboardInterrupt:
gdb.stop()
except Exception as e:
print "uncaught exception: %s" % e
gdb.stop()

View File

@ -48,8 +48,26 @@ if __name__ == '__main__':
help="The name of the desired test program")
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
default=False, help="Verbose diagnostic output")
parser.add_option("-D", "", action="append", dest="macros",
help="Add a macro definition")
# Local run
parser.add_option("--automated", action="store_true", dest="automated",
default=False, help="Automated test")
parser.add_option("--host", dest="host_test",
default=None, help="Host test")
parser.add_option("--extra", dest="extra",
default=None, help="Extra files")
parser.add_option("--peripherals", dest="peripherals",
default=None, help="Required peripherals")
parser.add_option("--dep", dest="dependencies",
default=None, help="Dependencies")
parser.add_option("--source", dest="source_dir",
default=None, help="The source (input) directory")
parser.add_option("--duration", type="int", dest="duration",
default=None, help="Duration of the test")
parser.add_option("--build", dest="build_dir",
default=None, help="The build (output) directory")
parser.add_option("-d", "--disk", dest="disk",
default=None, help="The mbed disk")
parser.add_option("-s", "--serial", dest="serial",
@ -67,9 +85,15 @@ if __name__ == '__main__':
default=None, help="use the specified linker script")
(options, args) = parser.parse_args()
# force program to "0" if a source dir is specified
if options.source_dir is not None:
p = 0
n = None
else:
# Program Number or name
p, n = options.program, options.program_name
p, n = options.program, options.program_name
if n is not None and p is not None:
args_error(parser, "[ERROR] specify either '-n' or '-p', not both")
if n:
@ -99,6 +123,19 @@ if __name__ == '__main__':
# Test
test = Test(p)
if options.automated is not None:
test.automated = options.automated
if options.dependencies is not None:
test.dependencies = options.dependencies
if options.host_test is not None:
test.host_test = options.host_test;
if options.peripherals is not None:
test.peripherals = options.peripherals;
if options.duration is not None:
test.duration = options.duration;
if options.extra is not None:
test.extra_files = options.extra
if not test.is_supported(mcu, toolchain):
print 'The selected test is not supported on target %s with toolchain %s' % (mcu, toolchain)
sys.exit()
@ -108,13 +145,20 @@ if __name__ == '__main__':
test.dependencies.append(RTOS_LIBRARIES)
build_dir = join(BUILD_DIR, "test", mcu, toolchain, test.id)
if options.source_dir is not None:
test.source_dir = options.source_dir
build_dir = options.source_dir
if options.build_dir is not None:
build_dir = options.build_dir
target = TARGET_MAP[mcu]
try:
bin = build_project(test.source_dir, build_dir, target, toolchain,
test.dependencies, options.options,
linker_script=options.linker_script,
clean=options.clean, verbose=options.verbose)
clean=options.clean, verbose=options.verbose,
macros=options.macros)
print 'Image: %s' % bin
if options.disk:

View File

@ -58,6 +58,12 @@ OFFICIAL_CODE = (
("USBDevice", "USBDevice"),
("USBHost" , "USBHost"),
("CellularModem", "net/cellular/CellularModem"),
("CellularUSBModem", "net/cellular/CellularUSBModem"),
("UbloxUSBModem", "net/cellular/UbloxUSBModem"),
("UbloxModemHTTPClientTest", ["tests/net/cellular/http/common", "tests/net/cellular/http/ubloxusb"]),
("UbloxModemSMSTest", ["tests/net/cellular/sms/common", "tests/net/cellular/sms/ubloxusb"]),
)
@ -235,7 +241,7 @@ def visit_files(path, visit):
visit(join(root, file))
def update_repo(repo_name, sdk_path):
def update_repo(repo_name, sdk_paths):
repo = MbedOfficialRepository(repo_name)
# copy files from mbed SDK to mbed_official repository
def visit_mbed_sdk(sdk_file):
@ -246,12 +252,16 @@ def update_repo(repo_name, sdk_path):
makedirs(repo_dir)
copy_with_line_endings(sdk_file, repo_file)
visit_files(sdk_path, visit_mbed_sdk)
for sdk_path in sdk_paths:
visit_files(sdk_path, visit_mbed_sdk)
# remove repository files that do not exist in the mbed SDK
def visit_repo(repo_file):
sdk_file = join(sdk_path, relpath(repo_file, repo.path))
if not exists(sdk_file):
for sdk_path in sdk_paths:
sdk_file = join(sdk_path, relpath(repo_file, repo.path))
if exists(sdk_file):
break
else:
remove(repo_file)
print "remove: %s" % repo_file
visit_files(repo.path, visit_repo)
@ -263,7 +273,8 @@ def update_repo(repo_name, sdk_path):
def update_code(repositories):
for repo_name, sdk_dir in repositories:
print '\n=== Updating "%s" ===' % repo_name
sdk_path = join(LIB_DIR, sdk_dir)
sdk_dirs = [sdk_dir] if type(sdk_dir) != type([]) else sdk_dir
sdk_path = [join(LIB_DIR, d) for d in sdk_dirs]
update_repo(repo_name, sdk_path)

View File

@ -565,20 +565,20 @@ TESTS = [
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, ETH_LIBRARY],
},
# Vodafone tests
# u-blox tests
{
"id": "VF_1", "description": "HTTP client",
"source_dir": join(TEST_DIR, "net", "vodafone", "HTTPClient_HelloWorld"),
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, VODAFONE_LIBRARY, TEST_MBED_LIB],
"id": "UB_1", "description": "u-blox USB modem: HTTP client",
"source_dir": [join(TEST_DIR, "net", "cellular", "http", "ubloxusb"), join(TEST_DIR, "net", "cellular", "http", "common")],
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, USB_HOST_LIBRARIES, UBLOX_LIBRARY],
"supported": CORTEX_ARM_SUPPORT,
},
{
"id": "VF_2", "description": "USSD & SMS Test",
"source_dir": join(TEST_DIR, "net", "vodafone", "USSD_SMS_HelloWorld"),
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, VODAFONE_LIBRARY, TEST_MBED_LIB],
"id": "UB_2", "description": "u-blox USB modem: SMS test",
"source_dir": [join(TEST_DIR, "net", "cellular", "sms", "ubloxusb"), join(TEST_DIR, "net", "cellular", "sms", "common")],
"dependencies": [MBED_LIBRARIES, RTOS_LIBRARIES, USB_HOST_LIBRARIES, UBLOX_LIBRARY],
"supported": CORTEX_ARM_SUPPORT,
},
# USB Tests
{
"id": "USB_1", "description": "Mouse",

View File

@ -146,7 +146,7 @@ class mbedToolchain:
GOANNA_FORMAT = "[Goanna] warning [%FILENAME%:%LINENO%] - [%CHECKNAME%(%SEVERITY%)] %MESSAGE%"
GOANNA_DIAGNOSTIC_PATTERN = re.compile(r'"\[Goanna\] (?P<severity>warning) \[(?P<file>[^:]+):(?P<line>\d+)\] \- (?P<message>.*)"')
def __init__(self, target, options=None, notify=None):
def __init__(self, target, options=None, notify=None, macros=None):
self.target = target
self.name = self.__class__.__name__
self.hook = hooks.Hook(target, self)
@ -162,6 +162,7 @@ class mbedToolchain:
self.options = []
else:
self.options = options
self.macros = macros or []
self.options.extend(BUILD_OPTIONS)
if self.options:
self.info("Build Options: %s" % (', '.join(self.options)))
@ -347,7 +348,7 @@ class mbedToolchain:
self.progress("compile", source, build_update=True)
# Compile
command = cc + ['-D%s' % s for s in self.get_symbols()] + ["-I%s" % i for i in includes] + ["-o", object, source]
command = cc + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source]
if hasattr(self, "get_dep_opt"):
command.extend(self.get_dep_opt(dep_path))

View File

@ -30,8 +30,8 @@ class ARM(mbedToolchain):
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+): (?P<severity>Warning|Error): (?P<message>.+)')
DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
def __init__(self, target, options=None, notify=None):
mbedToolchain.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None):
mbedToolchain.__init__(self, target, options, notify, macros)
if target.core == "Cortex-M0+":
cpu = "Cortex-M0"
@ -123,16 +123,16 @@ class ARM(mbedToolchain):
class ARM_STD(ARM):
def __init__(self, target, options=None, notify=None):
ARM.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None):
ARM.__init__(self, target, options, notify, macros)
self.ld.append("--libpath=%s" % ARM_LIB)
class ARM_MICRO(ARM):
PATCHED_LIBRARY = False
def __init__(self, target, options=None, notify=None):
ARM.__init__(self, target, notify)
def __init__(self, target, options=None, notify=None, macros=None):
ARM.__init__(self, target, options, notify, macros)
# Compiler
self.asm += ["-D__MICROLIB"]

View File

@ -29,8 +29,8 @@ class GCC(mbedToolchain):
CIRCULAR_DEPENDENCIES = True
DIAGNOSTIC_PATTERN = re.compile('((?P<line>\d+):)(\d+:)? (?P<severity>warning|error): (?P<message>.+)')
def __init__(self, target, options=None, notify=None, tool_path=""):
mbedToolchain.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None, tool_path=""):
mbedToolchain.__init__(self, target, options, notify, macros)
if target.core == "Cortex-M0+":
cpu = "cortex-m0"
@ -162,8 +162,8 @@ class GCC(mbedToolchain):
class GCC_ARM(GCC):
def __init__(self, target, options=None, notify=None):
GCC.__init__(self, target, options, notify, GCC_ARM_PATH)
def __init__(self, target, options=None, notify=None, macros=None):
GCC.__init__(self, target, options, notify, macros, GCC_ARM_PATH)
# Use latest gcc nanolib
self.ld.append("--specs=nano.specs")
@ -174,8 +174,8 @@ class GCC_ARM(GCC):
class GCC_CR(GCC):
def __init__(self, target, options=None, notify=None):
GCC.__init__(self, target, options, notify, GCC_CR_PATH)
def __init__(self, target, options=None, notify=None, macros=None):
GCC.__init__(self, target, options, notify, macros, GCC_CR_PATH)
additional_compiler_flags = [
"-D__NEWLIB__", "-D__CODE_RED", "-D__USE_CMSIS", "-DCPP_USE_HEAP",
@ -187,8 +187,8 @@ class GCC_CR(GCC):
class GCC_CS(GCC):
def __init__(self, target, options=None, notify=None):
GCC.__init__(self, target, options, notify, GCC_CS_PATH)
def __init__(self, target, options=None, notify=None, macros=None):
GCC.__init__(self, target, options, notify, macros, GCC_CS_PATH)
class GCC_CW(GCC):
@ -196,13 +196,13 @@ class GCC_CW(GCC):
"Cortex-M0+": "armv6-m",
}
def __init__(self, target, options=None, notify=None):
GCC.__init__(self, target, options, notify, CW_GCC_PATH)
def __init__(self, target, options=None, notify=None, macros=None):
GCC.__init__(self, target, options, notify, macros, CW_GCC_PATH)
class GCC_CW_EWL(GCC_CW):
def __init__(self, target, options=None, notify=None):
GCC_CW.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None):
GCC_CW.__init__(self, target, options, notify, macros)
# Compiler
common = [
@ -230,5 +230,5 @@ class GCC_CW_EWL(GCC_CW):
class GCC_CW_NEWLIB(GCC_CW):
def __init__(self, target, options=None, notify=None):
GCC_CW.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None):
GCC_CW.__init__(self, target, options, notify, macros)

View File

@ -29,8 +29,8 @@ class IAR(mbedToolchain):
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error)(?P<message>.+)')
def __init__(self, target, options=None, notify=None):
mbedToolchain.__init__(self, target, options, notify)
def __init__(self, target, options=None, notify=None, macros=None):
mbedToolchain.__init__(self, target, options, notify, macros)
c_flags = [
"-Oh",