1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

Initial batch of mocks for host side testing

This commit is contained in:
Ivan Grokhotkov 2016-03-03 09:37:35 +03:00
parent 1c9f9c3a6d
commit 5724f38542
8 changed files with 10033 additions and 0 deletions

View File

@ -0,0 +1,29 @@
//
// Arduino.cpp
// esp8266-host-tests
//
// Created by Ivan Grokhotkov on 02/03/16.
// Copyright © 2016 esp8266.com. All rights reserved.
//
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <sys/time.h>
#include "Arduino.h"
extern "C" unsigned long millis()
{
timeval time;
gettimeofday(&time, NULL);
return (time.tv_sec * 1000) + (time.tv_usec / 1000);
}
extern "C" void yield()
{
}
extern "C" void __panic_func(const char* file, int line, const char* func) {
abort();
}

271
tests/host/common/Arduino.h Normal file
View File

@ -0,0 +1,271 @@
//
// Arduino.hpp
// esp8266-host-tests
//
// Created by Ivan Grokhotkov on 02/03/16.
// Copyright © 2016 esp8266.com. All rights reserved.
//
#ifndef Arduino_h
#define Arduino_h
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "binary.h"
#include "twi.h"
#include "core_esp8266_features.h"
#define HIGH 0x1
#define LOW 0x0
#define PWMRANGE 1023
//GPIO FUNCTIONS
#define INPUT 0x00
#define INPUT_PULLUP 0x02
#define INPUT_PULLDOWN_16 0x04 // PULLDOWN only possible for pin16
#define OUTPUT 0x01
#define OUTPUT_OPEN_DRAIN 0x03
#define WAKEUP_PULLUP 0x05
#define WAKEUP_PULLDOWN 0x07
#define SPECIAL 0xF8 //defaults to the usable BUSes uart0rx/tx uart1tx and hspi
#define FUNCTION_0 0x08
#define FUNCTION_1 0x18
#define FUNCTION_2 0x28
#define FUNCTION_3 0x38
#define FUNCTION_4 0x48
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
//Interrupt Modes
#define DISABLED 0x00
#define RISING 0x01
#define FALLING 0x02
#define CHANGE 0x03
#define ONLOW 0x04
#define ONHIGH 0x05
#define ONLOW_WE 0x0C
#define ONHIGH_WE 0x0D
#define DEFAULT 1
#define EXTERNAL 0
//timer dividers
#define TIM_DIV1 0 //80MHz (80 ticks/us - 104857.588 us max)
#define TIM_DIV16 1 //5MHz (5 ticks/us - 1677721.4 us max)
#define TIM_DIV265 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max)
//timer int_types
#define TIM_EDGE 0
#define TIM_LEVEL 1
//timer reload values
#define TIM_SINGLE 0 //on interrupt routine you need to write a new value to start the timer again
#define TIM_LOOP 1 //on interrupt the counter will start with the same value again
#define timer1_read() (T1V)
#define timer1_enabled() ((T1C & (1 << TCTE)) != 0)
#define timer1_interrupted() ((T1C & (1 << TCIS)) != 0)
typedef void(*timercallback)(void);
void timer1_isr_init(void);
void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload);
void timer1_disable(void);
void timer1_attachInterrupt(timercallback userFunc);
void timer1_detachInterrupt(void);
void timer1_write(uint32_t ticks); //maximum ticks 8388607
// timer0 is a special CPU timer that has very high resolution but with
// limited control.
// it uses CCOUNT (ESP.GetCycleCount()) as the non-resetable timer counter
// it does not support divide, type, or reload flags
// it is auto-disabled when the compare value matches CCOUNT
// it is auto-enabled when the compare value changes
#define timer0_interrupted() (ETS_INTR_PENDING() & (_BV(ETS_COMPARE0_INUM)))
#define timer0_read() ((__extension__({uint32_t count;__asm__ __volatile__("esync; rsr %0,ccompare0":"=a" (count));count;})))
#define timer0_write(count) __asm__ __volatile__("wsr %0,ccompare0; esync"::"a" (count) : "memory")
void timer0_isr_init(void);
void timer0_attachInterrupt(timercallback userFunc);
void timer0_detachInterrupt(void);
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
void ets_intr_lock();
void ets_intr_unlock();
#ifndef __STRINGIFY
#define __STRINGIFY(a) #a
#endif
// these low level routines provide a replacement for SREG interrupt save that AVR uses
// but are esp8266 specific. A normal use pattern is like
//
//{
// uint32_t savedPS = xt_rsil(1); // this routine will allow level 2 and above
// // do work here
// xt_wsr_ps(savedPS); // restore the state
//}
//
// level (0-15), interrupts of the given level and above will be active
// level 15 will disable ALL interrupts,
// level 0 will enable ALL interrupts,
//
#define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)); state;}))
#define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
#define interrupts() xt_rsil(0)
#define noInterrupts() xt_rsil(15)
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
// avr-libc defines _NOP() since 1.6.2
#ifndef _NOP
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
#endif
typedef unsigned int word;
#define bit(b) (1UL << (b))
#define _BV(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void init(void);
void initVariant(void);
int atexit(void (*func)()) __attribute__((weak));
void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);
int analogRead(uint8_t pin);
void analogReference(uint8_t mode);
void analogWrite(uint8_t pin, int val);
void analogWriteFreq(uint32_t freq);
void analogWriteRange(uint32_t range);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void detachInterrupt(uint8_t pin);
void setup(void);
void loop(void);
void yield(void);
void optimistic_yield(uint32_t interval_us);
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
#define portOutputRegister(port) ((volatile uint32_t*) &GPO)
#define portInputRegister(port) ((volatile uint32_t*) &GPI)
#define portModeRegister(port) ((volatile uint32_t*) &GPE)
#define NOT_A_PIN -1
#define NOT_A_PORT -1
#define NOT_AN_INTERRUPT -1
#define NOT_ON_TIMER 0
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
#include "pgmspace.h"
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "Esp.h"
#include "Updater.h"
#include "debug.h"
#ifndef _GLIBCXX_VECTOR
// arduino is not compatible with std::vector
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#endif
#define _min(a,b) ((a)<(b)?(a):(b))
#define _max(a,b) ((a)>(b)?(a):(b))
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
extern "C" void configTime(long timezone, int daylightOffset_sec,
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
#endif
#include "pins_arduino.h"
#endif /* Arduino_h */

View File

@ -0,0 +1,61 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.org.co
Copyright (c) 2004-06 Hernando Barragan
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
$Id$
*/
extern "C" {
#include <stdlib.h>
}
void randomSeed(unsigned long seed) {
if(seed != 0) {
srand(seed);
}
}
long random(long howbig) {
if(howbig == 0) {
return 0;
}
return (rand()) % howbig;
}
long random(long howsmall, long howbig) {
if(howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
return random(diff) + howsmall;
}
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
unsigned int makeWord(unsigned int w) {
return w;
}
unsigned int makeWord(unsigned char h, unsigned char l) {
return (h << 8) | l;
}

9460
tests/host/common/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_
#include <stdint.h>
#include <stdio.h>
#define PROGMEM
#define PGM_P const char *
#define PGM_VOID_P const void *
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
#define _SFR_BYTE(n) (n)
typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
#define SIZE_IRRELEVANT 0x7fffffff
int memcmp_P(const void* buf1, PGM_VOID_P buf2P, size_t size);
// memccpy_P is only valid when used with pointers to 8bit data, due to size aligned pointers
// and endianess of the values greater than 8bit, matching c may return invalid aligned pointers
void* memccpy_P(void* dest, PGM_VOID_P src, int c, size_t count);
void* memmem_P(const void* buf, size_t bufSize, PGM_VOID_P findP, size_t findPSize);
void* memcpy_P(void* dest, PGM_VOID_P src, size_t count);
#define strncpy_P(dest, src, size) strncpy(dest, src, size)
#define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
#define strncat_P(dest, src, size) strncat(dest, src, size)
#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
#define strncmp_P(str1, str2P, size) strncmp(str1, str2P, size)
#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
#define strncasecmp_P(str1, str2P, size) strncasecmp(str1, str2P, size)
#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
#define strnlen_P(s, size) strnlen(s, size)
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
#define printf_P(formatP, ...) printf(formatP, __VA_ARGS__)
#define sprintf_P(str, formatP, ...) sprintf(str, formatP, __VA_ARGS__)
#define snprintf_P(str, strSize, formatP, ...) snprintf(str, strSize, formatP, __VA_ARGS__)
#define vsnprintf_P(str, strSize, formatP, ap) vsnprintf(str, strSize, formatP, ap)
// flash memory must be read using 32 bit aligned addresses else a processor
// exception will be triggered
// order within the 32 bit values are
// --------------
// b3, b2, b1, b0
// w1, w0
#define pgm_read_byte(x) (*reinterpret_cast<const uint8_t*>(x))
#define pgm_read_word(x) (*reinterpret_cast<const uint16_t*>(x))
#define pgm_read_float(x) (*reinterpret_cast<const float*>(x))
#define pgm_read_dword(x) (*reinterpret_cast<const uint32_t*>(x))
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#endif //__PGMSPACE_H_

View File

@ -0,0 +1,13 @@
//
// pins_arduino.h
// esp8266-host-tests
//
// Created by Ivan Grokhotkov on 02/03/16.
// Copyright © 2016 esp8266.com. All rights reserved.
//
#ifndef pins_arduino_h
#define pins_arduino_h
#endif /* pins_arduino_h */

View File

@ -0,0 +1,96 @@
//
// spiffs_mock.cpp
// esp8266-host-tests
//
// Created by Ivan Grokhotkov on 03/03/16.
// Copyright © 2016 esp8266.com. All rights reserved.
//
#include "spiffs_mock.h"
#include "spiffs/spiffs.h"
#include "debug.h"
#include <flash_utils.h>
#include <stdlib.h>
#include <spiffs_api.h>
extern "C"
{
uint32_t mock_spiffs_phys_addr = 0;
uint32_t mock_spiffs_phys_size = 0;
uint32_t mock_spiffs_phys_page = 0;
uint32_t mock_spiffs_phys_block = 0;
uint8_t* mock_spiffs_phys_data = nullptr;
}
FS SPIFFS(nullptr);
SpiffsMock::SpiffsMock(size_t fs_size, size_t fs_block, size_t fs_page)
{
m_fs.resize(fs_size, 0xff);
mock_spiffs_phys_addr = 0;
mock_spiffs_phys_size = fs_size;
mock_spiffs_phys_page = fs_page;
mock_spiffs_phys_block = fs_block;
mock_spiffs_phys_data = m_fs.data();
SPIFFS = FS(FSImplPtr(new SPIFFSImpl(0, fs_size, fs_page, fs_block, 5)));
}
SpiffsMock::~SpiffsMock()
{
mock_spiffs_phys_addr = 0;
mock_spiffs_phys_size = 0;
mock_spiffs_phys_page = 0;
mock_spiffs_phys_block = 0;
mock_spiffs_phys_data = nullptr;
SPIFFS = FS(FSImplPtr(nullptr));
}
/*
spi_flash_read function requires flash address to be aligned on word boundary.
We take care of this by reading first and last words separately and memcpy
relevant bytes into result buffer.
alignment: 012301230123012301230123
bytes requested: -------***********------
read directly: --------xxxxxxxx--------
read pre: ----aaaa----------------
read post: ----------------bbbb----
alignedBegin: ^
alignedEnd: ^
*/
int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
memcpy(dst, mock_spiffs_phys_data + addr, size);
return SPIFFS_OK;
}
/*
Like spi_flash_read, spi_flash_write has a requirement for flash address to be
aligned. However it also requires RAM address to be aligned as it reads data
in 32-bit words. Flash address (mis-)alignment is handled much the same way
as for reads, but for RAM alignment we have to copy data into a temporary
buffer. The size of this buffer is a tradeoff between number of writes required
and amount of stack required. This is chosen to be 512 bytes here, but might
be adjusted in the future if there are good reasons to do so.
*/
int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
memcpy(mock_spiffs_phys_data + addr, src, size);
return SPIFFS_OK;
}
int32_t spiffs_hal_erase(uint32_t addr, uint32_t size) {
if ((size & (FLASH_SECTOR_SIZE - 1)) != 0 ||
(addr & (FLASH_SECTOR_SIZE - 1)) != 0) {
abort();
}
const uint32_t sector = addr / FLASH_SECTOR_SIZE;
const uint32_t sectorCount = size / FLASH_SECTOR_SIZE;
for (uint32_t i = 0; i < sectorCount; ++i) {
memset(mock_spiffs_phys_data + (sector + i) * FLASH_SECTOR_SIZE, 0xff, FLASH_SECTOR_SIZE);
}
return SPIFFS_OK;
}

View File

@ -0,0 +1,27 @@
//
// spiffs_mock.hpp
// esp8266-host-tests
//
// Created by Ivan Grokhotkov on 03/03/16.
// Copyright © 2016 esp8266.com. All rights reserved.
//
#ifndef spiffs_mock_hpp
#define spiffs_mock_hpp
#include <stdint.h>
#include <stddef.h>
#include <vector>
#include <FS.h>
class SpiffsMock {
public:
SpiffsMock(size_t fs_size, size_t fs_block, size_t fs_page);
~SpiffsMock();
protected:
std::vector<uint8_t> m_fs;
};
#endif /* spiffs_mock_hpp */